#load libraries
library(dplyr)
library(readr)
library(tidyr)
library(lubridate)
library(fixest)
library(data.table)
library(stringr)
library(sf)
# Turn off scientific notation globally
#options(scipen = 999)
#load relevant files
#readRDS("C:/Users/yoshiara/OneDrive - RAND Corporation/Desktop/Dissertation/eastern drc/panel_p3_yearly.rds")
setwd("C:/Users/yoshiara/OneDrive - RAND Corporation/Desktop/Dissertation/eastern drc")
#Descriptive Stats
##Cross-sectional (2021 only)
###Mining vs. non-mining grids
What do mining vs. non-mining grid cells look like? Table below
includes grids covering all of DRC. Some things that stand out: - Mining
grids are closer to national borders - Mining grids have more cropland
(all types - irrigated, rainfed, other). For all grids, there is more
rainfed than irrigated cropland. - Mining grids have fewer permanent
bodies of water - Mining grids have higher population – but this could
just be because the non-mining grids may capture many unpopulated areas.
This matches the pattern for impervious/manmade surfaces but not for
nightlight density which is the same for both mining and non-mining
grids (weird) - Mining grids have higher conflict counts (across all
conflict categories)
#descriptive stats (means table) mining vs non_mining####
# 1) Restrict to latest year where all vars exist (2021)
df_latest <- panel_p3_yearly %>%
filter(year == 2021) %>%
mutate(mine_group = ifelse(total_mine_count == 0, "No mines", ">=1 mine"))
# 2) Variables to summarize
vars <- c(
"dist_to_border",
"forest","grassland","impervious","irrigated_crops",
"nightlights","other_crops","permanent_water",
"rainfed_crops","seasonal_water","shrubland",
"sparse","swamp","pop", "n_conflicts", "n_battles", "n_protests"
)
# helper: coerce to numeric if needed (handles factors/characters)
to_num <- function(x) {
if (is.numeric(x)) return(x)
if (is.factor(x)) return(as.numeric(as.character(x)))
if (is.character(x)) return(suppressWarnings(as.numeric(x)))
return(suppressWarnings(as.numeric(x)))
}
# 3) Run t-tests + build results
t_test_results <- lapply(vars, function(v) {
x <- to_num(df_latest[[v]])
g <- df_latest$mine_group
# group means
m0 <- mean(x[g == "No mines"], na.rm = TRUE)
m1 <- mean(x[g == ">=1 mine"], na.rm = TRUE)
# t-test (Welch)
tt <- t.test(x ~ g)
data.frame(
variable = v,
mean_no_mines = m0,
mean_mines = m1,
p_value = tt$p.value
)
}) %>%
bind_rows() %>%
mutate(sig = case_when(
p_value < 0.001 ~ "***",
p_value < 0.01 ~ "**",
p_value < 0.05 ~ "*",
TRUE ~ ""
))
# Turn off scientific notation globally
options(scipen = 999)
# Round numeric columns to 3 decimals
t_test_results_clean <- t_test_results %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# --- 1) Count grids in each group ---
group_counts <- df_latest %>%
group_by(mine_group) %>%
summarise(N_grids = n(), .groups = "drop")
# Extract counts
N_no_mines <- group_counts$N_grids[group_counts$mine_group == "No mines"]
N_mines <- group_counts$N_grids[group_counts$mine_group == ">=1 mine"]
# --- 2) Add counts to results table ---
t_test_results_clean <- t_test_results %>%
mutate(
N_no_mines = N_no_mines,
N_mines = N_mines
) %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# --- 3) View table ---
#turn of pagination for tables
DT::datatable(
t_test_results_clean,
options = list(
pageLength = nrow(t_test_results_clean), # show all rows
paging = FALSE # turn pagination off
)
)
NA
NA
###Mining vs. non-mining grids (excluding grids with fewer than 25
people)
This is the same table as the one above, except now I’m restricting
to grid cells with at least 25 people. The results are generally
consistent with the patterns in the previous table.
#descriptive stats (means table) mining vs non_mining (population >= 25)####
# 1) Restrict to latest year where all vars exist (2021)
df_latest_pop <- df_latest %>%
filter(pop >= 25)
# 2) Variables to summarize
vars <- c(
"dist_to_border",
"forest","grassland","impervious","irrigated_crops",
"nightlights","other_crops","permanent_water",
"rainfed_crops","seasonal_water","shrubland",
"sparse","swamp","pop", "n_conflicts", "n_battles", "n_protests"
)
# helper: coerce to numeric if needed (handles factors/characters)
to_num <- function(x) {
if (is.numeric(x)) return(x)
if (is.factor(x)) return(as.numeric(as.character(x)))
if (is.character(x)) return(suppressWarnings(as.numeric(x)))
return(suppressWarnings(as.numeric(x)))
}
# 3) Run t-tests + build results
t_test_results <- lapply(vars, function(v) {
x <- to_num(df_latest_pop[[v]])
g <- df_latest_pop$mine_group
# group means
m0 <- mean(x[g == "No mines"], na.rm = TRUE)
m1 <- mean(x[g == ">=1 mine"], na.rm = TRUE)
# t-test (Welch)
tt <- t.test(x ~ g)
data.frame(
variable = v,
mean_no_mines = m0,
mean_mines = m1,
p_value = tt$p.value
)
}) %>%
bind_rows() %>%
mutate(sig = case_when(
p_value < 0.001 ~ "***",
p_value < 0.01 ~ "**",
p_value < 0.05 ~ "*",
TRUE ~ ""
))
# Round numeric columns to 3 decimals
t_test_results_clean <- t_test_results %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# --- 1) Count grids in each group ---
group_counts <- df_latest_pop %>%
group_by(mine_group) %>%
summarise(N_grids = n(), .groups = "drop")
# Extract counts
N_no_mines <- group_counts$N_grids[group_counts$mine_group == "No mines"]
N_mines <- group_counts$N_grids[group_counts$mine_group == ">=1 mine"]
# --- 2) Add counts to results table ---
t_test_results_clean <- t_test_results %>%
mutate(
N_no_mines = N_no_mines,
N_mines = N_mines
) %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# --- 3) View table ---
#turn of pagination for tables
DT::datatable(
t_test_results_clean,
options = list(
pageLength = nrow(t_test_results_clean), # show all rows
paging = FALSE # turn pagination off
)
)
NA
###Mineral type treatment categories (3TG vs. non-3TG mines)
Here I’m again restricting to mining grids, but comparing grids that
mine the 3TG (tin,tantalum, tungsten, and gold) with grids that mine
other materials. The 3TG are the minerals covered by the DF Act. This is
the alternate identification strategy I want to explore in paper 3.
There is only one grid cell with both 3TG and non-3TG mines.Here we see
that: - 3TG grids have more crops (irrigated and rainfed) - Much higher
population in non-3TG mining grids, which tracks with impervious
surfaces and nightlights - More battles in 3TG grids, more protests in
non-DF grids
#descriptive stats (means table) df vs non df mining grids####
# 1) Restrict to latest year where all vars exist (2021)
df_latest_mining <- df_latest %>%
filter(mine_group == ">=1 mine")
# 2) Variables to summarize
vars <- c(
"dist_to_border",
"forest","grassland","impervious","irrigated_crops",
"nightlights","other_crops","permanent_water",
"rainfed_crops","seasonal_water","shrubland",
"sparse","swamp","pop",
"n_conflicts","n_battles","n_protests"
)
# helper: coerce to numeric if needed (handles factors/characters)
to_num <- function(x) {
if (is.numeric(x)) return(x)
if (is.factor(x)) return(as.numeric(as.character(x)))
if (is.character(x)) return(suppressWarnings(as.numeric(x)))
return(suppressWarnings(as.numeric(x)))
}
# 3) Run t-tests + build results
t_test_results <- lapply(vars, function(v) {
x <- to_num(df_latest_mining[[v]])
g <- df_latest_mining$has_df_mine_dummy
# group means
m0 <- mean(x[g == 0], na.rm = TRUE)
m1 <- mean(x[g == 1], na.rm = TRUE)
# t-test (Welch)
tt <- t.test(x ~ g)
data.frame(
variable = v,
mean_non_df = m0,
mean_df = m1,
p_value = tt$p.value
)
}) %>%
bind_rows() %>%
mutate(sig = case_when(
p_value < 0.001 ~ "***",
p_value < 0.01 ~ "**",
p_value < 0.05 ~ "*",
TRUE ~ ""
))
# Round numeric columns to 3 decimals
t_test_results_clean <- t_test_results %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# --- 1) Count grids in each group ---
group_counts <- df_latest_mining %>%
group_by(has_df_mine_dummy) %>%
summarise(N_grids = n(), .groups = "drop")
# Extract counts
N_non_df_mines <- group_counts$N_grids[group_counts$has_df_mine_dummy == 0]
N_df_mines <- group_counts$N_grids[group_counts$has_df_mine_dummy == 1]
# --- 2) Add counts to results table ---
t_test_results_clean <- t_test_results %>%
mutate(
N_non_df_mines = N_non_df_mines,
N_df_mines = N_df_mines
) %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# --- 3) View table ---
DT::datatable(
t_test_results_clean,
options = list(
pageLength = nrow(t_test_results_clean), # show all rows
paging = FALSE # turn pagination off
)
)
NA
###Parker and Vadheim/Dodd-Frank treated grids vs. untreated
grids
Now I’m looking only a mining grids, comparing grids that were
“treated” per the PV study (i.e. that are located in conflict affected
mining areas per the 2011 State Department map) to untreated mining
grids per the PV study: - There is less of a population delta than in
the previous table (the 3TG vs. non-3TG mining grid comparison). I’m not
sure what this means in terms of thinking through PV’s vs. my
identification strategy. - No statistically significant difference in
mean conflict counts in PV-DF treated vs. untreated mining grids. Again,
not sure what that implies.
# helper: coerce to numeric if needed (handles factors/characters)
to_num <- function(x) {
if (is.numeric(x)) return(x)
if (is.factor(x)) return(as.numeric(as.character(x)))
if (is.character(x)) return(suppressWarnings(as.numeric(x)))
return(suppressWarnings(as.numeric(x)))
}
# 3) Run t-tests + build results
t_test_results <- lapply(vars, function(v) {
x <- to_num(df_latest_mining[[v]])
g <- df_latest_mining$policy_terr
# group means
m0 <- mean(x[g == 0], na.rm = TRUE)
m1 <- mean(x[g == 1], na.rm = TRUE)
# t-test (Welch)
tt <- t.test(x ~ g)
data.frame(
variable = v,
mean_non_df = m0,
mean_df = m1,
p_value = tt$p.value
)
}) %>%
bind_rows() %>%
mutate(sig = case_when(
p_value < 0.001 ~ "***",
p_value < 0.01 ~ "**",
p_value < 0.05 ~ "*",
TRUE ~ ""
))
# Round numeric columns to 3 decimals
t_test_results_clean <- t_test_results %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# --- 1) Count grids in each group ---
group_counts <- df_latest_mining %>%
group_by(policy_terr) %>%
summarise(N_grids = n(), .groups = "drop")
# Extract counts
N_non_df_terr <- group_counts$N_grids[group_counts$policy_terr == 0]
N_df_terr <- group_counts$N_grids[group_counts$policy_terr == 1]
# --- 2) Add counts to results table ---
t_test_results_clean <- t_test_results %>%
mutate(
N_non_df_terr = N_non_df_terr,
N_df_terr = N_df_terr
) %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# --- 3) View table ---
DT::datatable(
t_test_results_clean,
options = list(
pageLength = nrow(t_test_results_clean), # show all rows
paging = FALSE # turn pagination off
)
)
##Rate of change (comparing 2003-2006 and 2019-2021)
###Mining vs. non-mining grids - More deforestation in mining grids -
More cropland growth (irrigated, rainfed) in mining grids - More
population growth in mining grids - Larger increase in conflict in
mining grids
#annual changes mining v. non-mining####
# -----------------------------
# 0) Choose the yearly variables (edit this list if you want)
# -----------------------------
yearly_vars <- c(
"forest","grassland","impervious","irrigated_crops",
"nightlights","other_crops","permanent_water",
"rainfed_crops","seasonal_water","shrubland","sparse","swamp","pop",
"n_conflicts","n_battles","n_protests"
)
# helper: coerce to numeric safely (handles factor/character numbers)
to_num <- function(x) {
if (is.numeric(x)) return(x)
if (is.factor(x)) return(as.numeric(as.character(x)))
if (is.character(x)) return(suppressWarnings(as.numeric(x)))
return(suppressWarnings(as.numeric(x)))
}
# -----------------------------
# 1) Create a static mine group per hex_id (No mines vs >=1 mine)
# Uses the maximum total_mine_count observed for each hex (robust)
# -----------------------------
mine_group_by_hex <- panel_p3_yearly %>%
group_by(hex_id) %>%
summarise(
total_mine_count_static = max(to_num(total_mine_count), na.rm = TRUE),
mine_group = ifelse(total_mine_count_static == 0, "No mines", ">=1 mine"),
.groups = "drop"
)
# -----------------------------
# 2) Compute hex-level averages in each period, then change (post - pre)
# -----------------------------
hex_period_avgs <- panel_p3_yearly %>%
select(hex_id, year, all_of(yearly_vars)) %>%
mutate(year = to_num(year)) %>%
filter(year %in% c(2003:2006, 2019:2021)) %>%
mutate(period = ifelse(year <= 2006, "pre_2003_06", "post_2019_21")) %>%
# ensure vars numeric
mutate(across(all_of(yearly_vars), to_num)) %>%
group_by(hex_id, period) %>%
summarise(across(all_of(yearly_vars), ~ mean(.x, na.rm = TRUE)), .groups = "drop") %>%
pivot_wider(
names_from = period,
values_from = all_of(yearly_vars),
names_sep = "__"
)
# compute change for each var: post - pre
# Join mine group onto the wide period-averaged data
tmp <- hex_period_avgs %>%
left_join(mine_group_by_hex, by = "hex_id")
# Create change columns: post - pre
for (v in yearly_vars) {
post_col <- paste0(v, "__post_2019_21")
pre_col <- paste0(v, "__pre_2003_06")
tmp[[paste0("chg__", v)]] <- tmp[[post_col]] - tmp[[pre_col]]
}
# Keep only what you need
hex_changes <- tmp %>%
select(hex_id, mine_group, starts_with("chg__"))
# -----------------------------
# 3) Compare mean changes across mine groups (Welch t-test), build table
# -----------------------------
chg_vars <- paste0("chg__", yearly_vars)
diff_in_changes <- lapply(chg_vars, function(v) {
x <- hex_changes[[v]]
g <- hex_changes$mine_group
ok <- !is.na(x) & !is.na(g)
x <- x[ok]; g <- g[ok]
m0 <- mean(x[g == "No mines"], na.rm = TRUE)
m1 <- mean(x[g == ">=1 mine"], na.rm = TRUE)
tt <- t.test(x ~ g) # Welch
data.frame(
variable = sub("^chg__", "", v),
mean_change_no_mines = m0,
mean_change_mines = m1,
diff_change = m1 - m0,
p_value = tt$p.value
)
}) %>%
bind_rows() %>%
mutate(
sig = case_when(
p_value < 0.001 ~ "***",
p_value < 0.01 ~ "**",
p_value < 0.05 ~ "*",
TRUE ~ ""
)
) %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# group Ns (number of hexes contributing to the change analysis)
group_Ns <- hex_changes %>%
count(mine_group)
group_Ns
DT::datatable(
diff_in_changes,
options = list(
pageLength = nrow(diff_in_changes), # show all rows
paging = FALSE # turn pagination off
)
)
Registered S3 method overwritten by 'htmlwidgets':
method from
print.htmlwidget tools:rstudio
###Mining vs. non-mining grids (excluding grids with fewer than 25
people)
Same table as the one above but restricting to grids with at least 25
people. Results generally track with the previous table.
#annual changes mining v. non-mining (pop>=25)####
# -----------------------------------
# 1) Restrict to hexes with pre-period avg pop >= 25
# -----------------------------------
hex_changes_pop25 <- hex_period_avgs %>%
left_join(mine_group_by_hex, by = "hex_id") %>%
filter(pop__pre_2003_06 >= 25)
# -----------------------------------
# 2) Create change variables
# -----------------------------------
tmp <- hex_changes_pop25
for (v in yearly_vars) {
post_col <- paste0(v, "__post_2019_21")
pre_col <- paste0(v, "__pre_2003_06")
tmp[[paste0("chg__", v)]] <- tmp[[post_col]] - tmp[[pre_col]]
}
hex_changes_pop25 <- tmp %>%
select(hex_id, mine_group, starts_with("chg__"))
# -----------------------------------
# 3) Compare mean changes across mine groups
# -----------------------------------
chg_vars <- paste0("chg__", yearly_vars)
diff_in_changes_pop25 <- lapply(chg_vars, function(v) {
x <- hex_changes_pop25[[v]]
g <- hex_changes_pop25$mine_group
ok <- !is.na(x) & !is.na(g)
x <- x[ok]; g <- g[ok]
m0 <- mean(x[g == "No mines"], na.rm = TRUE)
m1 <- mean(x[g == ">=1 mine"], na.rm = TRUE)
tt <- t.test(x ~ g)
data.frame(
variable = sub("^chg__", "", v),
mean_change_no_mines = m0,
mean_change_mines = m1,
diff_change = m1 - m0,
p_value = tt$p.value
)
}) %>%
bind_rows() %>%
mutate(
sig = case_when(
p_value < 0.001 ~ "***",
p_value < 0.01 ~ "**",
p_value < 0.05 ~ "*",
TRUE ~ ""
)
) %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# -----------------------------------
# 4) Group counts
# -----------------------------------
group_Ns_pop25 <- hex_changes_pop25 %>%
count(mine_group)
group_Ns_pop25
DT::datatable(
diff_in_changes_pop25,
options = list(
pageLength = nrow(diff_in_changes_pop25), # show all rows
paging = FALSE # turn pagination off
)
)
NA
###Mineral type treatment categories (3TG vs. non-3TG mines)
- Less forest loss in 3TG mineral grids, which tracks with lower
nightlight, pop and impervious growth
- Higher cropland growth (irrigated, rainfed) in 3TG mineral
grids
- Higher growth in conflicts overall and battles but not protests for
3TG mineral grids
#annual changes df vs. non df mineral grids####
# ------------------------------------------------------------
# 1) Build a hex-level DF grouping variable, and restrict to mining grids
# ------------------------------------------------------------
df_group_by_hex <- panel_p3_yearly %>%
group_by(hex_id) %>%
summarise(
total_mine_count_static = first(na.omit(to_num(total_mine_count))),
has_df_static = first(na.omit(to_num(has_df_mine_dummy))),
df_group = ifelse(has_df_static == 1, "DF mine", "Non-DF mine"),
.groups = "drop"
) %>%
filter(total_mine_count_static >= 1)
# ------------------------------------------------------------
# 2) Join onto the period-average wide data and compute changes
# ------------------------------------------------------------
tmp <- hex_period_avgs %>%
inner_join(df_group_by_hex %>% select(hex_id, df_group), by = "hex_id")
# change columns: post - pre
for (v in yearly_vars) {
post_col <- paste0(v, "__post_2019_21")
pre_col <- paste0(v, "__pre_2003_06")
tmp[[paste0("chg__", v)]] <- tmp[[post_col]] - tmp[[pre_col]]
}
hex_changes_df_vs_nondf <- tmp %>%
select(hex_id, df_group, starts_with("chg__"))
# ------------------------------------------------------------
# 3) Compare mean changes across DF vs non-DF (Welch t-tests)
# ------------------------------------------------------------
chg_vars <- paste0("chg__", yearly_vars)
diff_in_changes_df_vs_nondf <- lapply(chg_vars, function(v) {
x <- hex_changes_df_vs_nondf[[v]]
g <- hex_changes_df_vs_nondf$df_group
ok <- !is.na(x) & !is.na(g)
x <- x[ok]; g <- g[ok]
m0 <- mean(x[g == "Non-DF mine"], na.rm = TRUE)
m1 <- mean(x[g == "DF mine"], na.rm = TRUE)
tt <- t.test(x ~ g) # Welch
data.frame(
variable = sub("^chg__", "", v),
mean_change_non_df = m0,
mean_change_df = m1,
diff_change = m1 - m0,
p_value = tt$p.value
)
}) %>%
bind_rows() %>%
mutate(
sig = case_when(
p_value < 0.001 ~ "***",
p_value < 0.01 ~ "**",
p_value < 0.05 ~ "*",
TRUE ~ ""
)
) %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# ------------------------------------------------------------
# 4) Group counts
# ------------------------------------------------------------
group_Ns_df_vs_nondf <- hex_changes_df_vs_nondf %>%
count(df_group)
group_Ns_df_vs_nondf
DT::datatable(
diff_in_changes_df_vs_nondf,
options = list(
pageLength = nrow(diff_in_changes_df_vs_nondf), # show all rows
paging = FALSE # turn pagination off
)
)
NA
###Parker and Vadheim/Dodd-Frank mining grids vs. non-DF mining
grids
- No statistically significant difference in conflict count growth in
PV-DF treated vs. untreated mining grids.
#annual changes df vs. non df policy grids####
# ------------------------------------------------------------
# 1) Build a hex-level DF grouping variable, and restrict to mining grids
# ------------------------------------------------------------
df_group_by_hex <- panel_p3_yearly %>%
group_by(hex_id) %>%
summarise(
total_mine_count_static = first(na.omit(to_num(total_mine_count))),
has_policy_static = first(na.omit(to_num(policy_terr))),
policy_group = ifelse(has_policy_static == 1, "DF mine", "Non-DF mine"),
.groups = "drop"
) %>%
filter(total_mine_count_static >= 1)
# ------------------------------------------------------------
# 2) Join onto the period-average wide data and compute changes
# ------------------------------------------------------------
tmp <- hex_period_avgs %>%
inner_join(df_group_by_hex %>% select(hex_id, policy_group), by = "hex_id")
# change columns: post - pre
for (v in yearly_vars) {
post_col <- paste0(v, "__post_2019_21")
pre_col <- paste0(v, "__pre_2003_06")
tmp[[paste0("chg__", v)]] <- tmp[[post_col]] - tmp[[pre_col]]
}
hex_changes_df_vs_nondf <- tmp %>%
select(hex_id, policy_group, starts_with("chg__"))
# ------------------------------------------------------------
# 3) Compare mean changes across DF vs non-DF (Welch t-tests)
# ------------------------------------------------------------
chg_vars <- paste0("chg__", yearly_vars)
diff_in_changes_df_vs_nondf <- lapply(chg_vars, function(v) {
x <- hex_changes_df_vs_nondf[[v]]
g <- hex_changes_df_vs_nondf$policy_group
ok <- !is.na(x) & !is.na(g)
x <- x[ok]; g <- g[ok]
m0 <- mean(x[g == "Non-DF mine"], na.rm = TRUE)
m1 <- mean(x[g == "DF mine"], na.rm = TRUE)
tt <- t.test(x ~ g) # Welch
data.frame(
variable = sub("^chg__", "", v),
mean_change_non_df = m0,
mean_change_df = m1,
diff_change = m1 - m0,
p_value = tt$p.value
)
}) %>%
bind_rows() %>%
mutate(
sig = case_when(
p_value < 0.001 ~ "***",
p_value < 0.01 ~ "**",
p_value < 0.05 ~ "*",
TRUE ~ ""
)
) %>%
mutate(across(where(is.numeric), ~ round(.x, 3)))
# ------------------------------------------------------------
# 4) Group counts
# ------------------------------------------------------------
group_Ns_df_vs_nondf <- hex_changes_df_vs_nondf %>%
count(policy_group)
group_Ns_df_vs_nondf
DT::datatable(
diff_in_changes_df_vs_nondf,
options = list(
pageLength = nrow(diff_in_changes_df_vs_nondf), # show all rows
paging = FALSE # turn pagination off
)
)
NA
#Regressions
##Outcome: Pr(Battle Occurence)
###PV baseline model but with grids Looking at the outcome:
probability of any battle occurring. Same as PV study but using grid
cells instead of territories as the unit of analysis (so a much smaller
united of analysis that doesn’t follow political boundaries). Only
policy_dummy (indicator for grids in a territory flagged as
conflict-affected by State Dep in 2008-2010) is stat sig (at ***,
0.000187). Interaction terms with number of mine variables aren’t.
#any battles, matching PV but at grid vs. territory level####
mod <- feols(
any_battles ~ policy_dummy + policy_dummy:is_3t_count + policy_dummy:is_gold_count | hex_id + time_id,
data = pv_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709, time_id: 108
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095 Adj. R2: 0.117854
Within R2: 2.187e-5
###PV baseline model with grid-level treatment assignment
Now I’m assigning treatment at the grid level, rather than at the
territory level, based on whether the grid is in a State Department
policy territory + has a 3TG mine. When I assign treatment more
granularly, the treatment effect goes away.
#any battles, matching PV but at grid vs. territory level####
mod <- feols(
any_battles ~ df_policy_grids + df_policy_grids:is_3t_count + df_policy_grids:is_gold_count | hex_id + time_id,
data = pv_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709, time_id: 108
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095 Adj. R2: 0.117839
Within R2: 4.347e-6
###Government ban treatment
Now I”m ignoring Dodd-Frank and looking instead at the government ban
on artisanal mining that occurred at the same time that DF was passed.
Here I’m using the same approach as PV (but at the grid level vs
territory level). The ban covered 3 provinces, which encompass 44 of the
51 treated territories in the PV study. There is a reduction in the
probability of experiencing a battle in gov_ban provinces.
#what if we just look at the gov ban####
mod <- feols(
any_battles ~ gov_ban + gov_ban:is_3t_count + gov_ban:is_gold_count | hex_id + time_id,
data = pv_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709, time_id: 108
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095 Adj. R2: 0.11784
Within R2: 5.427e-6
###Government ban assigned at the grid level
Now I’m assigning the same government ban treatment but at the grid
level instead of at the territory level, based on whether the grid is in
a province targeted by the government ban + has a 3TG mine. When I
assign treatment more granularly, the coefficient on the Pr(battle)
remains negative, but now the interaction term with the number of gold
mines becomes statistically significant (and is positive).
#what if we assign gov ban treatment at the grid level
mod <- feols(
any_battles ~ gov_ban_grids + gov_ban_grids:is_3t_count + gov_ban_grids:is_gold_count | hex_id + time_id,
data = pv_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709, time_id: 108
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095 Adj. R2: 0.117839
Within R2: 4.331e-6
###Both PV-DF treatment and government ban
Now I’m looking at the PV-DF treatment + government ban
simultaneously. First regression has treatment assigned at the territory
or province level. Second regression has treatment assigned at the grid
level. When treatment is assigned at the territory/province level, the
two policies work in opposite directions and are both statistically
significant. When treatment is assigned at the grid level, they are both
negative and stat insignificant.
#what is we look at both df and gov grids
mod <- feols(
any_battles ~ policy_dummy + gov_ban | hex_id + time_id,
data = pv_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709, time_id: 108
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095 Adj. R2: 0.117856
Within R2: 2.34e-5
#same regression but with treatment assigned at the grid level
mod <- feols(
any_battles ~ df_policy_grids + gov_ban_grids | hex_id + time_id,
data = pv_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709, time_id: 108
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095 Adj. R2: 0.117837
Within R2: 2.95e-6
###Alternate treatment timing (May 2013)
Now I’m exploring whether using a later treatment starting time
changes the original PV results. Specifically, while Dodd-Frank was
passed in July 2010, companies didn’t have to file their first conflict
mineral disclosure reports until May 2014. I’m using June 2013 – one
year before the first company filing – as my alternate treatment start
timing. I’m also extending the timeframe from 2012 (PV study) to 2020.
All three coefficients of interest are positive and statistically
significant.
#May 2013 treatment####
mod <- feols(
any_battles ~ policy_dummy_2013 + policy_dummy_2013:is_3t_count + policy_dummy_2013:is_gold_count | hex_id + time_id,
data = full_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 14,220,636
Fixed-effects: hex_id: 69,709, time_id: 204
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.015611 Adj. R2: 0.088314
Within R2: 1.772e-4
###Mineral type treatment assignment
Now I’m exploring the use of an alternate treatment assignment based
on whether the grid cell has a 3TG mine vs non-3TG mine. First
regression uses the July 2010 treatment timing, second the June 2013
timing. Both show a positive, statistically significant treatment
effect.
#Mineral type treatment and 2010 or 2013 treatment####
#2013
panel_month <- panel_month %>%
mutate(
policy_dummy_2013_timeonly = as.integer(time_id >= 201306L)
)
full_months_grids <- panel_month %>%
dplyr::filter(
year >= 2004,
year <= 2020,
eastern_terr == 1
)
#2010
panel_month <- panel_month %>%
mutate(
policy_dummy_2010_timeonly = as.integer(time_id >= 201007L)
)
pv_months_grids <- panel_month %>%
dplyr::filter(
year >= 2004,
year <= 2012,
eastern_terr == 1
)
#2013 reg
mod <- feols(
any_battles ~ policy_dummy_2013_timeonly:has_df_mine_dummy | hex_id + time_id,
data = full_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 14,220,636
Fixed-effects: hex_id: 69,709, time_id: 204
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.015612 Adj. R2: 0.088213
Within R2: 6.65e-5
#2010 reg
mod <- feols(
any_battles ~ policy_dummy_2010_timeonly:has_df_mine_dummy | hex_id + time_id,
data = pv_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709, time_id: 108
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010095 Adj. R2: 0.117844
Within R2: 1.032e-5
Here I’m introducing some yearly covariates (population, nightlights
and select land use categories). This is the baseline PV specification
(2010 treatment, State Department map). Interesting that while the
policy summy remains positive and statistically significant, the
interaction term on the number of gold mines does not. The only
covariate that seems to pop is rainfed crops.
#baseline PV with RS controls
mod <- feols(
any_battles ~ policy_dummy + policy_dummy:is_3t_count + policy_dummy:is_gold_count + pop + nightlights + irrigated_crops + rainfed_crops + forest | hex_id + time_id,
data = pv_months_grids
)
# Cluster-robust summary
summary(mod, cluster = "hex_id")
OLS estimation, Dep. Var.: any_battles
Observations: 7,528,572
Fixed-effects: hex_id: 69,709, time_id: 108
Standard-errors: Clustered (hex_id)
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
RMSE: 0.010092 Adj. R2: 0.118337
Within R2: 5.704e-4
Add a new chunk by clicking the Insert Chunk button on the
toolbar or by pressing Ctrl+Alt+I.
When you save the notebook, an HTML file containing the code and
output will be saved alongside it (click the Preview button or
press Ctrl+Shift+K to preview the HTML file).
The preview shows you a rendered HTML copy of the contents of the
editor. Consequently, unlike Knit, Preview does not
run any R code chunks. Instead, the output of the chunk when it was last
run in the editor is displayed.
LS0tDQp0aXRsZTogIlBhcGVyIDMvRFJDIEV4cGxvcmF0b3J5IFJlZ3MiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCiNsb2FkIGxpYnJhcmllcw0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KGZpeGVzdCkNCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkoc2YpDQoNCmBgYA0KDQpgYGB7cn0NCiMgVHVybiBvZmYgc2NpZW50aWZpYyBub3RhdGlvbiBnbG9iYWxseQ0KI29wdGlvbnMoc2NpcGVuID0gOTk5KQ0KDQojbG9hZCByZWxldmFudCBmaWxlcw0KI3JlYWRSRFMoIkM6L1VzZXJzL3lvc2hpYXJhL09uZURyaXZlIC0gUkFORCBDb3Jwb3JhdGlvbi9EZXNrdG9wL0Rpc3NlcnRhdGlvbi9lYXN0ZXJuIGRyYy9wYW5lbF9wM195ZWFybHkucmRzIikNCg0Kc2V0d2QoIkM6L1VzZXJzL3lvc2hpYXJhL09uZURyaXZlIC0gUkFORCBDb3Jwb3JhdGlvbi9EZXNrdG9wL0Rpc3NlcnRhdGlvbi9lYXN0ZXJuIGRyYyIpDQpgYGANCg0KDQojRGVzY3JpcHRpdmUgU3RhdHMNCg0KIyNDcm9zcy1zZWN0aW9uYWwgKDIwMjEgb25seSkNCg0KIyMjTWluaW5nIHZzLiBub24tbWluaW5nIGdyaWRzDQoNCldoYXQgZG8gbWluaW5nIHZzLiBub24tbWluaW5nIGdyaWQgY2VsbHMgbG9vayBsaWtlPyBUYWJsZSBiZWxvdyBpbmNsdWRlcyBncmlkcyBjb3ZlcmluZyBhbGwgb2YgRFJDLiBTb21lIHRoaW5ncyB0aGF0IHN0YW5kIG91dDoNCi0gTWluaW5nIGdyaWRzIGFyZSBjbG9zZXIgdG8gbmF0aW9uYWwgYm9yZGVycw0KLSBNaW5pbmcgZ3JpZHMgaGF2ZSBtb3JlIGNyb3BsYW5kIChhbGwgdHlwZXMgLSBpcnJpZ2F0ZWQsIHJhaW5mZWQsIG90aGVyKS4gRm9yIGFsbCBncmlkcywgdGhlcmUgaXMgbW9yZSByYWluZmVkIHRoYW4gaXJyaWdhdGVkIGNyb3BsYW5kLg0KLSBNaW5pbmcgZ3JpZHMgaGF2ZSBmZXdlciBwZXJtYW5lbnQgYm9kaWVzIG9mIHdhdGVyDQotIE1pbmluZyBncmlkcyBoYXZlIGhpZ2hlciBwb3B1bGF0aW9uIOKAkyBidXQgdGhpcyBjb3VsZCBqdXN0IGJlIGJlY2F1c2UgdGhlIG5vbi1taW5pbmcgZ3JpZHMgbWF5IGNhcHR1cmUgbWFueSB1bnBvcHVsYXRlZCBhcmVhcy4gVGhpcyBtYXRjaGVzIHRoZSBwYXR0ZXJuIGZvciBpbXBlcnZpb3VzL21hbm1hZGUgc3VyZmFjZXMgYnV0IG5vdCBmb3IgbmlnaHRsaWdodCBkZW5zaXR5IHdoaWNoIGlzIHRoZSBzYW1lIGZvciBib3RoIG1pbmluZyBhbmQgbm9uLW1pbmluZyBncmlkcyAod2VpcmQpDQotIE1pbmluZyBncmlkcyBoYXZlIGhpZ2hlciBjb25mbGljdCBjb3VudHMgKGFjcm9zcyBhbGwgY29uZmxpY3QgY2F0ZWdvcmllcykNCmBgYHtyfQ0KI2Rlc2NyaXB0aXZlIHN0YXRzIChtZWFucyB0YWJsZSkgbWluaW5nIHZzIG5vbl9taW5pbmcjIyMjDQojIDEpIFJlc3RyaWN0IHRvIGxhdGVzdCB5ZWFyIHdoZXJlIGFsbCB2YXJzIGV4aXN0ICgyMDIxKQ0KZGZfbGF0ZXN0IDwtIHBhbmVsX3AzX3llYXJseSAlPiUNCiAgZmlsdGVyKHllYXIgPT0gMjAyMSkgJT4lDQogIG11dGF0ZShtaW5lX2dyb3VwID0gaWZlbHNlKHRvdGFsX21pbmVfY291bnQgPT0gMCwgIk5vIG1pbmVzIiwgIj49MSBtaW5lIikpDQoNCiMgMikgVmFyaWFibGVzIHRvIHN1bW1hcml6ZQ0KdmFycyA8LSBjKA0KICAiZGlzdF90b19ib3JkZXIiLA0KICAiZm9yZXN0IiwiZ3Jhc3NsYW5kIiwiaW1wZXJ2aW91cyIsImlycmlnYXRlZF9jcm9wcyIsDQogICJuaWdodGxpZ2h0cyIsIm90aGVyX2Nyb3BzIiwicGVybWFuZW50X3dhdGVyIiwNCiAgInJhaW5mZWRfY3JvcHMiLCJzZWFzb25hbF93YXRlciIsInNocnVibGFuZCIsDQogICJzcGFyc2UiLCJzd2FtcCIsInBvcCIsICJuX2NvbmZsaWN0cyIsICJuX2JhdHRsZXMiLCAibl9wcm90ZXN0cyINCikNCg0KIyBoZWxwZXI6IGNvZXJjZSB0byBudW1lcmljIGlmIG5lZWRlZCAoaGFuZGxlcyBmYWN0b3JzL2NoYXJhY3RlcnMpDQp0b19udW0gPC0gZnVuY3Rpb24oeCkgew0KICBpZiAoaXMubnVtZXJpYyh4KSkgcmV0dXJuKHgpDQogIGlmIChpcy5mYWN0b3IoeCkpICByZXR1cm4oYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoeCkpKQ0KICBpZiAoaXMuY2hhcmFjdGVyKHgpKSByZXR1cm4oc3VwcHJlc3NXYXJuaW5ncyhhcy5udW1lcmljKHgpKSkNCiAgcmV0dXJuKHN1cHByZXNzV2FybmluZ3MoYXMubnVtZXJpYyh4KSkpDQp9DQoNCiMgMykgUnVuIHQtdGVzdHMgKyBidWlsZCByZXN1bHRzDQp0X3Rlc3RfcmVzdWx0cyA8LSBsYXBwbHkodmFycywgZnVuY3Rpb24odikgew0KICB4IDwtIHRvX251bShkZl9sYXRlc3RbW3ZdXSkNCiAgZyA8LSBkZl9sYXRlc3QkbWluZV9ncm91cA0KICANCiAgIyBncm91cCBtZWFucw0KICBtMCA8LSBtZWFuKHhbZyA9PSAiTm8gbWluZXMiXSwgbmEucm0gPSBUUlVFKQ0KICBtMSA8LSBtZWFuKHhbZyA9PSAiPj0xIG1pbmUiXSwgbmEucm0gPSBUUlVFKQ0KICANCiAgIyB0LXRlc3QgKFdlbGNoKQ0KICB0dCA8LSB0LnRlc3QoeCB+IGcpDQogIA0KICBkYXRhLmZyYW1lKA0KICAgIHZhcmlhYmxlID0gdiwNCiAgICBtZWFuX25vX21pbmVzID0gbTAsDQogICAgbWVhbl9taW5lcyA9IG0xLA0KICAgIHBfdmFsdWUgPSB0dCRwLnZhbHVlDQogICkNCn0pICU+JQ0KICBiaW5kX3Jvd3MoKSAlPiUNCiAgbXV0YXRlKHNpZyA9IGNhc2Vfd2hlbigNCiAgICBwX3ZhbHVlIDwgMC4wMDEgfiAiKioqIiwNCiAgICBwX3ZhbHVlIDwgMC4wMSAgfiAiKioiLA0KICAgIHBfdmFsdWUgPCAwLjA1ICB+ICIqIiwNCiAgICBUUlVFIH4gIiINCiAgKSkNCg0KDQoNCiMgUm91bmQgbnVtZXJpYyBjb2x1bW5zIHRvIDMgZGVjaW1hbHMNCnRfdGVzdF9yZXN1bHRzX2NsZWFuIDwtIHRfdGVzdF9yZXN1bHRzICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC54LCAzKSkpDQoNCiMgLS0tIDEpIENvdW50IGdyaWRzIGluIGVhY2ggZ3JvdXAgLS0tDQpncm91cF9jb3VudHMgPC0gZGZfbGF0ZXN0ICU+JQ0KICBncm91cF9ieShtaW5lX2dyb3VwKSAlPiUNCiAgc3VtbWFyaXNlKE5fZ3JpZHMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQoNCiMgRXh0cmFjdCBjb3VudHMNCk5fbm9fbWluZXMgPC0gZ3JvdXBfY291bnRzJE5fZ3JpZHNbZ3JvdXBfY291bnRzJG1pbmVfZ3JvdXAgPT0gIk5vIG1pbmVzIl0NCk5fbWluZXMgICAgPC0gZ3JvdXBfY291bnRzJE5fZ3JpZHNbZ3JvdXBfY291bnRzJG1pbmVfZ3JvdXAgPT0gIj49MSBtaW5lIl0NCg0KIyAtLS0gMikgQWRkIGNvdW50cyB0byByZXN1bHRzIHRhYmxlIC0tLQ0KdF90ZXN0X3Jlc3VsdHNfY2xlYW4gPC0gdF90ZXN0X3Jlc3VsdHMgJT4lDQogIG11dGF0ZSgNCiAgICBOX25vX21pbmVzID0gTl9ub19taW5lcywNCiAgICBOX21pbmVzICAgID0gTl9taW5lcw0KICApICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC54LCAzKSkpDQoNCiMgLS0tIDMpIFZpZXcgdGFibGUgLS0tDQoNCiN0dXJuIG9mIHBhZ2luYXRpb24gZm9yIHRhYmxlcw0KRFQ6OmRhdGF0YWJsZSgNCiAgdF90ZXN0X3Jlc3VsdHNfY2xlYW4sDQogIG9wdGlvbnMgPSBsaXN0KA0KICAgIHBhZ2VMZW5ndGggPSBucm93KHRfdGVzdF9yZXN1bHRzX2NsZWFuKSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCg0KYGBgDQojIyNNaW5pbmcgdnMuIG5vbi1taW5pbmcgZ3JpZHMgKGV4Y2x1ZGluZyBncmlkcyB3aXRoIGZld2VyIHRoYW4gMjUgcGVvcGxlKQ0KDQpUaGlzIGlzIHRoZSBzYW1lIHRhYmxlIGFzIHRoZSBvbmUgYWJvdmUsIGV4Y2VwdCBub3cgSSdtIHJlc3RyaWN0aW5nIHRvIGdyaWQgY2VsbHMgd2l0aCBhdCBsZWFzdCAyNSBwZW9wbGUuIFRoZSByZXN1bHRzIGFyZSBnZW5lcmFsbHkgY29uc2lzdGVudCB3aXRoIHRoZSBwYXR0ZXJucyBpbiB0aGUgcHJldmlvdXMgdGFibGUuDQpgYGB7cn0NCiNkZXNjcmlwdGl2ZSBzdGF0cyAobWVhbnMgdGFibGUpIG1pbmluZyB2cyBub25fbWluaW5nIChwb3B1bGF0aW9uID49IDI1KSMjIyMNCiMgMSkgUmVzdHJpY3QgdG8gbGF0ZXN0IHllYXIgd2hlcmUgYWxsIHZhcnMgZXhpc3QgKDIwMjEpDQpkZl9sYXRlc3RfcG9wIDwtIGRmX2xhdGVzdCAlPiUNCiAgZmlsdGVyKHBvcCA+PSAyNSkgDQoNCg0KIyAzKSBSdW4gdC10ZXN0cyArIGJ1aWxkIHJlc3VsdHMNCnRfdGVzdF9yZXN1bHRzIDwtIGxhcHBseSh2YXJzLCBmdW5jdGlvbih2KSB7DQogIHggPC0gdG9fbnVtKGRmX2xhdGVzdF9wb3BbW3ZdXSkNCiAgZyA8LSBkZl9sYXRlc3RfcG9wJG1pbmVfZ3JvdXANCiAgDQogICMgZ3JvdXAgbWVhbnMNCiAgbTAgPC0gbWVhbih4W2cgPT0gIk5vIG1pbmVzIl0sIG5hLnJtID0gVFJVRSkNCiAgbTEgPC0gbWVhbih4W2cgPT0gIj49MSBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogICMgdC10ZXN0IChXZWxjaCkNCiAgdHQgPC0gdC50ZXN0KHggfiBnKQ0KICANCiAgZGF0YS5mcmFtZSgNCiAgICB2YXJpYWJsZSA9IHYsDQogICAgbWVhbl9ub19taW5lcyA9IG0wLA0KICAgIG1lYW5fbWluZXMgPSBtMSwNCiAgICBwX3ZhbHVlID0gdHQkcC52YWx1ZQ0KICApDQp9KSAlPiUNCiAgYmluZF9yb3dzKCkgJT4lDQogIG11dGF0ZShzaWcgPSBjYXNlX3doZW4oDQogICAgcF92YWx1ZSA8IDAuMDAxIH4gIioqKiIsDQogICAgcF92YWx1ZSA8IDAuMDEgIH4gIioqIiwNCiAgICBwX3ZhbHVlIDwgMC4wNSAgfiAiKiIsDQogICAgVFJVRSB+ICIiDQogICkpDQoNCg0KDQojIFJvdW5kIG51bWVyaWMgY29sdW1ucyB0byAzIGRlY2ltYWxzDQp0X3Rlc3RfcmVzdWx0c19jbGVhbiA8LSB0X3Rlc3RfcmVzdWx0cyAlPiUNCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiByb3VuZCgueCwgMykpKQ0KDQojIC0tLSAxKSBDb3VudCBncmlkcyBpbiBlYWNoIGdyb3VwIC0tLQ0KZ3JvdXBfY291bnRzIDwtIGRmX2xhdGVzdF9wb3AgJT4lDQogIGdyb3VwX2J5KG1pbmVfZ3JvdXApICU+JQ0KICBzdW1tYXJpc2UoTl9ncmlkcyA9IG4oKSwgLmdyb3VwcyA9ICJkcm9wIikNCg0KIyBFeHRyYWN0IGNvdW50cw0KTl9ub19taW5lcyA8LSBncm91cF9jb3VudHMkTl9ncmlkc1tncm91cF9jb3VudHMkbWluZV9ncm91cCA9PSAiTm8gbWluZXMiXQ0KTl9taW5lcyAgICA8LSBncm91cF9jb3VudHMkTl9ncmlkc1tncm91cF9jb3VudHMkbWluZV9ncm91cCA9PSAiPj0xIG1pbmUiXQ0KDQojIC0tLSAyKSBBZGQgY291bnRzIHRvIHJlc3VsdHMgdGFibGUgLS0tDQp0X3Rlc3RfcmVzdWx0c19jbGVhbiA8LSB0X3Rlc3RfcmVzdWx0cyAlPiUNCiAgbXV0YXRlKA0KICAgIE5fbm9fbWluZXMgPSBOX25vX21pbmVzLA0KICAgIE5fbWluZXMgICAgPSBOX21pbmVzDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyAtLS0gMykgVmlldyB0YWJsZSAtLS0NCiN0dXJuIG9mIHBhZ2luYXRpb24gZm9yIHRhYmxlcw0KRFQ6OmRhdGF0YWJsZSgNCiAgdF90ZXN0X3Jlc3VsdHNfY2xlYW4sDQogIG9wdGlvbnMgPSBsaXN0KA0KICAgIHBhZ2VMZW5ndGggPSBucm93KHRfdGVzdF9yZXN1bHRzX2NsZWFuKSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCmBgYA0KIyMjTWluZXJhbCB0eXBlIHRyZWF0bWVudCBjYXRlZ29yaWVzICgzVEcgdnMuIG5vbi0zVEcgbWluZXMpDQoNCkhlcmUgSSdtIGFnYWluIHJlc3RyaWN0aW5nIHRvIG1pbmluZyBncmlkcywgYnV0IGNvbXBhcmluZyBncmlkcyB0aGF0IG1pbmUgdGhlIDNURyAodGluLHRhbnRhbHVtLCB0dW5nc3RlbiwgYW5kIGdvbGQpIHdpdGggZ3JpZHMgdGhhdCBtaW5lIG90aGVyIG1hdGVyaWFscy4gVGhlIDNURyBhcmUgdGhlIG1pbmVyYWxzIGNvdmVyZWQgYnkgdGhlIERGIEFjdC4gVGhpcyBpcyB0aGUgYWx0ZXJuYXRlIGlkZW50aWZpY2F0aW9uIHN0cmF0ZWd5IEkgd2FudCB0byBleHBsb3JlIGluIHBhcGVyIDMuIFRoZXJlIGlzIG9ubHkgb25lIGdyaWQgY2VsbCB3aXRoIGJvdGggM1RHIGFuZCBub24tM1RHIG1pbmVzLkhlcmUgd2Ugc2VlIHRoYXQ6DQotIDNURyBncmlkcyBoYXZlIG1vcmUgY3JvcHMgKGlycmlnYXRlZCBhbmQgcmFpbmZlZCkNCi0gTXVjaCBoaWdoZXIgcG9wdWxhdGlvbiBpbiBub24tM1RHIG1pbmluZyBncmlkcywgd2hpY2ggdHJhY2tzIHdpdGggaW1wZXJ2aW91cyBzdXJmYWNlcyBhbmQgbmlnaHRsaWdodHMNCi0gTW9yZSBiYXR0bGVzIGluIDNURyBncmlkcywgbW9yZSBwcm90ZXN0cyBpbiBub24tREYgZ3JpZHMNCmBgYHtyfQ0KI2Rlc2NyaXB0aXZlIHN0YXRzIChtZWFucyB0YWJsZSkgZGYgdnMgbm9uIGRmIG1pbmluZyBncmlkcyMjIyMNCiMgMSkgUmVzdHJpY3QgdG8gbGF0ZXN0IHllYXIgd2hlcmUgYWxsIHZhcnMgZXhpc3QgKDIwMjEpDQpkZl9sYXRlc3RfbWluaW5nIDwtIGRmX2xhdGVzdCAlPiUNCiAgZmlsdGVyKG1pbmVfZ3JvdXAgPT0gIj49MSBtaW5lIikgDQoNCg0KIyAzKSBSdW4gdC10ZXN0cyArIGJ1aWxkIHJlc3VsdHMNCnRfdGVzdF9yZXN1bHRzIDwtIGxhcHBseSh2YXJzLCBmdW5jdGlvbih2KSB7DQogIHggPC0gdG9fbnVtKGRmX2xhdGVzdF9taW5pbmdbW3ZdXSkNCiAgZyA8LSBkZl9sYXRlc3RfbWluaW5nJGhhc19kZl9taW5lX2R1bW15DQogIA0KICAjIGdyb3VwIG1lYW5zDQogIG0wIDwtIG1lYW4oeFtnID09IDBdLCBuYS5ybSA9IFRSVUUpDQogIG0xIDwtIG1lYW4oeFtnID09IDFdLCBuYS5ybSA9IFRSVUUpDQogIA0KICAjIHQtdGVzdCAoV2VsY2gpDQogIHR0IDwtIHQudGVzdCh4IH4gZykNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSB2LA0KICAgIG1lYW5fbm9uX2RmID0gbTAsDQogICAgbWVhbl9kZiA9IG0xLA0KICAgIHBfdmFsdWUgPSB0dCRwLnZhbHVlDQogICkNCn0pICU+JQ0KICBiaW5kX3Jvd3MoKSAlPiUNCiAgbXV0YXRlKHNpZyA9IGNhc2Vfd2hlbigNCiAgICBwX3ZhbHVlIDwgMC4wMDEgfiAiKioqIiwNCiAgICBwX3ZhbHVlIDwgMC4wMSAgfiAiKioiLA0KICAgIHBfdmFsdWUgPCAwLjA1ICB+ICIqIiwNCiAgICBUUlVFIH4gIiINCiAgKSkNCg0KDQojIFJvdW5kIG51bWVyaWMgY29sdW1ucyB0byAzIGRlY2ltYWxzDQp0X3Rlc3RfcmVzdWx0c19jbGVhbiA8LSB0X3Rlc3RfcmVzdWx0cyAlPiUNCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiByb3VuZCgueCwgMykpKQ0KDQojIC0tLSAxKSBDb3VudCBncmlkcyBpbiBlYWNoIGdyb3VwIC0tLQ0KZ3JvdXBfY291bnRzIDwtIGRmX2xhdGVzdF9taW5pbmcgJT4lDQogIGdyb3VwX2J5KGhhc19kZl9taW5lX2R1bW15KSAlPiUNCiAgc3VtbWFyaXNlKE5fZ3JpZHMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQoNCiMgRXh0cmFjdCBjb3VudHMNCk5fbm9uX2RmX21pbmVzIDwtIGdyb3VwX2NvdW50cyROX2dyaWRzW2dyb3VwX2NvdW50cyRoYXNfZGZfbWluZV9kdW1teSA9PSAwXQ0KTl9kZl9taW5lcyAgICA8LSBncm91cF9jb3VudHMkTl9ncmlkc1tncm91cF9jb3VudHMkaGFzX2RmX21pbmVfZHVtbXkgPT0gMV0NCg0KIyAtLS0gMikgQWRkIGNvdW50cyB0byByZXN1bHRzIHRhYmxlIC0tLQ0KdF90ZXN0X3Jlc3VsdHNfY2xlYW4gPC0gdF90ZXN0X3Jlc3VsdHMgJT4lDQogIG11dGF0ZSgNCiAgICBOX25vbl9kZl9taW5lcyA9IE5fbm9uX2RmX21pbmVzLA0KICAgIE5fZGZfbWluZXMgICAgPSBOX2RmX21pbmVzDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyAtLS0gMykgVmlldyB0YWJsZSAtLS0NCkRUOjpkYXRhdGFibGUoDQogIHRfdGVzdF9yZXN1bHRzX2NsZWFuLA0KICBvcHRpb25zID0gbGlzdCgNCiAgICBwYWdlTGVuZ3RoID0gbnJvdyh0X3Rlc3RfcmVzdWx0c19jbGVhbiksICAjIHNob3cgYWxsIHJvd3MNCiAgICBwYWdpbmcgPSBGQUxTRSAgICAgICAgICAgICAjIHR1cm4gcGFnaW5hdGlvbiBvZmYNCiAgKQ0KKQ0KDQpgYGANCiMjI1BhcmtlciBhbmQgVmFkaGVpbS9Eb2RkLUZyYW5rIHRyZWF0ZWQgZ3JpZHMgdnMuIHVudHJlYXRlZCBncmlkcw0KDQpOb3cgSSdtIGxvb2tpbmcgb25seSBhIG1pbmluZyBncmlkcywgY29tcGFyaW5nIGdyaWRzIHRoYXQgd2VyZSAidHJlYXRlZCIgcGVyIHRoZSBQViBzdHVkeSAoaS5lLiB0aGF0IGFyZSBsb2NhdGVkIGluIGNvbmZsaWN0IGFmZmVjdGVkIG1pbmluZyBhcmVhcyBwZXIgdGhlIDIwMTEgU3RhdGUgRGVwYXJ0bWVudCBtYXApIHRvIHVudHJlYXRlZCBtaW5pbmcgZ3JpZHMgcGVyIHRoZSBQViBzdHVkeToNCi0gVGhlcmUgaXMgbGVzcyBvZiBhIHBvcHVsYXRpb24gZGVsdGEgdGhhbiBpbiB0aGUgcHJldmlvdXMgdGFibGUgKHRoZSAzVEcgdnMuIG5vbi0zVEcgbWluaW5nIGdyaWQgY29tcGFyaXNvbikuIEknbSBub3Qgc3VyZSB3aGF0IHRoaXMgbWVhbnMgaW4gdGVybXMgb2YgdGhpbmtpbmcgdGhyb3VnaCBQVidzIHZzLiBteSBpZGVudGlmaWNhdGlvbiBzdHJhdGVneS4NCi0gTm8gc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGluIG1lYW4gY29uZmxpY3QgY291bnRzIGluIFBWLURGIHRyZWF0ZWQgdnMuIHVudHJlYXRlZCBtaW5pbmcgZ3JpZHMuIEFnYWluLCBub3Qgc3VyZSB3aGF0IHRoYXQgaW1wbGllcy4NCmBgYHtyfQ0KDQoNCiMgMykgUnVuIHQtdGVzdHMgKyBidWlsZCByZXN1bHRzDQp0X3Rlc3RfcmVzdWx0cyA8LSBsYXBwbHkodmFycywgZnVuY3Rpb24odikgew0KICB4IDwtIHRvX251bShkZl9sYXRlc3RfbWluaW5nW1t2XV0pDQogIGcgPC0gZGZfbGF0ZXN0X21pbmluZyRwb2xpY3lfdGVycg0KICANCiAgIyBncm91cCBtZWFucw0KICBtMCA8LSBtZWFuKHhbZyA9PSAwXSwgbmEucm0gPSBUUlVFKQ0KICBtMSA8LSBtZWFuKHhbZyA9PSAxXSwgbmEucm0gPSBUUlVFKQ0KICANCiAgIyB0LXRlc3QgKFdlbGNoKQ0KICB0dCA8LSB0LnRlc3QoeCB+IGcpDQogIA0KICBkYXRhLmZyYW1lKA0KICAgIHZhcmlhYmxlID0gdiwNCiAgICBtZWFuX25vbl9kZiA9IG0wLA0KICAgIG1lYW5fZGYgPSBtMSwNCiAgICBwX3ZhbHVlID0gdHQkcC52YWx1ZQ0KICApDQp9KSAlPiUNCiAgYmluZF9yb3dzKCkgJT4lDQogIG11dGF0ZShzaWcgPSBjYXNlX3doZW4oDQogICAgcF92YWx1ZSA8IDAuMDAxIH4gIioqKiIsDQogICAgcF92YWx1ZSA8IDAuMDEgIH4gIioqIiwNCiAgICBwX3ZhbHVlIDwgMC4wNSAgfiAiKiIsDQogICAgVFJVRSB+ICIiDQogICkpDQoNCg0KDQojIFJvdW5kIG51bWVyaWMgY29sdW1ucyB0byAzIGRlY2ltYWxzDQp0X3Rlc3RfcmVzdWx0c19jbGVhbiA8LSB0X3Rlc3RfcmVzdWx0cyAlPiUNCiAgbXV0YXRlKGFjcm9zcyh3aGVyZShpcy5udW1lcmljKSwgfiByb3VuZCgueCwgMykpKQ0KDQojIC0tLSAxKSBDb3VudCBncmlkcyBpbiBlYWNoIGdyb3VwIC0tLQ0KZ3JvdXBfY291bnRzIDwtIGRmX2xhdGVzdF9taW5pbmcgJT4lDQogIGdyb3VwX2J5KHBvbGljeV90ZXJyKSAlPiUNCiAgc3VtbWFyaXNlKE5fZ3JpZHMgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpDQoNCiMgRXh0cmFjdCBjb3VudHMNCk5fbm9uX2RmX3RlcnIgPC0gZ3JvdXBfY291bnRzJE5fZ3JpZHNbZ3JvdXBfY291bnRzJHBvbGljeV90ZXJyID09IDBdDQpOX2RmX3RlcnIgICAgPC0gZ3JvdXBfY291bnRzJE5fZ3JpZHNbZ3JvdXBfY291bnRzJHBvbGljeV90ZXJyID09IDFdDQoNCiMgLS0tIDIpIEFkZCBjb3VudHMgdG8gcmVzdWx0cyB0YWJsZSAtLS0NCnRfdGVzdF9yZXN1bHRzX2NsZWFuIDwtIHRfdGVzdF9yZXN1bHRzICU+JQ0KICBtdXRhdGUoDQogICAgTl9ub25fZGZfdGVyciA9IE5fbm9uX2RmX3RlcnIsDQogICAgTl9kZl90ZXJyICAgID0gTl9kZl90ZXJyDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyAtLS0gMykgVmlldyB0YWJsZSAtLS0NCkRUOjpkYXRhdGFibGUoDQogIHRfdGVzdF9yZXN1bHRzX2NsZWFuLA0KICBvcHRpb25zID0gbGlzdCgNCiAgICBwYWdlTGVuZ3RoID0gbnJvdyh0X3Rlc3RfcmVzdWx0c19jbGVhbiksICAjIHNob3cgYWxsIHJvd3MNCiAgICBwYWdpbmcgPSBGQUxTRSAgICAgICAgICAgICAjIHR1cm4gcGFnaW5hdGlvbiBvZmYNCiAgKQ0KKQ0KYGBgDQojI1JhdGUgb2YgY2hhbmdlIChjb21wYXJpbmcgMjAwMy0yMDA2IGFuZCAyMDE5LTIwMjEpDQoNCiMjI01pbmluZyB2cy4gbm9uLW1pbmluZyBncmlkcw0KLSBNb3JlIGRlZm9yZXN0YXRpb24gaW4gbWluaW5nIGdyaWRzDQotIE1vcmUgY3JvcGxhbmQgZ3Jvd3RoIChpcnJpZ2F0ZWQsIHJhaW5mZWQpIGluIG1pbmluZyBncmlkcw0KLSBNb3JlIHBvcHVsYXRpb24gZ3Jvd3RoIGluIG1pbmluZyBncmlkcw0KLSBMYXJnZXIgaW5jcmVhc2UgaW4gY29uZmxpY3QgaW4gbWluaW5nIGdyaWRzDQpgYGB7cn0NCiNhbm51YWwgY2hhbmdlcyBtaW5pbmcgdi4gbm9uLW1pbmluZyMjIyMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMCkgQ2hvb3NlIHRoZSB5ZWFybHkgdmFyaWFibGVzIChlZGl0IHRoaXMgbGlzdCBpZiB5b3Ugd2FudCkNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCnllYXJseV92YXJzIDwtIGMoDQogICJmb3Jlc3QiLCJncmFzc2xhbmQiLCJpbXBlcnZpb3VzIiwiaXJyaWdhdGVkX2Nyb3BzIiwNCiAgIm5pZ2h0bGlnaHRzIiwib3RoZXJfY3JvcHMiLCJwZXJtYW5lbnRfd2F0ZXIiLA0KICAicmFpbmZlZF9jcm9wcyIsInNlYXNvbmFsX3dhdGVyIiwic2hydWJsYW5kIiwic3BhcnNlIiwic3dhbXAiLCJwb3AiLA0KICAibl9jb25mbGljdHMiLCJuX2JhdHRsZXMiLCJuX3Byb3Rlc3RzIg0KKQ0KDQojIGhlbHBlcjogY29lcmNlIHRvIG51bWVyaWMgc2FmZWx5IChoYW5kbGVzIGZhY3Rvci9jaGFyYWN0ZXIgbnVtYmVycykNCnRvX251bSA8LSBmdW5jdGlvbih4KSB7DQogIGlmIChpcy5udW1lcmljKHgpKSByZXR1cm4oeCkNCiAgaWYgKGlzLmZhY3Rvcih4KSkgIHJldHVybihhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih4KSkpDQogIGlmIChpcy5jaGFyYWN0ZXIoeCkpIHJldHVybihzdXBwcmVzc1dhcm5pbmdzKGFzLm51bWVyaWMoeCkpKQ0KICByZXR1cm4oc3VwcHJlc3NXYXJuaW5ncyhhcy5udW1lcmljKHgpKSkNCn0NCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAxKSBDcmVhdGUgYSBzdGF0aWMgbWluZSBncm91cCBwZXIgaGV4X2lkIChObyBtaW5lcyB2cyA+PTEgbWluZSkNCiMgICAgVXNlcyB0aGUgbWF4aW11bSB0b3RhbF9taW5lX2NvdW50IG9ic2VydmVkIGZvciBlYWNoIGhleCAocm9idXN0KQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KbWluZV9ncm91cF9ieV9oZXggPC0gcGFuZWxfcDNfeWVhcmx5ICU+JQ0KICBncm91cF9ieShoZXhfaWQpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfbWluZV9jb3VudF9zdGF0aWMgPSBtYXgodG9fbnVtKHRvdGFsX21pbmVfY291bnQpLCBuYS5ybSA9IFRSVUUpLA0KICAgIG1pbmVfZ3JvdXAgPSBpZmVsc2UodG90YWxfbWluZV9jb3VudF9zdGF0aWMgPT0gMCwgIk5vIG1pbmVzIiwgIj49MSBtaW5lIiksDQogICAgLmdyb3VwcyA9ICJkcm9wIg0KICApDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMikgQ29tcHV0ZSBoZXgtbGV2ZWwgYXZlcmFnZXMgaW4gZWFjaCBwZXJpb2QsIHRoZW4gY2hhbmdlIChwb3N0IC0gcHJlKQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KaGV4X3BlcmlvZF9hdmdzIDwtIHBhbmVsX3AzX3llYXJseSAlPiUNCiAgc2VsZWN0KGhleF9pZCwgeWVhciwgYWxsX29mKHllYXJseV92YXJzKSkgJT4lDQogIG11dGF0ZSh5ZWFyID0gdG9fbnVtKHllYXIpKSAlPiUNCiAgZmlsdGVyKHllYXIgJWluJSBjKDIwMDM6MjAwNiwgMjAxOToyMDIxKSkgJT4lDQogIG11dGF0ZShwZXJpb2QgPSBpZmVsc2UoeWVhciA8PSAyMDA2LCAicHJlXzIwMDNfMDYiLCAicG9zdF8yMDE5XzIxIikpICU+JQ0KICAjIGVuc3VyZSB2YXJzIG51bWVyaWMNCiAgbXV0YXRlKGFjcm9zcyhhbGxfb2YoeWVhcmx5X3ZhcnMpLCB0b19udW0pKSAlPiUNCiAgZ3JvdXBfYnkoaGV4X2lkLCBwZXJpb2QpICU+JQ0KICBzdW1tYXJpc2UoYWNyb3NzKGFsbF9vZih5ZWFybHlfdmFycyksIH4gbWVhbigueCwgbmEucm0gPSBUUlVFKSksIC5ncm91cHMgPSAiZHJvcCIpICU+JQ0KICBwaXZvdF93aWRlcigNCiAgICBuYW1lc19mcm9tID0gcGVyaW9kLA0KICAgIHZhbHVlc19mcm9tID0gYWxsX29mKHllYXJseV92YXJzKSwNCiAgICBuYW1lc19zZXAgPSAiX18iDQogICkNCg0KIyBjb21wdXRlIGNoYW5nZSBmb3IgZWFjaCB2YXI6IHBvc3QgLSBwcmUNCiMgSm9pbiBtaW5lIGdyb3VwIG9udG8gdGhlIHdpZGUgcGVyaW9kLWF2ZXJhZ2VkIGRhdGENCnRtcCA8LSBoZXhfcGVyaW9kX2F2Z3MgJT4lDQogIGxlZnRfam9pbihtaW5lX2dyb3VwX2J5X2hleCwgYnkgPSAiaGV4X2lkIikNCg0KIyBDcmVhdGUgY2hhbmdlIGNvbHVtbnM6IHBvc3QgLSBwcmUNCmZvciAodiBpbiB5ZWFybHlfdmFycykgew0KICBwb3N0X2NvbCA8LSBwYXN0ZTAodiwgIl9fcG9zdF8yMDE5XzIxIikNCiAgcHJlX2NvbCAgPC0gcGFzdGUwKHYsICJfX3ByZV8yMDAzXzA2IikNCiAgdG1wW1twYXN0ZTAoImNoZ19fIiwgdildXSA8LSB0bXBbW3Bvc3RfY29sXV0gLSB0bXBbW3ByZV9jb2xdXQ0KfQ0KDQojIEtlZXAgb25seSB3aGF0IHlvdSBuZWVkDQpoZXhfY2hhbmdlcyA8LSB0bXAgJT4lDQogIHNlbGVjdChoZXhfaWQsIG1pbmVfZ3JvdXAsIHN0YXJ0c193aXRoKCJjaGdfXyIpKQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDMpIENvbXBhcmUgbWVhbiBjaGFuZ2VzIGFjcm9zcyBtaW5lIGdyb3VwcyAoV2VsY2ggdC10ZXN0KSwgYnVpbGQgdGFibGUNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmNoZ192YXJzIDwtIHBhc3RlMCgiY2hnX18iLCB5ZWFybHlfdmFycykNCg0KZGlmZl9pbl9jaGFuZ2VzIDwtIGxhcHBseShjaGdfdmFycywgZnVuY3Rpb24odikgew0KICB4IDwtIGhleF9jaGFuZ2VzW1t2XV0NCiAgZyA8LSBoZXhfY2hhbmdlcyRtaW5lX2dyb3VwDQogIA0KICBvayA8LSAhaXMubmEoeCkgJiAhaXMubmEoZykNCiAgeCA8LSB4W29rXTsgZyA8LSBnW29rXQ0KICANCiAgbTAgPC0gbWVhbih4W2cgPT0gIk5vIG1pbmVzIl0sIG5hLnJtID0gVFJVRSkNCiAgbTEgPC0gbWVhbih4W2cgPT0gIj49MSBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogIHR0IDwtIHQudGVzdCh4IH4gZykgICMgV2VsY2gNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSBzdWIoIl5jaGdfXyIsICIiLCB2KSwNCiAgICBtZWFuX2NoYW5nZV9ub19taW5lcyA9IG0wLA0KICAgIG1lYW5fY2hhbmdlX21pbmVzICAgID0gbTEsDQogICAgZGlmZl9jaGFuZ2UgICAgICAgICAgPSBtMSAtIG0wLA0KICAgIHBfdmFsdWUgICAgICAgICAgICAgID0gdHQkcC52YWx1ZQ0KICApDQp9KSAlPiUNCiAgYmluZF9yb3dzKCkgJT4lDQogIG11dGF0ZSgNCiAgICBzaWcgPSBjYXNlX3doZW4oDQogICAgICBwX3ZhbHVlIDwgMC4wMDEgfiAiKioqIiwNCiAgICAgIHBfdmFsdWUgPCAwLjAxICB+ICIqKiIsDQogICAgICBwX3ZhbHVlIDwgMC4wNSAgfiAiKiIsDQogICAgICBUUlVFIH4gIiINCiAgICApDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyBncm91cCBOcyAobnVtYmVyIG9mIGhleGVzIGNvbnRyaWJ1dGluZyB0byB0aGUgY2hhbmdlIGFuYWx5c2lzKQ0KZ3JvdXBfTnMgPC0gaGV4X2NoYW5nZXMgJT4lDQogIGNvdW50KG1pbmVfZ3JvdXApDQoNCmdyb3VwX05zDQoNCkRUOjpkYXRhdGFibGUoDQogIGRpZmZfaW5fY2hhbmdlcywNCiAgb3B0aW9ucyA9IGxpc3QoDQogICAgcGFnZUxlbmd0aCA9IG5yb3coZGlmZl9pbl9jaGFuZ2VzKSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCmBgYA0KIyMjTWluaW5nIHZzLiBub24tbWluaW5nIGdyaWRzIChleGNsdWRpbmcgZ3JpZHMgd2l0aCBmZXdlciB0aGFuIDI1IHBlb3BsZSkNCg0KU2FtZSB0YWJsZSBhcyB0aGUgb25lIGFib3ZlIGJ1dCByZXN0cmljdGluZyB0byBncmlkcyB3aXRoIGF0IGxlYXN0IDI1IHBlb3BsZS4gUmVzdWx0cyBnZW5lcmFsbHkgdHJhY2sgd2l0aCB0aGUgcHJldmlvdXMgdGFibGUuDQpgYGB7cn0NCiNhbm51YWwgY2hhbmdlcyBtaW5pbmcgdi4gbm9uLW1pbmluZyAocG9wPj0yNSkjIyMjDQoNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAxKSBSZXN0cmljdCB0byBoZXhlcyB3aXRoIHByZS1wZXJpb2QgYXZnIHBvcCA+PSAyNQ0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KDQpoZXhfY2hhbmdlc19wb3AyNSA8LSBoZXhfcGVyaW9kX2F2Z3MgJT4lDQogIGxlZnRfam9pbihtaW5lX2dyb3VwX2J5X2hleCwgYnkgPSAiaGV4X2lkIikgJT4lDQogIGZpbHRlcihwb3BfX3ByZV8yMDAzXzA2ID49IDI1KQ0KDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDIpIENyZWF0ZSBjaGFuZ2UgdmFyaWFibGVzDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCnRtcCA8LSBoZXhfY2hhbmdlc19wb3AyNQ0KDQpmb3IgKHYgaW4geWVhcmx5X3ZhcnMpIHsNCiAgcG9zdF9jb2wgPC0gcGFzdGUwKHYsICJfX3Bvc3RfMjAxOV8yMSIpDQogIHByZV9jb2wgIDwtIHBhc3RlMCh2LCAiX19wcmVfMjAwM18wNiIpDQogIHRtcFtbcGFzdGUwKCJjaGdfXyIsIHYpXV0gPC0gdG1wW1twb3N0X2NvbF1dIC0gdG1wW1twcmVfY29sXV0NCn0NCg0KaGV4X2NoYW5nZXNfcG9wMjUgPC0gdG1wICU+JQ0KICBzZWxlY3QoaGV4X2lkLCBtaW5lX2dyb3VwLCBzdGFydHNfd2l0aCgiY2hnX18iKSkNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyAzKSBDb21wYXJlIG1lYW4gY2hhbmdlcyBhY3Jvc3MgbWluZSBncm91cHMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KY2hnX3ZhcnMgPC0gcGFzdGUwKCJjaGdfXyIsIHllYXJseV92YXJzKQ0KDQpkaWZmX2luX2NoYW5nZXNfcG9wMjUgPC0gbGFwcGx5KGNoZ192YXJzLCBmdW5jdGlvbih2KSB7DQogIA0KICB4IDwtIGhleF9jaGFuZ2VzX3BvcDI1W1t2XV0NCiAgZyA8LSBoZXhfY2hhbmdlc19wb3AyNSRtaW5lX2dyb3VwDQogIA0KICBvayA8LSAhaXMubmEoeCkgJiAhaXMubmEoZykNCiAgeCA8LSB4W29rXTsgZyA8LSBnW29rXQ0KICANCiAgbTAgPC0gbWVhbih4W2cgPT0gIk5vIG1pbmVzIl0sIG5hLnJtID0gVFJVRSkNCiAgbTEgPC0gbWVhbih4W2cgPT0gIj49MSBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogIHR0IDwtIHQudGVzdCh4IH4gZykNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSBzdWIoIl5jaGdfXyIsICIiLCB2KSwNCiAgICBtZWFuX2NoYW5nZV9ub19taW5lcyA9IG0wLA0KICAgIG1lYW5fY2hhbmdlX21pbmVzICAgID0gbTEsDQogICAgZGlmZl9jaGFuZ2UgICAgICAgICAgPSBtMSAtIG0wLA0KICAgIHBfdmFsdWUgICAgICAgICAgICAgID0gdHQkcC52YWx1ZQ0KICApDQp9KSAlPiUNCiAgYmluZF9yb3dzKCkgJT4lDQogIG11dGF0ZSgNCiAgICBzaWcgPSBjYXNlX3doZW4oDQogICAgICBwX3ZhbHVlIDwgMC4wMDEgfiAiKioqIiwNCiAgICAgIHBfdmFsdWUgPCAwLjAxICB+ICIqKiIsDQogICAgICBwX3ZhbHVlIDwgMC4wNSAgfiAiKiIsDQogICAgICBUUlVFIH4gIiINCiAgICApDQogICkgJT4lDQogIG11dGF0ZShhY3Jvc3Mod2hlcmUoaXMubnVtZXJpYyksIH4gcm91bmQoLngsIDMpKSkNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyA0KSBHcm91cCBjb3VudHMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KZ3JvdXBfTnNfcG9wMjUgPC0gaGV4X2NoYW5nZXNfcG9wMjUgJT4lDQogIGNvdW50KG1pbmVfZ3JvdXApDQoNCmdyb3VwX05zX3BvcDI1DQoNCkRUOjpkYXRhdGFibGUoDQogIGRpZmZfaW5fY2hhbmdlc19wb3AyNSwNCiAgb3B0aW9ucyA9IGxpc3QoDQogICAgcGFnZUxlbmd0aCA9IG5yb3coZGlmZl9pbl9jaGFuZ2VzX3BvcDI1KSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCmBgYA0KDQojIyNNaW5lcmFsIHR5cGUgdHJlYXRtZW50IGNhdGVnb3JpZXMgKDNURyB2cy4gbm9uLTNURyBtaW5lcykNCg0KLSBMZXNzIGZvcmVzdCBsb3NzIGluIDNURyBtaW5lcmFsIGdyaWRzLCB3aGljaCB0cmFja3Mgd2l0aCBsb3dlciBuaWdodGxpZ2h0LCBwb3AgYW5kIGltcGVydmlvdXMgZ3Jvd3RoDQotIEhpZ2hlciBjcm9wbGFuZCBncm93dGggKGlycmlnYXRlZCwgcmFpbmZlZCkgaW4gM1RHIG1pbmVyYWwgZ3JpZHMNCi0gSGlnaGVyIGdyb3d0aCBpbiBjb25mbGljdHMgb3ZlcmFsbCBhbmQgYmF0dGxlcyBidXQgbm90IHByb3Rlc3RzIGZvciAzVEcgbWluZXJhbCBncmlkcw0KYGBge3J9DQojYW5udWFsIGNoYW5nZXMgZGYgdnMuIG5vbiBkZiBtaW5lcmFsIGdyaWRzIyMjIw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMSkgQnVpbGQgYSBoZXgtbGV2ZWwgREYgZ3JvdXBpbmcgdmFyaWFibGUsIGFuZCByZXN0cmljdCB0byBtaW5pbmcgZ3JpZHMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpkZl9ncm91cF9ieV9oZXggPC0gcGFuZWxfcDNfeWVhcmx5ICU+JQ0KICBncm91cF9ieShoZXhfaWQpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfbWluZV9jb3VudF9zdGF0aWMgPSBmaXJzdChuYS5vbWl0KHRvX251bSh0b3RhbF9taW5lX2NvdW50KSkpLA0KICAgIGhhc19kZl9zdGF0aWMgICAgICAgICAgID0gZmlyc3QobmEub21pdCh0b19udW0oaGFzX2RmX21pbmVfZHVtbXkpKSksDQogICAgZGZfZ3JvdXAgPSBpZmVsc2UoaGFzX2RmX3N0YXRpYyA9PSAxLCAiREYgbWluZSIsICJOb24tREYgbWluZSIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKSAlPiUNCiAgZmlsdGVyKHRvdGFsX21pbmVfY291bnRfc3RhdGljID49IDEpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDIpIEpvaW4gb250byB0aGUgcGVyaW9kLWF2ZXJhZ2Ugd2lkZSBkYXRhIGFuZCBjb21wdXRlIGNoYW5nZXMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQp0bXAgPC0gaGV4X3BlcmlvZF9hdmdzICU+JQ0KICBpbm5lcl9qb2luKGRmX2dyb3VwX2J5X2hleCAlPiUgc2VsZWN0KGhleF9pZCwgZGZfZ3JvdXApLCBieSA9ICJoZXhfaWQiKQ0KDQojIGNoYW5nZSBjb2x1bW5zOiBwb3N0IC0gcHJlDQpmb3IgKHYgaW4geWVhcmx5X3ZhcnMpIHsNCiAgcG9zdF9jb2wgPC0gcGFzdGUwKHYsICJfX3Bvc3RfMjAxOV8yMSIpDQogIHByZV9jb2wgIDwtIHBhc3RlMCh2LCAiX19wcmVfMjAwM18wNiIpDQogIHRtcFtbcGFzdGUwKCJjaGdfXyIsIHYpXV0gPC0gdG1wW1twb3N0X2NvbF1dIC0gdG1wW1twcmVfY29sXV0NCn0NCg0KaGV4X2NoYW5nZXNfZGZfdnNfbm9uZGYgPC0gdG1wICU+JQ0KICBzZWxlY3QoaGV4X2lkLCBkZl9ncm91cCwgc3RhcnRzX3dpdGgoImNoZ19fIikpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDMpIENvbXBhcmUgbWVhbiBjaGFuZ2VzIGFjcm9zcyBERiB2cyBub24tREYgKFdlbGNoIHQtdGVzdHMpDQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KY2hnX3ZhcnMgPC0gcGFzdGUwKCJjaGdfXyIsIHllYXJseV92YXJzKQ0KDQpkaWZmX2luX2NoYW5nZXNfZGZfdnNfbm9uZGYgPC0gbGFwcGx5KGNoZ192YXJzLCBmdW5jdGlvbih2KSB7DQogIA0KICB4IDwtIGhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmW1t2XV0NCiAgZyA8LSBoZXhfY2hhbmdlc19kZl92c19ub25kZiRkZl9ncm91cA0KICANCiAgb2sgPC0gIWlzLm5hKHgpICYgIWlzLm5hKGcpDQogIHggPC0geFtva107IGcgPC0gZ1tva10NCiAgDQogIG0wIDwtIG1lYW4oeFtnID09ICJOb24tREYgbWluZSJdLCBuYS5ybSA9IFRSVUUpDQogIG0xIDwtIG1lYW4oeFtnID09ICJERiBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogIHR0IDwtIHQudGVzdCh4IH4gZykgICMgV2VsY2gNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSBzdWIoIl5jaGdfXyIsICIiLCB2KSwNCiAgICBtZWFuX2NoYW5nZV9ub25fZGYgPSBtMCwNCiAgICBtZWFuX2NoYW5nZV9kZiAgICAgPSBtMSwNCiAgICBkaWZmX2NoYW5nZSAgICAgICAgPSBtMSAtIG0wLA0KICAgIHBfdmFsdWUgICAgICAgICAgICA9IHR0JHAudmFsdWUNCiAgKQ0KfSkgJT4lDQogIGJpbmRfcm93cygpICU+JQ0KICBtdXRhdGUoDQogICAgc2lnID0gY2FzZV93aGVuKA0KICAgICAgcF92YWx1ZSA8IDAuMDAxIH4gIioqKiIsDQogICAgICBwX3ZhbHVlIDwgMC4wMSAgfiAiKioiLA0KICAgICAgcF92YWx1ZSA8IDAuMDUgIH4gIioiLA0KICAgICAgVFJVRSB+ICIiDQogICAgKQ0KICApICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC54LCAzKSkpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDQpIEdyb3VwIGNvdW50cw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmdyb3VwX05zX2RmX3ZzX25vbmRmIDwtIGhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmICU+JQ0KICBjb3VudChkZl9ncm91cCkNCg0KZ3JvdXBfTnNfZGZfdnNfbm9uZGYNCg0KRFQ6OmRhdGF0YWJsZSgNCiAgZGlmZl9pbl9jaGFuZ2VzX2RmX3ZzX25vbmRmLA0KICBvcHRpb25zID0gbGlzdCgNCiAgICBwYWdlTGVuZ3RoID0gbnJvdyhkaWZmX2luX2NoYW5nZXNfZGZfdnNfbm9uZGYpLCAgIyBzaG93IGFsbCByb3dzDQogICAgcGFnaW5nID0gRkFMU0UgICAgICAgICAgICAgIyB0dXJuIHBhZ2luYXRpb24gb2ZmDQogICkNCikNCg0KYGBgDQoNCiMjI1BhcmtlciBhbmQgVmFkaGVpbS9Eb2RkLUZyYW5rIG1pbmluZyBncmlkcyB2cy4gbm9uLURGIG1pbmluZyBncmlkcw0KDQotIE5vIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiBjb25mbGljdCBjb3VudCBncm93dGggaW4gUFYtREYgdHJlYXRlZCB2cy4gdW50cmVhdGVkIG1pbmluZyBncmlkcy4NCmBgYHtyfQ0KI2FubnVhbCBjaGFuZ2VzIGRmIHZzLiBub24gZGYgcG9saWN5IGdyaWRzIyMjIw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMSkgQnVpbGQgYSBoZXgtbGV2ZWwgREYgZ3JvdXBpbmcgdmFyaWFibGUsIGFuZCByZXN0cmljdCB0byBtaW5pbmcgZ3JpZHMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpkZl9ncm91cF9ieV9oZXggPC0gcGFuZWxfcDNfeWVhcmx5ICU+JQ0KICBncm91cF9ieShoZXhfaWQpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgdG90YWxfbWluZV9jb3VudF9zdGF0aWMgPSBmaXJzdChuYS5vbWl0KHRvX251bSh0b3RhbF9taW5lX2NvdW50KSkpLA0KICAgIGhhc19wb2xpY3lfc3RhdGljICAgICAgICAgICA9IGZpcnN0KG5hLm9taXQodG9fbnVtKHBvbGljeV90ZXJyKSkpLA0KICAgIHBvbGljeV9ncm91cCA9IGlmZWxzZShoYXNfcG9saWN5X3N0YXRpYyA9PSAxLCAiREYgbWluZSIsICJOb24tREYgbWluZSIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCINCiAgKSAlPiUNCiAgZmlsdGVyKHRvdGFsX21pbmVfY291bnRfc3RhdGljID49IDEpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDIpIEpvaW4gb250byB0aGUgcGVyaW9kLWF2ZXJhZ2Ugd2lkZSBkYXRhIGFuZCBjb21wdXRlIGNoYW5nZXMNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQp0bXAgPC0gaGV4X3BlcmlvZF9hdmdzICU+JQ0KICBpbm5lcl9qb2luKGRmX2dyb3VwX2J5X2hleCAlPiUgc2VsZWN0KGhleF9pZCwgcG9saWN5X2dyb3VwKSwgYnkgPSAiaGV4X2lkIikNCg0KIyBjaGFuZ2UgY29sdW1uczogcG9zdCAtIHByZQ0KZm9yICh2IGluIHllYXJseV92YXJzKSB7DQogIHBvc3RfY29sIDwtIHBhc3RlMCh2LCAiX19wb3N0XzIwMTlfMjEiKQ0KICBwcmVfY29sICA8LSBwYXN0ZTAodiwgIl9fcHJlXzIwMDNfMDYiKQ0KICB0bXBbW3Bhc3RlMCgiY2hnX18iLCB2KV1dIDwtIHRtcFtbcG9zdF9jb2xdXSAtIHRtcFtbcHJlX2NvbF1dDQp9DQoNCmhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmIDwtIHRtcCAlPiUNCiAgc2VsZWN0KGhleF9pZCwgcG9saWN5X2dyb3VwLCBzdGFydHNfd2l0aCgiY2hnX18iKSkNCg0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMgMykgQ29tcGFyZSBtZWFuIGNoYW5nZXMgYWNyb3NzIERGIHZzIG5vbi1ERiAoV2VsY2ggdC10ZXN0cykNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpjaGdfdmFycyA8LSBwYXN0ZTAoImNoZ19fIiwgeWVhcmx5X3ZhcnMpDQoNCmRpZmZfaW5fY2hhbmdlc19kZl92c19ub25kZiA8LSBsYXBwbHkoY2hnX3ZhcnMsIGZ1bmN0aW9uKHYpIHsNCiAgDQogIHggPC0gaGV4X2NoYW5nZXNfZGZfdnNfbm9uZGZbW3ZdXQ0KICBnIDwtIGhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmJHBvbGljeV9ncm91cA0KICANCiAgb2sgPC0gIWlzLm5hKHgpICYgIWlzLm5hKGcpDQogIHggPC0geFtva107IGcgPC0gZ1tva10NCiAgDQogIG0wIDwtIG1lYW4oeFtnID09ICJOb24tREYgbWluZSJdLCBuYS5ybSA9IFRSVUUpDQogIG0xIDwtIG1lYW4oeFtnID09ICJERiBtaW5lIl0sIG5hLnJtID0gVFJVRSkNCiAgDQogIHR0IDwtIHQudGVzdCh4IH4gZykgICMgV2VsY2gNCiAgDQogIGRhdGEuZnJhbWUoDQogICAgdmFyaWFibGUgPSBzdWIoIl5jaGdfXyIsICIiLCB2KSwNCiAgICBtZWFuX2NoYW5nZV9ub25fZGYgPSBtMCwNCiAgICBtZWFuX2NoYW5nZV9kZiAgICAgPSBtMSwNCiAgICBkaWZmX2NoYW5nZSAgICAgICAgPSBtMSAtIG0wLA0KICAgIHBfdmFsdWUgICAgICAgICAgICA9IHR0JHAudmFsdWUNCiAgKQ0KfSkgJT4lDQogIGJpbmRfcm93cygpICU+JQ0KICBtdXRhdGUoDQogICAgc2lnID0gY2FzZV93aGVuKA0KICAgICAgcF92YWx1ZSA8IDAuMDAxIH4gIioqKiIsDQogICAgICBwX3ZhbHVlIDwgMC4wMSAgfiAiKioiLA0KICAgICAgcF92YWx1ZSA8IDAuMDUgIH4gIioiLA0KICAgICAgVFJVRSB+ICIiDQogICAgKQ0KICApICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCB+IHJvdW5kKC54LCAzKSkpDQoNCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIDQpIEdyb3VwIGNvdW50cw0KIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCmdyb3VwX05zX2RmX3ZzX25vbmRmIDwtIGhleF9jaGFuZ2VzX2RmX3ZzX25vbmRmICU+JQ0KICBjb3VudChwb2xpY3lfZ3JvdXApDQoNCmdyb3VwX05zX2RmX3ZzX25vbmRmDQoNCkRUOjpkYXRhdGFibGUoDQogIGRpZmZfaW5fY2hhbmdlc19kZl92c19ub25kZiwNCiAgb3B0aW9ucyA9IGxpc3QoDQogICAgcGFnZUxlbmd0aCA9IG5yb3coZGlmZl9pbl9jaGFuZ2VzX2RmX3ZzX25vbmRmKSwgICMgc2hvdyBhbGwgcm93cw0KICAgIHBhZ2luZyA9IEZBTFNFICAgICAgICAgICAgICMgdHVybiBwYWdpbmF0aW9uIG9mZg0KICApDQopDQoNCmBgYA0KI1JlZ3Jlc3Npb25zDQoNCiMjT3V0Y29tZTogUHIoQmF0dGxlIE9jY3VyZW5jZSkNCg0KIyMjUFYgYmFzZWxpbmUgbW9kZWwgYnV0IHdpdGggZ3JpZHMNCkxvb2tpbmcgYXQgdGhlIG91dGNvbWU6IHByb2JhYmlsaXR5IG9mIGFueSBiYXR0bGUgb2NjdXJyaW5nLiBTYW1lIGFzIFBWIHN0dWR5IGJ1dCB1c2luZyBncmlkIGNlbGxzIGluc3RlYWQgb2YgdGVycml0b3JpZXMgYXMgdGhlIHVuaXQgb2YgYW5hbHlzaXMgKHNvIGEgbXVjaCBzbWFsbGVyIHVuaXRlZCBvZiBhbmFseXNpcyB0aGF0IGRvZXNuJ3QgZm9sbG93IHBvbGl0aWNhbCBib3VuZGFyaWVzKS4gT25seSBwb2xpY3lfZHVtbXkgKGluZGljYXRvciBmb3IgZ3JpZHMgaW4gYSB0ZXJyaXRvcnkgZmxhZ2dlZCBhcyBjb25mbGljdC1hZmZlY3RlZCBieSBTdGF0ZSBEZXAgaW4gMjAwOC0yMDEwKSBpcyBzdGF0IHNpZyAoYXQgKioqLCAwLjAwMDE4NykuIEludGVyYWN0aW9uIHRlcm1zIHdpdGggbnVtYmVyIG9mIG1pbmUgdmFyaWFibGVzIGFyZW4ndC4NCmBgYHtyfQ0KI2FueSBiYXR0bGVzLCBtYXRjaGluZyBQViBidXQgYXQgZ3JpZCB2cy4gdGVycml0b3J5IGxldmVsIyMjIw0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teSArIHBvbGljeV9kdW1teTppc18zdF9jb3VudCArIHBvbGljeV9kdW1teTppc19nb2xkX2NvdW50IHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IHB2X21vbnRoc19ncmlkcw0KKQ0KDQojIENsdXN0ZXItcm9idXN0IHN1bW1hcnkNCnN1bW1hcnkobW9kLCBjbHVzdGVyID0gImhleF9pZCIpDQpgYGANCiMjI1BWIGJhc2VsaW5lIG1vZGVsIHdpdGggZ3JpZC1sZXZlbCB0cmVhdG1lbnQgYXNzaWdubWVudA0KDQpOb3cgSSdtIGFzc2lnbmluZyB0cmVhdG1lbnQgYXQgdGhlIGdyaWQgbGV2ZWwsIHJhdGhlciB0aGFuIGF0IHRoZSB0ZXJyaXRvcnkgbGV2ZWwsIGJhc2VkIG9uIHdoZXRoZXIgdGhlIGdyaWQgaXMgaW4gYSBTdGF0ZSBEZXBhcnRtZW50IHBvbGljeSB0ZXJyaXRvcnkgKyBoYXMgYSAzVEcgbWluZS4gV2hlbiBJIGFzc2lnbiB0cmVhdG1lbnQgbW9yZSBncmFudWxhcmx5LCB0aGUgdHJlYXRtZW50IGVmZmVjdCBnb2VzIGF3YXkuDQpgYGB7cn0NCiNhbnkgYmF0dGxlcywgbWF0Y2hpbmcgUFYgYnV0IGF0IGdyaWQgdnMuIHRlcnJpdG9yeSBsZXZlbCMjIyMNCm1vZCA8LSBmZW9scygNCiAgYW55X2JhdHRsZXMgfiBkZl9wb2xpY3lfZ3JpZHMgKyBkZl9wb2xpY3lfZ3JpZHM6aXNfM3RfY291bnQgKyBkZl9wb2xpY3lfZ3JpZHM6aXNfZ29sZF9jb3VudCB8IGhleF9pZCArIHRpbWVfaWQsDQogIGRhdGEgPSBwdl9tb250aHNfZ3JpZHMNCikNCg0KIyBDbHVzdGVyLXJvYnVzdCBzdW1tYXJ5DQpzdW1tYXJ5KG1vZCwgY2x1c3RlciA9ICJoZXhfaWQiKQ0KYGBgDQojIyNHb3Zlcm5tZW50IGJhbiB0cmVhdG1lbnQNCg0KTm93IEkibSBpZ25vcmluZyBEb2RkLUZyYW5rIGFuZCBsb29raW5nIGluc3RlYWQgYXQgdGhlIGdvdmVybm1lbnQgYmFuIG9uIGFydGlzYW5hbCBtaW5pbmcgdGhhdCBvY2N1cnJlZCBhdCB0aGUgc2FtZSB0aW1lIHRoYXQgREYgd2FzIHBhc3NlZC4gSGVyZSBJJ20gdXNpbmcgdGhlIHNhbWUgYXBwcm9hY2ggYXMgUFYgKGJ1dCBhdCB0aGUgZ3JpZCBsZXZlbCB2cyB0ZXJyaXRvcnkgbGV2ZWwpLiBUaGUgYmFuIGNvdmVyZWQgMyBwcm92aW5jZXMsIHdoaWNoIGVuY29tcGFzcyA0NCBvZiB0aGUgNTEgdHJlYXRlZCB0ZXJyaXRvcmllcyBpbiB0aGUgUFYgc3R1ZHkuIFRoZXJlIGlzIGEgcmVkdWN0aW9uIGluIHRoZSBwcm9iYWJpbGl0eSBvZiBleHBlcmllbmNpbmcgYSBiYXR0bGUgaW4gZ292X2JhbiBwcm92aW5jZXMuIA0KYGBge3J9DQoNCiN3aGF0IGlmIHdlIGp1c3QgbG9vayBhdCB0aGUgZ292IGJhbiMjIyMNCm1vZCA8LSBmZW9scygNCiAgYW55X2JhdHRsZXMgfiBnb3ZfYmFuICsgZ292X2Jhbjppc18zdF9jb3VudCArIGdvdl9iYW46aXNfZ29sZF9jb3VudCB8IGhleF9pZCArIHRpbWVfaWQsDQogIGRhdGEgPSBwdl9tb250aHNfZ3JpZHMNCikNCg0KIyBDbHVzdGVyLXJvYnVzdCBzdW1tYXJ5DQpzdW1tYXJ5KG1vZCwgY2x1c3RlciA9ICJoZXhfaWQiKQ0KYGBgDQoNCiMjI0dvdmVybm1lbnQgYmFuIGFzc2lnbmVkIGF0IHRoZSBncmlkIGxldmVsDQoNCk5vdyBJJ20gYXNzaWduaW5nIHRoZSBzYW1lIGdvdmVybm1lbnQgYmFuIHRyZWF0bWVudCBidXQgYXQgdGhlIGdyaWQgbGV2ZWwgaW5zdGVhZCBvZiBhdCB0aGUgdGVycml0b3J5IGxldmVsLCBiYXNlZCBvbiB3aGV0aGVyIHRoZSBncmlkIGlzIGluIGEgcHJvdmluY2UgdGFyZ2V0ZWQgYnkgdGhlIGdvdmVybm1lbnQgYmFuICsgaGFzIGEgM1RHIG1pbmUuIFdoZW4gSSBhc3NpZ24gdHJlYXRtZW50IG1vcmUgZ3JhbnVsYXJseSwgdGhlIGNvZWZmaWNpZW50IG9uIHRoZSBQcihiYXR0bGUpIHJlbWFpbnMgbmVnYXRpdmUsIGJ1dCBub3cgdGhlIGludGVyYWN0aW9uIHRlcm0gd2l0aCB0aGUgbnVtYmVyIG9mIGdvbGQgbWluZXMgYmVjb21lcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IChhbmQgaXMgcG9zaXRpdmUpLg0KYGBge3J9DQojd2hhdCBpZiB3ZSBhc3NpZ24gZ292IGJhbiB0cmVhdG1lbnQgYXQgdGhlIGdyaWQgbGV2ZWwNCm1vZCA8LSBmZW9scygNCiAgYW55X2JhdHRsZXMgfiBnb3ZfYmFuX2dyaWRzICsgZ292X2Jhbl9ncmlkczppc18zdF9jb3VudCArIGdvdl9iYW5fZ3JpZHM6aXNfZ29sZF9jb3VudCB8IGhleF9pZCArIHRpbWVfaWQsDQogIGRhdGEgPSBwdl9tb250aHNfZ3JpZHMNCikNCg0KIyBDbHVzdGVyLXJvYnVzdCBzdW1tYXJ5DQpzdW1tYXJ5KG1vZCwgY2x1c3RlciA9ICJoZXhfaWQiKQ0KDQpgYGANCg0KIyMjQm90aCBQVi1ERiB0cmVhdG1lbnQgYW5kIGdvdmVybm1lbnQgYmFuDQoNCk5vdyBJJ20gbG9va2luZyBhdCB0aGUgUFYtREYgdHJlYXRtZW50ICsgZ292ZXJubWVudCBiYW4gc2ltdWx0YW5lb3VzbHkuIEZpcnN0IHJlZ3Jlc3Npb24gaGFzIHRyZWF0bWVudCBhc3NpZ25lZCBhdCB0aGUgdGVycml0b3J5IG9yIHByb3ZpbmNlIGxldmVsLiBTZWNvbmQgcmVncmVzc2lvbiBoYXMgdHJlYXRtZW50IGFzc2lnbmVkIGF0IHRoZSBncmlkIGxldmVsLiBXaGVuIHRyZWF0bWVudCBpcyBhc3NpZ25lZCBhdCB0aGUgdGVycml0b3J5L3Byb3ZpbmNlIGxldmVsLCB0aGUgdHdvIHBvbGljaWVzIHdvcmsgaW4gb3Bwb3NpdGUgZGlyZWN0aW9ucyBhbmQgYXJlIGJvdGggc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gV2hlbiB0cmVhdG1lbnQgaXMgYXNzaWduZWQgYXQgdGhlIGdyaWQgbGV2ZWwsIHRoZXkgYXJlIGJvdGggbmVnYXRpdmUgYW5kIHN0YXQgaW5zaWduaWZpY2FudC4NCmBgYHtyfQ0KDQojd2hhdCBpcyB3ZSBsb29rIGF0IGJvdGggZGYgYW5kIGdvdiBncmlkcw0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teSArIGdvdl9iYW4gfCBoZXhfaWQgKyB0aW1lX2lkLA0KICBkYXRhID0gcHZfbW9udGhzX2dyaWRzDQopDQoNCiMgQ2x1c3Rlci1yb2J1c3Qgc3VtbWFyeQ0Kc3VtbWFyeShtb2QsIGNsdXN0ZXIgPSAiaGV4X2lkIikNCg0KI3NhbWUgcmVncmVzc2lvbiBidXQgd2l0aCB0cmVhdG1lbnQgYXNzaWduZWQgYXQgdGhlIGdyaWQgbGV2ZWwNCm1vZCA8LSBmZW9scygNCiAgYW55X2JhdHRsZXMgfiBkZl9wb2xpY3lfZ3JpZHMgKyBnb3ZfYmFuX2dyaWRzIHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IHB2X21vbnRoc19ncmlkcw0KKQ0KDQojIENsdXN0ZXItcm9idXN0IHN1bW1hcnkNCnN1bW1hcnkobW9kLCBjbHVzdGVyID0gImhleF9pZCIpDQoNCmBgYA0KIyMjQWx0ZXJuYXRlIHRyZWF0bWVudCB0aW1pbmcgKE1heSAyMDEzKQ0KDQpOb3cgSSdtIGV4cGxvcmluZyB3aGV0aGVyIHVzaW5nIGEgbGF0ZXIgdHJlYXRtZW50IHN0YXJ0aW5nIHRpbWUgY2hhbmdlcyB0aGUgb3JpZ2luYWwgUFYgcmVzdWx0cy4gU3BlY2lmaWNhbGx5LCB3aGlsZSBEb2RkLUZyYW5rIHdhcyBwYXNzZWQgaW4gSnVseSAyMDEwLCBjb21wYW5pZXMgZGlkbid0IGhhdmUgdG8gZmlsZSB0aGVpciBmaXJzdCBjb25mbGljdCBtaW5lcmFsIGRpc2Nsb3N1cmUgcmVwb3J0cyB1bnRpbCBNYXkgMjAxNC4gSSdtIHVzaW5nIEp1bmUgMjAxMyAtLSBvbmUgeWVhciBiZWZvcmUgdGhlIGZpcnN0IGNvbXBhbnkgZmlsaW5nIC0tIGFzIG15IGFsdGVybmF0ZSB0cmVhdG1lbnQgc3RhcnQgdGltaW5nLiBJJ20gYWxzbyBleHRlbmRpbmcgdGhlIHRpbWVmcmFtZSBmcm9tIDIwMTIgKFBWIHN0dWR5KSB0byAyMDIwLiBBbGwgdGhyZWUgY29lZmZpY2llbnRzIG9mIGludGVyZXN0IGFyZSBwb3NpdGl2ZSBhbmQgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4NCmBgYHtyfQ0KI01heSAyMDEzIHRyZWF0bWVudCMjIyMNCg0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teV8yMDEzICsgcG9saWN5X2R1bW15XzIwMTM6aXNfM3RfY291bnQgKyBwb2xpY3lfZHVtbXlfMjAxMzppc19nb2xkX2NvdW50IHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IGZ1bGxfbW9udGhzX2dyaWRzDQopDQoNCiMgQ2x1c3Rlci1yb2J1c3Qgc3VtbWFyeQ0Kc3VtbWFyeShtb2QsIGNsdXN0ZXIgPSAiaGV4X2lkIikNCg0KDQpgYGANCiMjI01pbmVyYWwgdHlwZSB0cmVhdG1lbnQgYXNzaWdubWVudA0KDQpOb3cgSSdtIGV4cGxvcmluZyB0aGUgdXNlIG9mIGFuIGFsdGVybmF0ZSB0cmVhdG1lbnQgYXNzaWdubWVudCBiYXNlZCBvbiB3aGV0aGVyIHRoZSBncmlkIGNlbGwgaGFzIGEgM1RHIG1pbmUgdnMgbm9uLTNURyBtaW5lLiBGaXJzdCByZWdyZXNzaW9uIHVzZXMgdGhlIEp1bHkgMjAxMCB0cmVhdG1lbnQgdGltaW5nLCBzZWNvbmQgdGhlIEp1bmUgMjAxMyB0aW1pbmcuIEJvdGggc2hvdyBhIHBvc2l0aXZlLCBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHRyZWF0bWVudCBlZmZlY3QuDQoNCmBgYHtyfQ0KI01pbmVyYWwgdHlwZSB0cmVhdG1lbnQgYW5kIDIwMTAgb3IgMjAxMyB0cmVhdG1lbnQjIyMjDQojMjAxMw0KcGFuZWxfbW9udGggPC0gcGFuZWxfbW9udGggJT4lDQogIG11dGF0ZSgNCiAgICBwb2xpY3lfZHVtbXlfMjAxM190aW1lb25seSA9IGFzLmludGVnZXIodGltZV9pZCA+PSAyMDEzMDZMKQ0KICApDQoNCmZ1bGxfbW9udGhzX2dyaWRzIDwtIHBhbmVsX21vbnRoICU+JQ0KICBkcGx5cjo6ZmlsdGVyKA0KICAgIHllYXIgPj0gMjAwNCwNCiAgICB5ZWFyIDw9IDIwMjAsDQogICAgZWFzdGVybl90ZXJyID09IDENCiAgKQ0KDQojMjAxMA0KcGFuZWxfbW9udGggPC0gcGFuZWxfbW9udGggJT4lDQogIG11dGF0ZSgNCiAgICBwb2xpY3lfZHVtbXlfMjAxMF90aW1lb25seSA9IGFzLmludGVnZXIodGltZV9pZCA+PSAyMDEwMDdMKQ0KICApDQoNCg0KDQpwdl9tb250aHNfZ3JpZHMgPC0gcGFuZWxfbW9udGggJT4lDQogIGRwbHlyOjpmaWx0ZXIoDQogICAgeWVhciA+PSAyMDA0LA0KICAgIHllYXIgPD0gMjAxMiwNCiAgICBlYXN0ZXJuX3RlcnIgPT0gMQ0KICApDQoNCiMyMDEzIHJlZw0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teV8yMDEzX3RpbWVvbmx5Omhhc19kZl9taW5lX2R1bW15IHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IGZ1bGxfbW9udGhzX2dyaWRzDQopDQoNCiMgQ2x1c3Rlci1yb2J1c3Qgc3VtbWFyeQ0Kc3VtbWFyeShtb2QsIGNsdXN0ZXIgPSAiaGV4X2lkIikNCg0KIzIwMTAgcmVnDQptb2QgPC0gZmVvbHMoDQogIGFueV9iYXR0bGVzIH4gcG9saWN5X2R1bW15XzIwMTBfdGltZW9ubHk6aGFzX2RmX21pbmVfZHVtbXkgfCBoZXhfaWQgKyB0aW1lX2lkLA0KICBkYXRhID0gcHZfbW9udGhzX2dyaWRzDQopDQoNCiMgQ2x1c3Rlci1yb2J1c3Qgc3VtbWFyeQ0Kc3VtbWFyeShtb2QsIGNsdXN0ZXIgPSAiaGV4X2lkIikNCg0KDQoNCmBgYA0KSGVyZSBJJ20gaW50cm9kdWNpbmcgc29tZSB5ZWFybHkgY292YXJpYXRlcyAocG9wdWxhdGlvbiwgbmlnaHRsaWdodHMgYW5kIHNlbGVjdCBsYW5kIHVzZSBjYXRlZ29yaWVzKS4gVGhpcyBpcyB0aGUgYmFzZWxpbmUgUFYgc3BlY2lmaWNhdGlvbiAoMjAxMCB0cmVhdG1lbnQsIFN0YXRlIERlcGFydG1lbnQgbWFwKS4gSW50ZXJlc3RpbmcgdGhhdCB3aGlsZSB0aGUgcG9saWN5IHN1bW15IHJlbWFpbnMgcG9zaXRpdmUgYW5kIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQsIHRoZSBpbnRlcmFjdGlvbiB0ZXJtIG9uIHRoZSBudW1iZXIgb2YgZ29sZCBtaW5lcyBkb2VzIG5vdC4gVGhlIG9ubHkgY292YXJpYXRlIHRoYXQgc2VlbXMgdG8gcG9wIGlzIHJhaW5mZWQgY3JvcHMuDQoNCmBgYHtyfQ0KI2Jhc2VsaW5lIFBWIHdpdGggUlMgY29udHJvbHMNCg0KbW9kIDwtIGZlb2xzKA0KICBhbnlfYmF0dGxlcyB+IHBvbGljeV9kdW1teSArIHBvbGljeV9kdW1teTppc18zdF9jb3VudCArIHBvbGljeV9kdW1teTppc19nb2xkX2NvdW50ICsgcG9wICsgbmlnaHRsaWdodHMgKyBpcnJpZ2F0ZWRfY3JvcHMgKyByYWluZmVkX2Nyb3BzICsgZm9yZXN0IHwgaGV4X2lkICsgdGltZV9pZCwNCiAgZGF0YSA9IHB2X21vbnRoc19ncmlkcw0KKQ0KDQojIENsdXN0ZXItcm9idXN0IHN1bW1hcnkNCnN1bW1hcnkobW9kLCBjbHVzdGVyID0gImhleF9pZCIpDQpgYGANCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0K