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

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

plot(cars)

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Cmd+Option+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 Cmd+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.

# --- 1. LOAD LIBRARIES ---
library(sf)
library(tidyverse)
library(spdep)
library(stringr)
library(broom)

# --- 2. PREPARE NUMERIC DATA (Excel Results) ---
composite_trends_ols <- composite_index_score %>%
  mutate(Year = as.numeric(as.character(Year))) %>%
  group_by(District) %>%
  do(tidy(lm(`Composite Index Score` ~ Year, data = .))) %>%
  filter(term == "Year") %>%
  mutate(District = str_replace_all(District, "\\|", "i"), # Fixes Pan|pat
         District = str_trim(District),
         CleanName = toupper(District)) %>%
  mutate(CleanName = case_when(
    CleanName == "GURGAON" ~ "GURUGRAM",
    CleanName == "MEWAT"   ~ "NUH",
    CleanName == "CHARKHIDADRI" ~ "CHARKHI DADRI", # Fixes the no-space version
    TRUE ~ CleanName
  )) %>%
  dplyr::select(CleanName, beta_ols = estimate)

# --- 3. PREPARE SPATIAL DATA (KML Map) ---
haryana_map_clean <- st_read("~/Desktop/ec8e264b-aadd-4adf-b349-5d8a5753a22d.kml") %>%
  st_zm() %>% 
  st_make_valid() %>%
  mutate(Name = str_replace_all(Name, "\\|", "i"),
         Name = str_trim(Name),
         CleanName = toupper(Name)) %>%
  mutate(CleanName = case_when(
    CleanName == "GURGAON" ~ "GURUGRAM",
    CleanName == "MEWAT"   ~ "NUH",
    CleanName == "CHARKI DADRI" ~ "CHARKHI DADRI",
    TRUE ~ CleanName
  ))
Reading layer `Haryana Districts' from data source 
  `/Users/zhangchuanhong/Desktop/ec8e264b-aadd-4adf-b349-5d8a5753a22d.kml' 
  using driver `KML'
Simple feature collection with 22 features and 2 fields
Geometry type: MULTIPOLYGON
Dimension:     XY, XYZ
Bounding box:  xmin: 74.47326 ymin: 27.65227 xmax: 77.60459 ymax: 30.92854
z_range:       zmin: 0 zmax: 0
Geodetic CRS:  WGS 84
# --- 4. JOIN (Target: 22 Districts) ---
haryana_spatial <- haryana_map_clean %>%
  inner_join(composite_trends_ols, by = "CleanName")

print(paste("District Count for Analysis:", nrow(haryana_spatial))) 
[1] "District Count for Analysis: 22"
# --- 5. GLOBAL MORAN'S I (Power Test) ---
nb <- poly2nb(haryana_spatial, queen = TRUE)
lw <- nb2listw(nb, style = "W", zero.policy = TRUE)

set.seed(123)
moran_mc <- moran.mc(haryana_spatial$beta_ols, lw, nsim = 999, zero.policy = TRUE)
print(moran_mc)

    Monte-Carlo simulation of Moran I

data:  haryana_spatial$beta_ols 
weights: lw  
number of simulations + 1: 1000 

statistic = 0.26042, observed rank = 973, p-value = 0.027
alternative hypothesis: greater
# LISA Cluster of Index
library(sf)
library(tidyverse)
library(spdep)
library(gridExtra)
# 1. Prepare Data: Filter for the 3 key years and ensure naming matches
target_years <- c(2018, 2022, 2025)
map_data_years <- composite_index_score %>%
filter(Year %in% target_years) %>%
mutate(CleanName = toupper(str_trim(District))) %>%
mutate(CleanName = case_when(
CleanName == "GURGAON" ~ "GURUGRAM",
CleanName == "MEWAT"   ~ "NUH",
CleanName == "CHARKHIDADRI" ~ "CHARKHI DADRI",
TRUE ~ CleanName
))
# 2. Join with the Haryana SF map object
haryana_lisa <- haryana_map %>%
left_join(map_data_years, by = "CleanName")
# 3. Create a function to calculate LISA for a specific year
get_lisa_for_year <- function(yr) {
# Filter for the year
temp_sf <- haryana_lisa %>% filter(Year == yr)
# Weights matrix
nb <- poly2nb(temp_sf, queen = TRUE)
lw <- nb2listw(nb, style = "W", zero.policy = TRUE)
# Local Moran
local_m <- localmoran(temp_sf$`Composite Index Score`, lw, zero.policy = TRUE)
# Manual Quadrant calculation
scale_val <- scale(temp_sf$`Composite Index Score`)
lag_val <- lag.listw(lw, scale_val)
p_vals <- local_m[, 5]
temp_sf$Category <- "Not Significant"
# Using p <= 0.1 for small N robustness
temp_sf$Category[scale_val > 0 & lag_val > 0 & p_vals <= 0.1] <- "High-High (Hotspot)"
temp_sf$Category[scale_val < 0 & lag_val < 0 & p_vals <= 0.1] <- "Low-Low (Coldspot)"
temp_sf$Category[scale_val < 0 & lag_val > 0 & p_vals <= 0.1] <- "Low-High (Outlier)"
temp_sf$Category[scale_val > 0 & lag_val < 0 & p_vals <= 0.1] <- "High-Low (Outlier)"
return(temp_sf)
}
# 4. Run the function for all 3 years and combine
lisa_2018 <- get_lisa_for_year(2018)
lisa_2022 <- get_lisa_for_year(2022)
lisa_2025 <- get_lisa_for_year(2025)
final_lisa_data <- rbind(lisa_2018, lisa_2022, lisa_2025)
# 5. Create the Side-by-Side Plot
ggplot(data = final_lisa_data) +
geom_sf(aes(fill = Category), color = "black", size = 0.2) +
facet_wrap(~Year, ncol = 3) +
scale_fill_manual(values = c(
"High-High (Hotspot)" = "#d73027", # Red
"Low-Low (Coldspot)"  = "#4575b4", # Blue
"Low-High (Outlier)"  = "#74add1", # Light Blue
"High-Low (Outlier)"  = "#fdae61", # Orange
"Not Significant"     = "#f0f0f0"  # Grey
)) +
theme_minimal() +
theme(
legend.position = "bottom",
axis.text = element_blank(),
panel.grid = element_blank(),
strip.text = element_text(face = "bold", size = 14)
) +
labs(title = "Spatial Dynamic Evolution of Nexus Sustainability",
subtitle = "Local Indicators of Spatial Association (LISA) for 2018, 2022, and 2025",
fill = "LISA Cluster")
# 6. Save for Thesis
ggsave("Triple_LISA_Map.png", width = 15, height = 7, dpi = 300)

# LISA Cluster Evolution of Specific Pillars
# 1. Load Libraries
library(sf)
library(tidyverse)
library(spdep)
library(stringr)

# 2. Prepare the Data
pillar_data_long <- four_pillar %>%
  pivot_longer(cols = c(`Water Pillar`, `Energy Pillar`, `Food Pillar`, `Social Pillar`), 
               names_to = "Pillar", values_to = "Score") %>%
  mutate(CleanName = toupper(str_trim(District)))

# 3. Create Spatial Dataframe
final_lisa_grid <- data.frame()
pillars <- unique(pillar_data_long$Pillar)
years <- sort(unique(pillar_data_long$Year))

for (p in pillars) {
  for (y in years) {
    
    # Subset data for specific pillar and year
    subset_data <- pillar_data_long %>% filter(Pillar == p, Year == y)
    
    # Join with your cleaned haryana_map object
    temp_sf <- haryana_map %>%
      inner_join(subset_data, by = "CleanName")
    
    # Calculate Spatial Weights (Queen contiguity)
    nb <- poly2nb(temp_sf, queen = TRUE)
    lw <- nb2listw(nb, style = "W", zero.policy = TRUE)
    
    # Calculate Local Moran's I
    local_m <- localmoran(temp_sf$Score, lw, zero.policy = TRUE)
    
    # Manual Quadrant Calculation
    scale_val <- as.numeric(scale(temp_sf$Score))
    lag_val <- as.numeric(lag.listw(lw, scale_val, zero.policy = TRUE))
    p_vals <- local_m[, 5]
    
    # Classify the clusters (using p <= 0.1 for small N robustness)
    temp_sf$LISA_Cat <- "Not Significant"
    temp_sf$LISA_Cat[scale_val > 0 & lag_val > 0 & p_vals <= 0.1] <- "High-High (Hotspot)"
    temp_sf$LISA_Cat[scale_val < 0 & lag_val < 0 & p_vals <= 0.1] <- "Low-Low (Coldspot)"
    temp_sf$LISA_Cat[scale_val < 0 & lag_val > 0 & p_vals <= 0.1] <- "Low-High (Outlier)"
    temp_sf$LISA_Cat[scale_val > 0 & lag_val < 0 & p_vals <= 0.1] <- "High-Low (Outlier)"
    
    # Collect results
    final_lisa_grid <- rbind(final_lisa_grid, temp_sf)
  }
}

# 4. Visualization
ggplot(data = final_lisa_grid) +
  geom_sf(aes(fill = LISA_Cat), color = "black", size = 0.05) +
  facet_grid(Pillar ~ Year) +
  scale_fill_manual(values = c(
    "High-High (Hotspot)" = "#d73027", # Red
    "Low-Low (Coldspot)"  = "#4575b4", # Blue
    "Low-High (Outlier)"  = "#74add1", # Light Blue
    "High-Low (Outlier)"  = "#fdae61", # Orange
    "Not Significant"     = "#f0f0f0"  # Grey
  )) +
  theme_minimal() +
  theme(
    axis.text = element_blank(),
    axis.ticks = element_blank(),
    panel.grid = element_blank(),
    strip.text.x = element_text(face = "bold", size = 10),
    strip.text.y = element_text(face = "bold", size = 10, angle = 0),
    legend.position = "bottom",
    legend.title = element_text(face = "bold")
  ) +
  labs(title = "LISA Cluster Evolution of Specific Pillars (2018-2025)",
       subtitle = "4x8 Matrix of Local Indicators of Spatial Association (LISA)",
       fill = "LISA Cluster Type")

# 5. Save
ggsave("Nexus_LISA_Matrix_4x8.png", width = 18, height = 12, dpi = 300)

# Transition Velocity LISA Clusters of Specific Pillarslibrary(sf)
library(tidyverse)
library(spdep)
library(broom)

# 1. Calculate the OLS Betas for EACH Pillar separately
pillar_betas <- four_pillar_long %>%
mutate(Year = as.numeric(as.character(Year))) %>%
group_by(District, Pillar) %>%
do(tidy(lm(Score ~ Year, data = .))) %>%
filter(term == "Year") %>%
dplyr::select(District, Pillar, beta = estimate) %>%
mutate(CleanName = toupper(str_trim(District))) %>%
mutate(CleanName = case_when(
CleanName == "GURGAON" ~ "GURUGRAM",
CleanName == "MEWAT"   ~ "NUH",
CleanName == "CHARKHIDADRI" ~ "CHARKHI DADRI",
TRUE ~ CleanName
))

# 2. JOIN and Run Moran's I Loop
pillars <- unique(pillar_betas$Pillar)
moran_summary <- data.frame()
for (p in pillars) {
# Subset for current pillar and join with map
p_data <- pillar_betas %>% filter(Pillar == p)
p_spatial <- haryana_map %>% inner_join(p_data, by = "CleanName")
# Weights Matrix
nb <- poly2nb(p_spatial, queen = TRUE)
lw <- nb2listw(nb, style = "W", zero.policy = TRUE)
# Global Moran's I (Monte Carlo)
set.seed(123)
mc_res <- moran.mc(p_spatial$beta, lw, nsim = 999, zero.policy = TRUE)
# Store Result
moran_summary <- rbind(moran_summary, data.frame(
Pillar = p,
Moran_I = mc_res$statistic,
p_value = mc_res$p.value
))
}
print(moran_summary)
                  Pillar     Moran_I p_value
statistic  Energy Pillar  0.59051342   0.001
statistic1   Food Pillar -0.08374114   0.621
statistic2 Social Pillar  0.49570507   0.001
statistic3  Water Pillar  0.37901555   0.004
# 3. Cleanup the Beta Data (Regression Results)
pillar_betas_clean <- pillar_betas %>%
mutate(CleanName = District %>%
str_replace_all("\\|", "i") %>%
str_trim() %>%
toupper()) %>%
mutate(CleanName = case_when(
CleanName == "GURGAON" ~ "GURUGRAM",
CleanName == "MEWAT"   ~ "NUH",
CleanName == "CHARKHIDADRI" ~ "CHARKHI DADRI",
TRUE ~ CleanName
))

# 5. Initialize the loop for spatial analysis
pillars_to_plot <- unique(pillar_betas_clean$Pillar)
lisa_output_list <- list()
for (p in pillars_to_plot) {
# Filter for specific pillar and join with the spatial haryana_map
p_data <- pillar_betas_clean %>% filter(Pillar == p)
# Ensure haryana_map (your KML) is available and has 'CleanName'
p_spatial <- haryana_map %>%
mutate(CleanName = Name %>% str_replace_all("\\|", "i") %>% str_trim() %>% toupper()) %>%
mutate(CleanName = case_when(
CleanName == "GURGAON" ~ "GURUGRAM",
CleanName == "MEWAT"   ~ "NUH",
CleanName == "CHARKI DADRI" ~ "CHARKHI DADRI",
TRUE ~ CleanName
)) %>%
inner_join(p_data, by = "CleanName")
# Calculate Neighbors and Weights
nb <- poly2nb(p_spatial, queen = TRUE)
lw <- nb2listw(nb, style = "W", zero.policy = TRUE)
# Local Moran's I math
local_m <- localmoran(p_spatial$beta, lw, zero.policy = TRUE)
# Center the data around the mean
diff_beta <- p_spatial$beta - mean(p_spatial$beta)
# Calculate the spatial lag (what the neighbors are doing)
lag_beta <- lag.listw(lw, diff_beta, zero.policy = TRUE)
# Get p-values
p_vals <- local_m[, 5]
p_spatial$LISA_Cat <- "Not Significant"
# p <= 0.1 for small sample robustness
p_spatial$LISA_Cat[diff_beta > 0 & lag_beta > 0 & p_vals <= 0.1] <- "High-High (Hotspot)"
p_spatial$LISA_Cat[diff_beta < 0 & lag_beta < 0 & p_vals <= 0.1] <- "Low-Low (Coldspot)"
p_spatial$LISA_Cat[diff_beta < 0 & lag_beta > 0 & p_vals <= 0.1] <- "Low-High (Outlier)"
p_spatial$LISA_Cat[diff_beta > 0 & lag_beta < 0 & p_vals <= 0.1] <- "High-Low (Outlier)"
lisa_output_list[[p]] <- p_spatial
}
# Combine all pillars for the final plot
all_pillars_lisa <- do.call(rbind, lisa_output_list)

# 6. Visualization
ggplot(data = all_pillars_lisa) +
geom_sf(aes(fill = LISA_Cat), color = "black", size = 0.2) +
facet_wrap(~Pillar, ncol = 2) +
scale_fill_manual(values = c(
"High-High (Hotspot)" = "#d73027", # Red
"Low-Low (Coldspot)"  = "#4575b4", # Blue
"Low-High (Outlier)"  = "#74add1", # Light Blue
"High-Low (Outlier)"  = "#fdae61", # Orange
"Not Significant"     = "#f0f0f0"  # Grey
), name = "Momentum Type") +
theme_minimal() +
theme(
strip.text = element_text(face = "bold", size = 12),
legend.position = "bottom",
axis.text = element_blank(),
panel.grid = element_blank()
) +
labs(title = "Regional Momentum of the Agroecological Transition",
subtitle = "Local Moran's I Analysis of Pillar Growth Rates (2018-2025)")

# 7. Save
ggsave("Transition_Momentum_LISA_Final.png", width = 12, height = 10, dpi = 300)

# Link to other Indicators
library(readxl)
View(SDG)
library(tidyverse)
library(ggpubr) # For easy correlation plots

# 1. Prepare your data for the year 2024
# Filtering and selecting relevant columns from your dataframes
my_comp_2024 <- composite_index_score %>%
filter(Year == 2024) %>%
select(District, `Composite Index Score`)
my_pillars_2024 <- four_pillar %>%
filter(Year == 2024) %>%
select(District, `Water Pillar`, `Energy Pillar`, `Food Pillar`, `Social Pillar`)

# 2. Join with the SDG dataframe
comparison_df <- my_comp_2024 %>%
left_join(my_pillars_2024, by = "District") %>%
left_join(SDG, by = "District")

# --- VISUAL 1: Composite Comparison ---
# Added na.rm = TRUE inside ggscatter so geom_text_repel inherits it
plot1 <- ggscatter(comparison_df, x = "Composite Index Score", y = "SDG_Composite",
          add = "reg.line", conf.int = TRUE,
          cor.coef = TRUE, cor.method = "spearman",
          xlab = "XXXX Composite Index (2024)", ylab = "Haryana SDG Composite Score (2024)",
          title = "Validation: XXXX Index vs. Official SDG Index",
          label = "District", repel = TRUE, font.label = c(8, "plain"),
          na.rm = TRUE) + 
  theme_minimal()

# --- VISUAL 2: Pillar-Specific Validation (Faceted) ---
# Added na.rm = TRUE to geom_point, geom_smooth, AND stat_cor separately
plot2 <- ggplot(pillar_comparison, aes(x = My_Score, y = SDG_Score)) +
  geom_point(color = "steelblue", na.rm = TRUE) +
  geom_smooth(method = "lm", color = "darkred", fill = "lightgray", na.rm = TRUE) +
  stat_cor(method = "spearman", label.x.npc = "left", label.y.npc = "top", na.rm = TRUE) + 
  facet_wrap(~Pillar, scales = "free") +
  labs(title = "Pillar-Specific Validation against Corresponding SDGs",
       subtitle = "Social-SDG1, Food-SDG2, Water-SDG6, Energy-SDG7",
       x = "XXXX Pillar Scores", y = "Official SDG Scores") +
  theme_bw()

# Display Visuals without warnings popping up
print(plot1)

print(plot2)

LS0tCnRpdGxlOiAiUmVwcm9kdWN0aW9uIG9mIHRoZSBBbmFseXRpY2FsIFN0ZXBzIG9mIFdFRlNOZXh1cyBJbmRleCIKb3V0cHV0OgogIHBkZl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKLS0tCgpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLgoKVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkNtZCtTaGlmdCtFbnRlciouCgpgYGB7cn0KcGxvdChjYXJzKQpgYGAKCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDbWQrT3B0aW9uK0kqLgoKV2hlbiB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2ssIGFuIEhUTUwgZmlsZSBjb250YWluaW5nIHRoZSBjb2RlIGFuZCBvdXRwdXQgd2lsbCBiZSBzYXZlZCBhbG9uZ3NpZGUgaXQgKGNsaWNrIHRoZSAqUHJldmlldyogYnV0dG9uIG9yIHByZXNzICpDbWQrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4KClRoZSBwcmV2aWV3IHNob3dzIHlvdSBhIHJlbmRlcmVkIEhUTUwgY29weSBvZiB0aGUgY29udGVudHMgb2YgdGhlIGVkaXRvci4gQ29uc2VxdWVudGx5LCB1bmxpa2UgKktuaXQqLCAqUHJldmlldyogZG9lcyBub3QgcnVuIGFueSBSIGNvZGUgY2h1bmtzLiBJbnN0ZWFkLCB0aGUgb3V0cHV0IG9mIHRoZSBjaHVuayB3aGVuIGl0IHdhcyBsYXN0IHJ1biBpbiB0aGUgZWRpdG9yIGlzIGRpc3BsYXllZC4KCmBgYHtyfQojIC0tLSAxLiBMT0FEIExJQlJBUklFUyAtLS0KbGlicmFyeShzZikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3BkZXApCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShicm9vbSkKCiMgLS0tIDIuIFBSRVBBUkUgTlVNRVJJQyBEQVRBIChFeGNlbCBSZXN1bHRzKSAtLS0KY29tcG9zaXRlX3RyZW5kc19vbHMgPC0gY29tcG9zaXRlX2luZGV4X3Njb3JlICU+JQogIG11dGF0ZShZZWFyID0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoWWVhcikpKSAlPiUKICBncm91cF9ieShEaXN0cmljdCkgJT4lCiAgZG8odGlkeShsbShgQ29tcG9zaXRlIEluZGV4IFNjb3JlYCB+IFllYXIsIGRhdGEgPSAuKSkpICU+JQogIGZpbHRlcih0ZXJtID09ICJZZWFyIikgJT4lCiAgbXV0YXRlKERpc3RyaWN0ID0gc3RyX3JlcGxhY2VfYWxsKERpc3RyaWN0LCAiXFx8IiwgImkiKSwgIyBGaXhlcyBQYW58cGF0CiAgICAgICAgIERpc3RyaWN0ID0gc3RyX3RyaW0oRGlzdHJpY3QpLAogICAgICAgICBDbGVhbk5hbWUgPSB0b3VwcGVyKERpc3RyaWN0KSkgJT4lCiAgbXV0YXRlKENsZWFuTmFtZSA9IGNhc2Vfd2hlbigKICAgIENsZWFuTmFtZSA9PSAiR1VSR0FPTiIgfiAiR1VSVUdSQU0iLAogICAgQ2xlYW5OYW1lID09ICJNRVdBVCIgICB+ICJOVUgiLAogICAgQ2xlYW5OYW1lID09ICJDSEFSS0hJREFEUkkiIH4gIkNIQVJLSEkgREFEUkkiLCAjIEZpeGVzIHRoZSBuby1zcGFjZSB2ZXJzaW9uCiAgICBUUlVFIH4gQ2xlYW5OYW1lCiAgKSkgJT4lCiAgZHBseXI6OnNlbGVjdChDbGVhbk5hbWUsIGJldGFfb2xzID0gZXN0aW1hdGUpCgojIC0tLSAzLiBQUkVQQVJFIFNQQVRJQUwgREFUQSAoS01MIE1hcCkgLS0tCmhhcnlhbmFfbWFwX2NsZWFuIDwtIHN0X3JlYWQoIn4vRGVza3RvcC9lYzhlMjY0Yi1hYWRkLTRhZGYtYjM0OS01ZDhhNTc1M2EyMmQua21sIikgJT4lCiAgc3Rfem0oKSAlPiUgCiAgc3RfbWFrZV92YWxpZCgpICU+JQogIG11dGF0ZShOYW1lID0gc3RyX3JlcGxhY2VfYWxsKE5hbWUsICJcXHwiLCAiaSIpLAogICAgICAgICBOYW1lID0gc3RyX3RyaW0oTmFtZSksCiAgICAgICAgIENsZWFuTmFtZSA9IHRvdXBwZXIoTmFtZSkpICU+JQogIG11dGF0ZShDbGVhbk5hbWUgPSBjYXNlX3doZW4oCiAgICBDbGVhbk5hbWUgPT0gIkdVUkdBT04iIH4gIkdVUlVHUkFNIiwKICAgIENsZWFuTmFtZSA9PSAiTUVXQVQiICAgfiAiTlVIIiwKICAgIENsZWFuTmFtZSA9PSAiQ0hBUktJIERBRFJJIiB+ICJDSEFSS0hJIERBRFJJIiwKICAgIFRSVUUgfiBDbGVhbk5hbWUKICApKQoKIyAtLS0gNC4gSk9JTiAoVGFyZ2V0OiAyMiBEaXN0cmljdHMpIC0tLQpoYXJ5YW5hX3NwYXRpYWwgPC0gaGFyeWFuYV9tYXBfY2xlYW4gJT4lCiAgaW5uZXJfam9pbihjb21wb3NpdGVfdHJlbmRzX29scywgYnkgPSAiQ2xlYW5OYW1lIikKCiMgLS0tIDUuIEdMT0JBTCBNT1JBTidTIEkgKFBvd2VyIFRlc3QpIC0tLQpuYiA8LSBwb2x5Mm5iKGhhcnlhbmFfc3BhdGlhbCwgcXVlZW4gPSBUUlVFKQpsdyA8LSBuYjJsaXN0dyhuYiwgc3R5bGUgPSAiVyIsIHplcm8ucG9saWN5ID0gVFJVRSkKCnNldC5zZWVkKDEyMykKbW9yYW5fbWMgPC0gbW9yYW4ubWMoaGFyeWFuYV9zcGF0aWFsJGJldGFfb2xzLCBsdywgbnNpbSA9IDk5OSwgemVyby5wb2xpY3kgPSBUUlVFKQpwcmludChtb3Jhbl9tYykKYGBgCgpgYGB7cn0KIyBMSVNBIENsdXN0ZXIgb2YgSW5kZXgKbGlicmFyeShzZikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3BkZXApCmxpYnJhcnkoZ3JpZEV4dHJhKQojIDEuIFByZXBhcmUgRGF0YTogRmlsdGVyIGZvciB0aGUgMyBrZXkgeWVhcnMgYW5kIGVuc3VyZSBuYW1pbmcgbWF0Y2hlcwp0YXJnZXRfeWVhcnMgPC0gYygyMDE4LCAyMDIyLCAyMDI1KQptYXBfZGF0YV95ZWFycyA8LSBjb21wb3NpdGVfaW5kZXhfc2NvcmUgJT4lCmZpbHRlcihZZWFyICVpbiUgdGFyZ2V0X3llYXJzKSAlPiUKbXV0YXRlKENsZWFuTmFtZSA9IHRvdXBwZXIoc3RyX3RyaW0oRGlzdHJpY3QpKSkgJT4lCm11dGF0ZShDbGVhbk5hbWUgPSBjYXNlX3doZW4oCkNsZWFuTmFtZSA9PSAiR1VSR0FPTiIgfiAiR1VSVUdSQU0iLApDbGVhbk5hbWUgPT0gIk1FV0FUIiAgIH4gIk5VSCIsCkNsZWFuTmFtZSA9PSAiQ0hBUktISURBRFJJIiB+ICJDSEFSS0hJIERBRFJJIiwKVFJVRSB+IENsZWFuTmFtZQopKQoKIyAyLiBKb2luIHdpdGggdGhlIEhhcnlhbmEgU0YgbWFwIG9iamVjdApoYXJ5YW5hX2xpc2EgPC0gaGFyeWFuYV9tYXAgJT4lCmxlZnRfam9pbihtYXBfZGF0YV95ZWFycywgYnkgPSAiQ2xlYW5OYW1lIikKCiMgMy4gQ3JlYXRlIGEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIExJU0EgZm9yIGEgc3BlY2lmaWMgeWVhcgpnZXRfbGlzYV9mb3JfeWVhciA8LSBmdW5jdGlvbih5cikgCiMgRmlsdGVyIGZvciB0aGUgeWVhcgp0ZW1wX3NmIDwtIGhhcnlhbmFfbGlzYSAlPiUgZmlsdGVyKFllYXIgPT0geXIpCiMgV2VpZ2h0cyBtYXRyaXgKbmIgPC0gcG9seTJuYih0ZW1wX3NmLCBxdWVlbiA9IFRSVUUpCmx3IDwtIG5iMmxpc3R3KG5iLCBzdHlsZSA9ICJXIiwgemVyby5wb2xpY3kgPSBUUlVFKQojIExvY2FsIE1vcmFuCmxvY2FsX20gPC0gbG9jYWxtb3Jhbih0ZW1wX3NmJGBDb21wb3NpdGUgSW5kZXggU2NvcmVgLCBsdywgemVyby5wb2xpY3kgPSBUUlVFKQojIE1hbnVhbCBRdWFkcmFudCBjYWxjdWxhdGlvbgpzY2FsZV92YWwgPC0gc2NhbGUodGVtcF9zZiRgQ29tcG9zaXRlIEluZGV4IFNjb3JlYCkKbGFnX3ZhbCA8LSBsYWcubGlzdHcobHcsIHNjYWxlX3ZhbCkKcF92YWxzIDwtIGxvY2FsX21bLCA1XQp0ZW1wX3NmJENhdGVnb3J5IDwtICJOb3QgU2lnbmlmaWNhbnQiCiMgVXNpbmcgcCA8PSAwLjEgZm9yIHNtYWxsIE4gcm9idXN0bmVzcwp0ZW1wX3NmJENhdGVnb3J5W3NjYWxlX3ZhbCA+IDAgJiBsYWdfdmFsID4gMCAmIHBfdmFscyA8PSAwLjFdIDwtICJIaWdoLUhpZ2ggKEhvdHNwb3QpIgp0ZW1wX3NmJENhdGVnb3J5W3NjYWxlX3ZhbCA8IDAgJiBsYWdfdmFsIDwgMCAmIHBfdmFscyA8PSAwLjFdIDwtICJMb3ctTG93IChDb2xkc3BvdCkiCnRlbXBfc2YkQ2F0ZWdvcnlbc2NhbGVfdmFsIDwgMCAmIGxhZ192YWwgPiAwICYgcF92YWxzIDw9IDAuMV0gPC0gIkxvdy1IaWdoIChPdXRsaWVyKSIKdGVtcF9zZiRDYXRlZ29yeVtzY2FsZV92YWwgPiAwICYgbGFnX3ZhbCA8IDAgJiBwX3ZhbHMgPD0gMC4xXSA8LSAiSGlnaC1Mb3cgKE91dGxpZXIpIgpyZXR1cm4odGVtcF9zZikKCiMgNC4gUnVuIHRoZSBmdW5jdGlvbiBmb3IgYWxsIDMgeWVhcnMgYW5kIGNvbWJpbmUKbGlzYV8yMDE4IDwtIGdldF9saXNhX2Zvcl95ZWFyKDIwMTgpCmxpc2FfMjAyMiA8LSBnZXRfbGlzYV9mb3JfeWVhcigyMDIyKQpsaXNhXzIwMjUgPC0gZ2V0X2xpc2FfZm9yX3llYXIoMjAyNSkKZmluYWxfbGlzYV9kYXRhIDwtIHJiaW5kKGxpc2FfMjAxOCwgbGlzYV8yMDIyLCBsaXNhXzIwMjUpCgojIDUuIENyZWF0ZSB0aGUgU2lkZS1ieS1TaWRlIFBsb3QKZ2dwbG90KGRhdGEgPSBmaW5hbF9saXNhX2RhdGEpICsKZ2VvbV9zZihhZXMoZmlsbCA9IENhdGVnb3J5KSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC4yKSArCmZhY2V0X3dyYXAoflllYXIsIG5jb2wgPSAzKSArCnNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoCiJIaWdoLUhpZ2ggKEhvdHNwb3QpIiA9ICIjZDczMDI3IiwgIyBSZWQKIkxvdy1Mb3cgKENvbGRzcG90KSIgID0gIiM0NTc1YjQiLCAjIEJsdWUKIkxvdy1IaWdoIChPdXRsaWVyKSIgID0gIiM3NGFkZDEiLCAjIExpZ2h0IEJsdWUKIkhpZ2gtTG93IChPdXRsaWVyKSIgID0gIiNmZGFlNjEiLCAjIE9yYW5nZQoiTm90IFNpZ25pZmljYW50IiAgICAgPSAiI2YwZjBmMCIgICMgR3JleQopKSArCnRoZW1lX21pbmltYWwoKSArCnRoZW1lKApsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLApwYW5lbC5ncmlkID0gZWxlbWVudF9ibGFuaygpLApzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KGZhY2UgPSAiYm9sZCIsIHNpemUgPSAxNCkKKSArCmxhYnModGl0bGUgPSAiU3BhdGlhbCBEeW5hbWljIEV2b2x1dGlvbiBvZiBOZXh1cyBTdXN0YWluYWJpbGl0eSIsCnN1YnRpdGxlID0gIkxvY2FsIEluZGljYXRvcnMgb2YgU3BhdGlhbCBBc3NvY2lhdGlvbiAoTElTQSkgZm9yIDIwMTgsIDIwMjIsIGFuZCAyMDI1IiwKZmlsbCA9ICJMSVNBIENsdXN0ZXIiKQoKIyA2LiBTYXZlIGZvciBUaGVzaXMKZ2dzYXZlKCJUcmlwbGVfTElTQV9NYXAucG5nIiwgd2lkdGggPSAxNSwgaGVpZ2h0ID0gNywgZHBpID0gMzAwKQpgYGAKCgpgYGB7cn0KIyBMSVNBIENsdXN0ZXIgRXZvbHV0aW9uIG9mIFNwZWNpZmljIFBpbGxhcnMKIyAxLiBMb2FkIExpYnJhcmllcwpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShzcGRlcCkKbGlicmFyeShzdHJpbmdyKQoKIyAyLiBQcmVwYXJlIHRoZSBEYXRhCnBpbGxhcl9kYXRhX2xvbmcgPC0gZm91cl9waWxsYXIgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGBXYXRlciBQaWxsYXJgLCBgRW5lcmd5IFBpbGxhcmAsIGBGb29kIFBpbGxhcmAsIGBTb2NpYWwgUGlsbGFyYCksIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJQaWxsYXIiLCB2YWx1ZXNfdG8gPSAiU2NvcmUiKSAlPiUKICBtdXRhdGUoQ2xlYW5OYW1lID0gdG91cHBlcihzdHJfdHJpbShEaXN0cmljdCkpKQoKIyAzLiBDcmVhdGUgU3BhdGlhbCBEYXRhZnJhbWUKZmluYWxfbGlzYV9ncmlkIDwtIGRhdGEuZnJhbWUoKQpwaWxsYXJzIDwtIHVuaXF1ZShwaWxsYXJfZGF0YV9sb25nJFBpbGxhcikKeWVhcnMgPC0gc29ydCh1bmlxdWUocGlsbGFyX2RhdGFfbG9uZyRZZWFyKSkKCmZvciAocCBpbiBwaWxsYXJzKSB7CiAgZm9yICh5IGluIHllYXJzKSB7CiAgICAKICAgICMgU3Vic2V0IGRhdGEgZm9yIHNwZWNpZmljIHBpbGxhciBhbmQgeWVhcgogICAgc3Vic2V0X2RhdGEgPC0gcGlsbGFyX2RhdGFfbG9uZyAlPiUgZmlsdGVyKFBpbGxhciA9PSBwLCBZZWFyID09IHkpCiAgICAKICAgICMgSm9pbiB3aXRoIHlvdXIgY2xlYW5lZCBoYXJ5YW5hX21hcCBvYmplY3QKICAgIHRlbXBfc2YgPC0gaGFyeWFuYV9tYXAgJT4lCiAgICAgIGlubmVyX2pvaW4oc3Vic2V0X2RhdGEsIGJ5ID0gIkNsZWFuTmFtZSIpCiAgICAKICAgICMgQ2FsY3VsYXRlIFNwYXRpYWwgV2VpZ2h0cyAoUXVlZW4gY29udGlndWl0eSkKICAgIG5iIDwtIHBvbHkybmIodGVtcF9zZiwgcXVlZW4gPSBUUlVFKQogICAgbHcgPC0gbmIybGlzdHcobmIsIHN0eWxlID0gIlciLCB6ZXJvLnBvbGljeSA9IFRSVUUpCiAgICAKICAgICMgQ2FsY3VsYXRlIExvY2FsIE1vcmFuJ3MgSQogICAgbG9jYWxfbSA8LSBsb2NhbG1vcmFuKHRlbXBfc2YkU2NvcmUsIGx3LCB6ZXJvLnBvbGljeSA9IFRSVUUpCiAgICAKICAgICMgTWFudWFsIFF1YWRyYW50IENhbGN1bGF0aW9uCiAgICBzY2FsZV92YWwgPC0gYXMubnVtZXJpYyhzY2FsZSh0ZW1wX3NmJFNjb3JlKSkKICAgIGxhZ192YWwgPC0gYXMubnVtZXJpYyhsYWcubGlzdHcobHcsIHNjYWxlX3ZhbCwgemVyby5wb2xpY3kgPSBUUlVFKSkKICAgIHBfdmFscyA8LSBsb2NhbF9tWywgNV0KICAgIAogICAgIyBDbGFzc2lmeSB0aGUgY2x1c3RlcnMgKHVzaW5nIHAgPD0gMC4xIGZvciBzbWFsbCBOIHJvYnVzdG5lc3MpCiAgICB0ZW1wX3NmJExJU0FfQ2F0IDwtICJOb3QgU2lnbmlmaWNhbnQiCiAgICB0ZW1wX3NmJExJU0FfQ2F0W3NjYWxlX3ZhbCA+IDAgJiBsYWdfdmFsID4gMCAmIHBfdmFscyA8PSAwLjFdIDwtICJIaWdoLUhpZ2ggKEhvdHNwb3QpIgogICAgdGVtcF9zZiRMSVNBX0NhdFtzY2FsZV92YWwgPCAwICYgbGFnX3ZhbCA8IDAgJiBwX3ZhbHMgPD0gMC4xXSA8LSAiTG93LUxvdyAoQ29sZHNwb3QpIgogICAgdGVtcF9zZiRMSVNBX0NhdFtzY2FsZV92YWwgPCAwICYgbGFnX3ZhbCA+IDAgJiBwX3ZhbHMgPD0gMC4xXSA8LSAiTG93LUhpZ2ggKE91dGxpZXIpIgogICAgdGVtcF9zZiRMSVNBX0NhdFtzY2FsZV92YWwgPiAwICYgbGFnX3ZhbCA8IDAgJiBwX3ZhbHMgPD0gMC4xXSA8LSAiSGlnaC1Mb3cgKE91dGxpZXIpIgogICAgCiAgICAjIENvbGxlY3QgcmVzdWx0cwogICAgZmluYWxfbGlzYV9ncmlkIDwtIHJiaW5kKGZpbmFsX2xpc2FfZ3JpZCwgdGVtcF9zZikKICB9Cn0KCiMgNC4gVmlzdWFsaXphdGlvbgpnZ3Bsb3QoZGF0YSA9IGZpbmFsX2xpc2FfZ3JpZCkgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBMSVNBX0NhdCksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDAuMDUpICsKICBmYWNldF9ncmlkKFBpbGxhciB+IFllYXIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKAogICAgIkhpZ2gtSGlnaCAoSG90c3BvdCkiID0gIiNkNzMwMjciLCAjIFJlZAogICAgIkxvdy1Mb3cgKENvbGRzcG90KSIgID0gIiM0NTc1YjQiLCAjIEJsdWUKICAgICJMb3ctSGlnaCAoT3V0bGllcikiICA9ICIjNzRhZGQxIiwgIyBMaWdodCBCbHVlCiAgICAiSGlnaC1Mb3cgKE91dGxpZXIpIiAgPSAiI2ZkYWU2MSIsICMgT3JhbmdlCiAgICAiTm90IFNpZ25pZmljYW50IiAgICAgPSAiI2YwZjBmMCIgICMgR3JleQogICkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKAogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLAogICAgYXhpcy50aWNrcyA9IGVsZW1lbnRfYmxhbmsoKSwKICAgIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksCiAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEwKSwKICAgIHN0cmlwLnRleHQueSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiLCBzaXplID0gMTAsIGFuZ2xlID0gMCksCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwKICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gImJvbGQiKQogICkgKwogIGxhYnModGl0bGUgPSAiTElTQSBDbHVzdGVyIEV2b2x1dGlvbiBvZiBTcGVjaWZpYyBQaWxsYXJzICgyMDE4LTIwMjUpIiwKICAgICAgIHN1YnRpdGxlID0gIjR4OCBNYXRyaXggb2YgTG9jYWwgSW5kaWNhdG9ycyBvZiBTcGF0aWFsIEFzc29jaWF0aW9uIChMSVNBKSIsCiAgICAgICBmaWxsID0gIkxJU0EgQ2x1c3RlciBUeXBlIikKCiMgNS4gU2F2ZQpnZ3NhdmUoIk5leHVzX0xJU0FfTWF0cml4XzR4OC5wbmciLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSAxMiwgZHBpID0gMzAwKQpgYGAKCgoKYGBge3J9CiMgVHJhbnNpdGlvbiBWZWxvY2l0eSBMSVNBIENsdXN0ZXJzIG9mIFNwZWNpZmljIFBpbGxhcnNsaWJyYXJ5KHNmKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShzcGRlcCkKbGlicmFyeShicm9vbSkKCiMgMS4gQ2FsY3VsYXRlIHRoZSBPTFMgQmV0YXMgZm9yIEVBQ0ggUGlsbGFyIHNlcGFyYXRlbHkKcGlsbGFyX2JldGFzIDwtIGZvdXJfcGlsbGFyX2xvbmcgJT4lCm11dGF0ZShZZWFyID0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoWWVhcikpKSAlPiUKZ3JvdXBfYnkoRGlzdHJpY3QsIFBpbGxhcikgJT4lCmRvKHRpZHkobG0oU2NvcmUgfiBZZWFyLCBkYXRhID0gLikpKSAlPiUKZmlsdGVyKHRlcm0gPT0gIlllYXIiKSAlPiUKZHBseXI6OnNlbGVjdChEaXN0cmljdCwgUGlsbGFyLCBiZXRhID0gZXN0aW1hdGUpICU+JQptdXRhdGUoQ2xlYW5OYW1lID0gdG91cHBlcihzdHJfdHJpbShEaXN0cmljdCkpKSAlPiUKbXV0YXRlKENsZWFuTmFtZSA9IGNhc2Vfd2hlbigKQ2xlYW5OYW1lID09ICJHVVJHQU9OIiB+ICJHVVJVR1JBTSIsCkNsZWFuTmFtZSA9PSAiTUVXQVQiICAgfiAiTlVIIiwKQ2xlYW5OYW1lID09ICJDSEFSS0hJREFEUkkiIH4gIkNIQVJLSEkgREFEUkkiLApUUlVFIH4gQ2xlYW5OYW1lCikpCgojIDIuIEpPSU4gYW5kIFJ1biBNb3JhbidzIEkgTG9vcApwaWxsYXJzIDwtIHVuaXF1ZShwaWxsYXJfYmV0YXMkUGlsbGFyKQptb3Jhbl9zdW1tYXJ5IDwtIGRhdGEuZnJhbWUoKQpmb3IgKHAgaW4gcGlsbGFycykgewojIFN1YnNldCBmb3IgY3VycmVudCBwaWxsYXIgYW5kIGpvaW4gd2l0aCBtYXAKcF9kYXRhIDwtIHBpbGxhcl9iZXRhcyAlPiUgZmlsdGVyKFBpbGxhciA9PSBwKQpwX3NwYXRpYWwgPC0gaGFyeWFuYV9tYXAgJT4lIGlubmVyX2pvaW4ocF9kYXRhLCBieSA9ICJDbGVhbk5hbWUiKQojIFdlaWdodHMgTWF0cml4Cm5iIDwtIHBvbHkybmIocF9zcGF0aWFsLCBxdWVlbiA9IFRSVUUpCmx3IDwtIG5iMmxpc3R3KG5iLCBzdHlsZSA9ICJXIiwgemVyby5wb2xpY3kgPSBUUlVFKQojIEdsb2JhbCBNb3JhbidzIEkgKE1vbnRlIENhcmxvKQpzZXQuc2VlZCgxMjMpCm1jX3JlcyA8LSBtb3Jhbi5tYyhwX3NwYXRpYWwkYmV0YSwgbHcsIG5zaW0gPSA5OTksIHplcm8ucG9saWN5ID0gVFJVRSkKIyBTdG9yZSBSZXN1bHQKbW9yYW5fc3VtbWFyeSA8LSByYmluZChtb3Jhbl9zdW1tYXJ5LCBkYXRhLmZyYW1lKApQaWxsYXIgPSBwLApNb3Jhbl9JID0gbWNfcmVzJHN0YXRpc3RpYywKcF92YWx1ZSA9IG1jX3JlcyRwLnZhbHVlCikpCn0KcHJpbnQobW9yYW5fc3VtbWFyeSkKCiMgMy4gQ2xlYW51cCB0aGUgQmV0YSBEYXRhIChSZWdyZXNzaW9uIFJlc3VsdHMpCnBpbGxhcl9iZXRhc19jbGVhbiA8LSBwaWxsYXJfYmV0YXMgJT4lCm11dGF0ZShDbGVhbk5hbWUgPSBEaXN0cmljdCAlPiUKc3RyX3JlcGxhY2VfYWxsKCJcXHwiLCAiaSIpICU+JQpzdHJfdHJpbSgpICU+JQp0b3VwcGVyKCkpICU+JQptdXRhdGUoQ2xlYW5OYW1lID0gY2FzZV93aGVuKApDbGVhbk5hbWUgPT0gIkdVUkdBT04iIH4gIkdVUlVHUkFNIiwKQ2xlYW5OYW1lID09ICJNRVdBVCIgICB+ICJOVUgiLApDbGVhbk5hbWUgPT0gIkNIQVJLSElEQURSSSIgfiAiQ0hBUktISSBEQURSSSIsClRSVUUgfiBDbGVhbk5hbWUKKSkKCiMgNS4gSW5pdGlhbGl6ZSB0aGUgbG9vcCBmb3Igc3BhdGlhbCBhbmFseXNpcwpwaWxsYXJzX3RvX3Bsb3QgPC0gdW5pcXVlKHBpbGxhcl9iZXRhc19jbGVhbiRQaWxsYXIpCmxpc2Ffb3V0cHV0X2xpc3QgPC0gbGlzdCgpCmZvciAocCBpbiBwaWxsYXJzX3RvX3Bsb3QpIHsKIyBGaWx0ZXIgZm9yIHNwZWNpZmljIHBpbGxhciBhbmQgam9pbiB3aXRoIHRoZSBzcGF0aWFsIGhhcnlhbmFfbWFwCnBfZGF0YSA8LSBwaWxsYXJfYmV0YXNfY2xlYW4gJT4lIGZpbHRlcihQaWxsYXIgPT0gcCkKIyBFbnN1cmUgaGFyeWFuYV9tYXAgKHlvdXIgS01MKSBpcyBhdmFpbGFibGUgYW5kIGhhcyAnQ2xlYW5OYW1lJwpwX3NwYXRpYWwgPC0gaGFyeWFuYV9tYXAgJT4lCm11dGF0ZShDbGVhbk5hbWUgPSBOYW1lICU+JSBzdHJfcmVwbGFjZV9hbGwoIlxcfCIsICJpIikgJT4lIHN0cl90cmltKCkgJT4lIHRvdXBwZXIoKSkgJT4lCm11dGF0ZShDbGVhbk5hbWUgPSBjYXNlX3doZW4oCkNsZWFuTmFtZSA9PSAiR1VSR0FPTiIgfiAiR1VSVUdSQU0iLApDbGVhbk5hbWUgPT0gIk1FV0FUIiAgIH4gIk5VSCIsCkNsZWFuTmFtZSA9PSAiQ0hBUktJIERBRFJJIiB+ICJDSEFSS0hJIERBRFJJIiwKVFJVRSB+IENsZWFuTmFtZQopKSAlPiUKaW5uZXJfam9pbihwX2RhdGEsIGJ5ID0gIkNsZWFuTmFtZSIpCiMgQ2FsY3VsYXRlIE5laWdoYm9ycyBhbmQgV2VpZ2h0cwpuYiA8LSBwb2x5Mm5iKHBfc3BhdGlhbCwgcXVlZW4gPSBUUlVFKQpsdyA8LSBuYjJsaXN0dyhuYiwgc3R5bGUgPSAiVyIsIHplcm8ucG9saWN5ID0gVFJVRSkKIyBMb2NhbCBNb3JhbidzIEkgbWF0aApsb2NhbF9tIDwtIGxvY2FsbW9yYW4ocF9zcGF0aWFsJGJldGEsIGx3LCB6ZXJvLnBvbGljeSA9IFRSVUUpCiMgQ2VudGVyIHRoZSBkYXRhIGFyb3VuZCB0aGUgbWVhbgpkaWZmX2JldGEgPC0gcF9zcGF0aWFsJGJldGEgLSBtZWFuKHBfc3BhdGlhbCRiZXRhKQojIENhbGN1bGF0ZSB0aGUgc3BhdGlhbCBsYWcgKHdoYXQgdGhlIG5laWdoYm9ycyBhcmUgZG9pbmcpCmxhZ19iZXRhIDwtIGxhZy5saXN0dyhsdywgZGlmZl9iZXRhLCB6ZXJvLnBvbGljeSA9IFRSVUUpCiMgR2V0IHAtdmFsdWVzCnBfdmFscyA8LSBsb2NhbF9tWywgNV0KcF9zcGF0aWFsJExJU0FfQ2F0IDwtICJOb3QgU2lnbmlmaWNhbnQiCiMgcCA8PSAwLjEgZm9yIHNtYWxsIHNhbXBsZSByb2J1c3RuZXNzCnBfc3BhdGlhbCRMSVNBX0NhdFtkaWZmX2JldGEgPiAwICYgbGFnX2JldGEgPiAwICYgcF92YWxzIDw9IDAuMV0gPC0gIkhpZ2gtSGlnaCAoSG90c3BvdCkiCnBfc3BhdGlhbCRMSVNBX0NhdFtkaWZmX2JldGEgPCAwICYgbGFnX2JldGEgPCAwICYgcF92YWxzIDw9IDAuMV0gPC0gIkxvdy1Mb3cgKENvbGRzcG90KSIKcF9zcGF0aWFsJExJU0FfQ2F0W2RpZmZfYmV0YSA8IDAgJiBsYWdfYmV0YSA+IDAgJiBwX3ZhbHMgPD0gMC4xXSA8LSAiTG93LUhpZ2ggKE91dGxpZXIpIgpwX3NwYXRpYWwkTElTQV9DYXRbZGlmZl9iZXRhID4gMCAmIGxhZ19iZXRhIDwgMCAmIHBfdmFscyA8PSAwLjFdIDwtICJIaWdoLUxvdyAoT3V0bGllcikiCmxpc2Ffb3V0cHV0X2xpc3RbW3BdXSA8LSBwX3NwYXRpYWwKfQojIENvbWJpbmUgYWxsIHBpbGxhcnMgZm9yIHRoZSBmaW5hbCBwbG90CmFsbF9waWxsYXJzX2xpc2EgPC0gZG8uY2FsbChyYmluZCwgbGlzYV9vdXRwdXRfbGlzdCkKCiMgNi4gVmlzdWFsaXphdGlvbgpnZ3Bsb3QoZGF0YSA9IGFsbF9waWxsYXJzX2xpc2EpICsKZ2VvbV9zZihhZXMoZmlsbCA9IExJU0FfQ2F0KSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMC4yKSArCmZhY2V0X3dyYXAoflBpbGxhciwgbmNvbCA9IDIpICsKc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygKIkhpZ2gtSGlnaCAoSG90c3BvdCkiID0gIiNkNzMwMjciLCAjIFJlZAoiTG93LUxvdyAoQ29sZHNwb3QpIiAgPSAiIzQ1NzViNCIsICMgQmx1ZQoiTG93LUhpZ2ggKE91dGxpZXIpIiAgPSAiIzc0YWRkMSIsICMgTGlnaHQgQmx1ZQoiSGlnaC1Mb3cgKE91dGxpZXIpIiAgPSAiI2ZkYWU2MSIsICMgT3JhbmdlCiJOb3QgU2lnbmlmaWNhbnQiICAgICA9ICIjZjBmMGYwIiAgIyBHcmV5CiksIG5hbWUgPSAiTW9tZW50dW0gVHlwZSIpICsKdGhlbWVfbWluaW1hbCgpICsKdGhlbWUoCnN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoZmFjZSA9ICJib2xkIiwgc2l6ZSA9IDEyKSwKbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCmF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKQopICsKbGFicyh0aXRsZSA9ICJSZWdpb25hbCBNb21lbnR1bSBvZiB0aGUgQWdyb2Vjb2xvZ2ljYWwgVHJhbnNpdGlvbiIsCnN1YnRpdGxlID0gIkxvY2FsIE1vcmFuJ3MgSSBBbmFseXNpcyBvZiBQaWxsYXIgR3Jvd3RoIFJhdGVzICgyMDE4LTIwMjUpIikKCiMgNy4gU2F2ZQpnZ3NhdmUoIlRyYW5zaXRpb25fTW9tZW50dW1fTElTQV9GaW5hbC5wbmciLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSAxMCwgZHBpID0gMzAwKQpgYGAKCgpgYGB7cn0KIyBMaW5rIHRvIG90aGVyIEluZGljYXRvcnMKbGlicmFyeShyZWFkeGwpClZpZXcoU0RHKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3B1YnIpIAoKIyAxLiBQcmVwYXJlIGRhdGEgZm9yIHRoZSB5ZWFyIDIwMjQKbXlfY29tcF8yMDI0IDwtIGNvbXBvc2l0ZV9pbmRleF9zY29yZSAlPiUKZmlsdGVyKFllYXIgPT0gMjAyNCkgJT4lCnNlbGVjdChEaXN0cmljdCwgYENvbXBvc2l0ZSBJbmRleCBTY29yZWApCm15X3BpbGxhcnNfMjAyNCA8LSBmb3VyX3BpbGxhciAlPiUKZmlsdGVyKFllYXIgPT0gMjAyNCkgJT4lCnNlbGVjdChEaXN0cmljdCwgYFdhdGVyIFBpbGxhcmAsIGBFbmVyZ3kgUGlsbGFyYCwgYEZvb2QgUGlsbGFyYCwgYFNvY2lhbCBQaWxsYXJgKQoKIyAyLiBKb2luIHdpdGggdGhlIFNERyBkYXRhZnJhbWUKY29tcGFyaXNvbl9kZiA8LSBteV9jb21wXzIwMjQgJT4lCmxlZnRfam9pbihteV9waWxsYXJzXzIwMjQsIGJ5ID0gIkRpc3RyaWN0IikgJT4lCmxlZnRfam9pbihTREcsIGJ5ID0gIkRpc3RyaWN0IikKCiMgLS0tIFZJU1VBTCAxOiBDb21wb3NpdGUgQ29tcGFyaXNvbiAtLS0KcGxvdDEgPC0gZ2dzY2F0dGVyKGNvbXBhcmlzb25fZGYsIHggPSAiQ29tcG9zaXRlIEluZGV4IFNjb3JlIiwgeSA9ICJTREdfQ29tcG9zaXRlIiwKICAgICAgICAgIGFkZCA9ICJyZWcubGluZSIsIGNvbmYuaW50ID0gVFJVRSwKICAgICAgICAgIGNvci5jb2VmID0gVFJVRSwgY29yLm1ldGhvZCA9ICJzcGVhcm1hbiIsCiAgICAgICAgICB4bGFiID0gIlhYWFggQ29tcG9zaXRlIEluZGV4ICgyMDI0KSIsIHlsYWIgPSAiSGFyeWFuYSBTREcgQ29tcG9zaXRlIFNjb3JlICgyMDI0KSIsCiAgICAgICAgICB0aXRsZSA9ICJWYWxpZGF0aW9uOiBYWFhYIEluZGV4IHZzLiBPZmZpY2lhbCBTREcgSW5kZXgiLAogICAgICAgICAgbGFiZWwgPSAiRGlzdHJpY3QiLCByZXBlbCA9IFRSVUUsIGZvbnQubGFiZWwgPSBjKDgsICJwbGFpbiIpLAogICAgICAgICAgbmEucm0gPSBUUlVFKSArIAogIHRoZW1lX21pbmltYWwoKQoKIyAtLS0gVklTVUFMIDI6IFBpbGxhci1TcGVjaWZpYyBWYWxpZGF0aW9uIChGYWNldGVkKSAtLS0KcGxvdDIgPC0gZ2dwbG90KHBpbGxhcl9jb21wYXJpc29uLCBhZXMoeCA9IE15X1Njb3JlLCB5ID0gU0RHX1Njb3JlKSkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAic3RlZWxibHVlIiwgbmEucm0gPSBUUlVFKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAiZGFya3JlZCIsIGZpbGwgPSAibGlnaHRncmF5IiwgbmEucm0gPSBUUlVFKSArCiAgc3RhdF9jb3IobWV0aG9kID0gInNwZWFybWFuIiwgbGFiZWwueC5ucGMgPSAibGVmdCIsIGxhYmVsLnkubnBjID0gInRvcCIsIG5hLnJtID0gVFJVRSkgKyAKICBmYWNldF93cmFwKH5QaWxsYXIsIHNjYWxlcyA9ICJmcmVlIikgKwogIGxhYnModGl0bGUgPSAiUGlsbGFyLVNwZWNpZmljIFZhbGlkYXRpb24gYWdhaW5zdCBDb3JyZXNwb25kaW5nIFNER3MiLAogICAgICAgc3VidGl0bGUgPSAiU29jaWFsLVNERzEsIEZvb2QtU0RHMiwgV2F0ZXItU0RHNiwgRW5lcmd5LVNERzciLAogICAgICAgeCA9ICJYWFhYIFBpbGxhciBTY29yZXMiLCB5ID0gIk9mZmljaWFsIFNERyBTY29yZXMiKSArCiAgdGhlbWVfYncoKQoKIyBEaXNwbGF5IFZpc3VhbHMKcHJpbnQocGxvdDEpCnByaW50KHBsb3QyKQpgYGA=