Load data

data <- read_rds('../../temp/data_reg.rds')

Regression data prep

Sorting etc

# Just to be sure
data %<>%
  distinct(AID, year, .keep_all = TRUE) %>%
  relocate(AID, year, type, transition, transited_t, seniority) 

Lagged variables

# Decide what to lag
data %<>%
  arrange(AID, year) %>%
  group_by(AID) %>%
  mutate(
    across(c(concepts,
             DL,
             paper_n, 
             citation_n, 
             author_mean,
             oa_mean, 
             novelty_mean, 
             deg_cen, 
             deg_cen_comp, 
             novelty_fw, 
             citation_fw,
             aff_citation_fw,
             aff_novelty_fw
             ), ~ lag(.x, 1))
  ) %>%
  ungroup()
# Some last preprocessing
data %<>%
  filter(year >= 2000,
         year <= 2021) %>%
  mutate(co_author_industry = deg_cen_comp > 0) %>% #,year_min = ifelse(year_min < 2000, 2000, year_min))
    group_by(AID) %>%
  mutate(t = 1:n(),
         t_max = n()) %>%
  ungroup()
# Check missing data
data  %>% naniar::gg_miss_var()

# Replace again missing
data %<>%   
  group_by(AID) %>%
    arrange(AID, year) %>%
    fill(DL, concepts, 
         aff_id, aff_type, aff_novelty_fw, aff_citation_fw, 
         novelty_fw, citation_fw, paper_n, oa_mean, novelty_mean, deg_cen_comp, deg_cen, # IS not really correct, but can be done. Consider
         co_author_industry, citation_n, author_mean, # IS not really correct, but can be done. Consider
         .direction = "downup") %>%
  ungroup() 
# Replace NA. All others are by construction
data %<>%
  replace_na(list(DL = 0, concepts = 'unknown'))
data %>% count(concepts, sort = TRUE) %>% 
  mutate(rank_pct = percent_rank(n))

Survival analysis

data_surv <- data %>% 
  # Filter for last observation (=right cernsoring or transition)
  filter(is.na(transited_t) | transited_t <= 1) %>%
  group_by(AID) %>%
  slice_max(order_by = t, n= 1, with_ties = FALSE) %>%
  ungroup() %>%
  # Add some variables
  mutate(auth_star = citation_fw >= 0.9,
         aff_star = aff_citation_fw >= 0.9,
         )


# Previous filtering approach:
# filter(  (type == 'education' & year == year_max) | (type == 'switcher' & transition == 1)) %>%
data_surv %>% count(type)
# Surf object
surv_object <- Surv(time = data_surv$t, event = data_surv$transition)
table(surv_object)
surv_object
    1     2     3     4    4+     5    5+     6    6+     7    7+     8    8+     9    9+    10   10+    11   11+    12   12+    13   13+    14   14+    15 
    2    71    97   117 17504   110 13583   128 10859    95  8588    63  7404    51  6341    33  5430    19  5214    27  4649    16  4068    13  3409     3 
  15+    16   16+    17   17+    18   18+    19   19+    20   20+    21   21+   22+ 
 3012     7  2689     3  2276     8  1917     4  1739     5  1610     9  1547  2576 

Kaplan-Meier Method and Log Rank Test

fit_km0 <- survfit(surv_object ~ 1, 
                   data = data_surv)
fit_km1 <- survfit(surv_object ~ DL, 
                   data = data_surv)
fit_km2 <- survfit(surv_object ~ auth_star, 
                   data = data_surv)
fit_km3 <- survfit(surv_object ~ aff_star,
                   data = data_surv)
p1 <- fit_km0 %>% autoplot() + labs(title= 'KM: baseline')
p2 <- fit_km1 %>% autoplot() + labs(title= 'KM: DL researcher')
p3 <- fit_km2 %>% autoplot() + labs(title= 'KM: Star researcher')
p4 <- fit_km3 %>% autoplot() + labs(title= 'KM: Star institution')

(p1 + p2) / (p3 + p4) +  plot_layout(guides = "collect") & theme(legend.position = 'bottom') & labs(x = 'Time', y = 'Survival Probability')

rm(fit_km0, fit_km1, fit_km2, fit_km3,
   p1, p2, p3, p4)

Cox Proportional Hazard Model

### Fit Cox proportional hazard model
set.seed(1337)

#Baseline
fit_cox0 <- coxph(surv_object ~ seniority + concepts + year,
                  data = data_surv)
Warning: Loglik converged before variable  13,31,38,40,43,48,51,53,54,56,58,60,61,62,64,67,70,72,76,78,79,85,87,89,90,94,95,96,98,99,101 ; coefficient may be infinite. 
fit_cox1 <- coxph(surv_object ~ seniority + concepts + year 
                  + DL,
                  data = data_surv)
Warning: Loglik converged before variable  13,31,38,40,43,48,51,53,54,56,58,60,61,62,64,67,70,72,76,78,79,85,87,89,90,94,95,96,98,99,101 ; coefficient may be infinite. 
fit_cox2 <- coxph(surv_object ~ seniority + concepts + year 
                  + deg_cen + deg_cen_comp,
                  data = data_surv)
Warning: Loglik converged before variable  55 ; coefficient may be infinite. 
fit_cox3 <- coxph(surv_object ~ seniority + concepts + year 
                  + citation_fw + novelty_fw,
                  data = data_surv)
Warning: Loglik converged before variable  13,31,38,40,48,51,53,54,56,58,60,61,62,67,70,72,76,78,79,85,89,90,94,95,96,98,99,101 ; coefficient may be infinite. 
fit_cox4 <- coxph(surv_object ~ seniority + concepts + year 
                  + aff_citation_fw,
                  data = data_surv)
Warning: Loglik converged before variable  13,31,38,40,43,48,51,53,54,56,58,60,61,62,64,67,70,72,76,78,79,85,87,89,90,94,95,96,98,99,101 ; coefficient may be infinite. 
fit_cox5 <- coxph(surv_object ~ seniority + concepts + year 
                  + DL + deg_cen + deg_cen_comp + citation_fw + novelty_fw + aff_citation_fw,
                  data = data_surv)
#stargazer(fit_cox0, fit_cox1, fit_cox2, fit_cox3, fit_cox4, fit_cox5, type = 'latex', 
# omit = c( 'concepts', 'year', 'Constant'), out ='../../output/surv_res1.tex')
#stargazer(fit_cox0, fit_cox1, fit_cox2, fit_cox3, fit_cox4, fit_cox5, type = 'text',  omit = c( 'concepts', 'year', 'Constant'))
stargazer(fit_cox0, fit_cox1, fit_cox2, fit_cox3, fit_cox4, fit_cox5, type = 'html', omit = c( 'concepts', 'year', 'Constant'))
Warning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: number of rows of result is not a multiple of vector length (arg 2)Warning: number of rows of result is not a multiple of vector length (arg 2)Warning: number of rows of result is not a multiple of vector length (arg 2)Warning: number of rows of result is not a multiple of vector length (arg 2)Warning: number of rows of result is not a multiple of vector length (arg 2)
Dependent variable:
surv_object
(1) (2) (3) (4) (5) (6)
seniority -0.232*** -0.226*** -0.239*** -0.213*** -0.220*** -0.209***
(0.011) (0.011) (0.011) (0.011) (0.011) (0.011)
DL 1.349*** 0.692***
(0.076) (0.081)
deg_cen 0.190*** -0.308***
(0.028) (0.047)
deg_cen_comp 0.129*** 0.127***
(0.007) (0.007)
citation_fw 4.261*** 4.181***
(0.130) (0.156)
novelty_fw -0.876*** -0.880***
(0.157) (0.159)
aff_citation_fw 5.379*** 0.292
(0.275) (0.326)
Observations 105,296 105,296 105,296 105,296 105,296 105,296
R2 0.017 0.020 0.020 0.030 0.020 0.033
Max. Possible R2 0.169 0.169 0.169 0.169 0.169 0.169
Log Likelihood -8,867.794 -8,709.206 -8,684.612 -8,173.723 -8,697.137 -8,017.109
Wald Test 262.910*** (df = 99) 597.870*** (df = 100) 2,188.910*** (df = 70) 1,383.660*** (df = 98) 642.810*** (df = 100) 3,284.940*** (df = 74)
LR Test 1,781.754*** (df = 99) 2,098.929*** (df = 100) 2,148.117*** (df = 70) 3,169.896*** (df = 98) 2,123.067*** (df = 100) 3,483.124*** (df = 74)
Score (Logrank) Test 1,560.421*** (df = 99) 1,926.216*** (df = 100) 7,626.015*** (df = 70) 3,211.857*** (df = 98) 1,954.019*** (df = 100) 8,859.206*** (df = 74)
Note: p<0.1; p<0.05; p<0.01
#fit_cox5 %>% ggforest(data = data_surv)
#save models
list(fit_cox0, fit_cox1, fit_cox2, fit_cox3, fit_cox4, fit_cox5) %>% write_rds('../../temp/reg_surv1.rds')
#rm(fit_cox0, fit_cox1, fit_cox2, fit_cox3, fit_cox4, fit_cox5)

Propensity Score matching

library(MatchIt)
data_match <- data %>%
  filter(type == 'education' | type == 'switcher' & transition == 1) %>%
  left_join(read_rds('../../temp/author_concepts_main.rds') %>% select(AID, concepts) %>% rename(concept_main = concepts), by = 'AID') %>%
  select(-transition, -transited_t, -year_transit) %>%
  mutate(type = (type %>% factor() %>% as.numeric()) -1,
         aff_id = aff_id %>% factor(),
         concepts = concepts %>% factor(),
         concept_main = concept_main %>% factor()) %>%
  drop_na()
# Do the PSM
set.seed(1337)
match_out <-  data_match %>% 
  # Matching
  matchit(type ~ paper_n + author_mean + oa_mean + DL + t + t_max + co_author_industry + aff_citation_fw + aff_citation_fw, exact = c('year', 'seniority', 'concept_main'),
          data = ., verbose = FALSE, method = "nearest", ratio = 1) # OR method  "genetic" ... takes forever.....
# GEt the matched pairs
matched_pairs  <- bind_cols(data_match[row.names(match_out$match.matrix),"AID"] , data_match[match_out$match.matrix,"AID"] ) %>%
  rename(orig_AID = `AID...1`,
         match_AID = `AID...2`) 
New names:
# construct the matched dataset
data_did <- matched_pairs %>% 
  mutate(pair_id = 1:n())

data_did <- data_did %>%
  select(orig_AID, pair_id) %>%
  rename(AID = orig_AID) %>%
  bind_rows(data_did %>%
  select(match_AID, pair_id) %>%
  rename(AID = match_AID) ) %>%
  arrange(pair_id) %>%
  left_join(data, by = 'AID')
# compute transition point for matched partner
data_did %<>%
  group_by(pair_id) %>%
  mutate(switcher = type == 'switcher',
         year_transit = max(year_transit, na.rm = TRUE),
         transition = year == year_transit,
         transited = year >= year_transit,
         transited_t = year - year_transit + 1) %>%
  mutate(across(c(year, concepts, transited), ~ factor(.x))) %>%
  mutate(transited_t = ifelse(transited_t > 0, transited_t, 0)) %>%
  drop_na()
data_did %>% saveRDS('../temp_reg/reg_data_did.rds')

Diff-in-Diff

# Delete all objects
rm(list = ls(all.names = TRUE)) #will clear all objects includes hidden objects.
gc() #free up memrory and report the memory usage.
           used  (Mb) gc trigger    (Mb) limit (Mb)   max used    (Mb)
Ncells  3874576 207.0   12010248   641.5         NA   12010248   641.5
Vcells 23545267 179.7 5445164727 41543.4      65536 8507759093 64909.1
data_did <- read_rds('../temp_reg/reg_data_did.rds')
# For the interaction plot code logical to numeric
# data_did %<>%  mutate(switcher = switcher %>% as.numeric(), transited = transited %>% as.numeric())
data_did %>% 
  count(concepts, sort = TRUE) %>% 
  mutate(rank_pct = percent_rank(n))

Models

# fit_did_0 <- lm(citation_rank ~ switcher + field_of_study_name, data = data_did)

fit_did_1 <- lm(citation_fw ~ (type + transited)^2 + year + seniority + year, # + concepts, 
                data = data_did)

fit_did_2 <- lm(citation_fw ~ (type + transited)^2 + (type + transited_t)^2 + year  + seniority, # + concepts, 
                data = data_did)

fit_did_3 <- lm(novelty_fw ~ (type + transited)^2 + year + seniority + year, # + concepts, 
                data = data_did)

fit_did_4 <- lm(novelty_fw ~ (type + transited)^2 + (type + transited_t)^2 + year + seniority, # + concepts , 
                data = data_did)

# + paper_n ?
#stargazer(fit_did_1, fit_did_2, fit_did_3, fit_did_4, type = 'latex', omit = c( 'concepts', 'year', 'Constant'), out ='../../output/did_res1.tex')
stargazer(fit_did_1, fit_did_2, fit_did_3, fit_did_4, type = 'text', omit = c('year', 'Constant'))
Warning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: number of rows of result is not a multiple of vector length (arg 2)Warning: number of rows of result is not a multiple of vector length (arg 2)

========================================================================================================================================
                                                                       Dependent variable:                                              
                         ---------------------------------------------------------------------------------------------------------------
                                               citation_fw                                             novelty_fw                       
                                     (1)                         (2)                         (3)                         (4)            
----------------------------------------------------------------------------------------------------------------------------------------
typeswitcher                      0.050***                    0.051***                      0.007                       0.007           
                                   (0.007)                     (0.007)                     (0.005)                     (0.005)          
                                                                                                                                        
transited                         0.123***                    0.203***                    0.101***                    0.112***          
                                   (0.009)                     (0.011)                     (0.005)                     (0.007)          
                                                                                                                                        
transited_t                                                   -0.021***                                               -0.003***         
                                                               (0.002)                                                 (0.001)          
                                                                                                                                        
seniority                         0.004***                    0.007***                    0.006***                    0.006***          
                                  (0.0004)                    (0.0004)                    (0.0002)                    (0.0002)          
                                                                                                                                        
typeswitcher:transited            0.114***                    0.172***                    -0.020***                    -0.010           
                                   (0.011)                     (0.014)                     (0.007)                     (0.009)          
                                                                                                                                        
typeswitcher:transited_t                                      -0.015***                                                -0.003*          
                                                               (0.002)                                                 (0.001)          
                                                                                                                                        
----------------------------------------------------------------------------------------------------------------------------------------
Observations                       17,151                      17,151                      17,151                      17,151           
R2                                  0.165                       0.195                       0.142                       0.143           
Adjusted R2                         0.164                       0.194                       0.140                       0.142           
Residual Std. Error          0.349 (df = 17125)          0.343 (df = 17123)          0.222 (df = 17125)          0.222 (df = 17123)     
F Statistic              135.153*** (df = 25; 17125) 153.683*** (df = 27; 17123) 113.069*** (df = 25; 17125) 106.066*** (df = 27; 17123)
========================================================================================================================================
Note:                                                                                                        *p<0.1; **p<0.05; ***p<0.01
stargazer(fit_did_1, fit_did_2, fit_did_3, fit_did_4, type = 'html', omit = c('year', 'Constant'))
Warning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: length of NULL cannot be changedWarning: number of rows of result is not a multiple of vector length (arg 2)Warning: number of rows of result is not a multiple of vector length (arg 2)
Dependent variable:
citation_fw novelty_fw
(1) (2) (3) (4)
typeswitcher 0.050*** 0.051*** 0.007 0.007
(0.007) (0.007) (0.005) (0.005)
transited 0.123*** 0.203*** 0.101*** 0.112***
(0.009) (0.011) (0.005) (0.007)
transited_t -0.021*** -0.003***
(0.002) (0.001)
seniority 0.004*** 0.007*** 0.006*** 0.006***
(0.0004) (0.0004) (0.0002) (0.0002)
typeswitcher:transited 0.114*** 0.172*** -0.020*** -0.010
(0.011) (0.014) (0.007) (0.009)
typeswitcher:transited_t -0.015*** -0.003*
(0.002) (0.001)
Observations 17,151 17,151 17,151 17,151
R2 0.165 0.195 0.142 0.143
Adjusted R2 0.164 0.194 0.140 0.142
Residual Std. Error 0.349 (df = 17125) 0.343 (df = 17123) 0.222 (df = 17125) 0.222 (df = 17123)
F Statistic 135.153*** (df = 25; 17125) 153.683*** (df = 27; 17123) 113.069*** (df = 25; 17125) 106.066*** (df = 27; 17123)
Note: p<0.1; p<0.05; p<0.01
#library(interplot)
#fit_did_2 %>% interplot(var1 ="switcher", var2 = "transited_t", hist = TRUE) 
library(interactions)
fit_did_2 %>% interact_plot(pred = transited_t, modx = switcher,
                            interval = TRUE) +
  theme(legend.position = 'bottom')
ggsave('../../output/fig_interaction_1.png', width = 10, height = 7.5, units = 'cm')
library(interactions)
fit_did_2 %>% interact_plot(pred = transited_t, modx = switcher,
                            interval = TRUE, linearity.check = TRUE)

—>

Descriptives

data %>% select(seniority, deg_cen, deg_cen_comp, co_author_industry, DL, paper_n, author_mean, citation_fw, novelty_fw, aff_citation_fw, aff_novelty_fw) %>% as.data.frame() %>%
  stargazer(summary = TRUE, type = 'html')

By university vs. switcher career

data %>% 
  select(type, seniority, deg_cen, deg_cen_comp, co_author_industry, DL, paper_n, author_mean, citation_fw, novelty_fw, aff_citation_fw, aff_novelty_fw) %>%
  as.data.frame() %>%
  split(.$type) %>% 
  walk(~ stargazer(., summary = TRUE, type = 'html'))
data %>% 
  filter(transited_t <= 0) %>%
  mutate(auth_star = citation_fw >= 0.9,
         aff_star = aff_citation_fw >= 0.9)

–>

LS0tCnRpdGxlOiAnUHJpdmF0aXphdGlvbiBvZiBBSSByZXNlYXJjaDogRXhlY3V0aW5nIHJlZ3Jlc3Npb25zJwphdXRob3I6ICJEYW5pZWwgUy4gSGFpbiAoZHNoQGJ1c2luZXNzLmFhdS5kaykiCmRhdGU6ICJVcGRhdGVkIGByIGZvcm1hdChTeXMudGltZSgpLCAnJUIgJWQsICVZJylgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICB0b2M6IGZhbHNlCiAgICB0b2NfZGVwdGg6IDIKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgdGhlbWU6IGZsYXRseQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQojIEtuaXRyIG9wdGlvbnMKIyMjIEdlbmVyaWMgcHJlYW1ibGUKcm0obGlzdCA9IGxzKGFsbC5uYW1lcyA9IFRSVUUpKSAjd2lsbCBjbGVhciBhbGwgb2JqZWN0cyBpbmNsdWRlcyBoaWRkZW4gb2JqZWN0cy4KZ2MoKSAjZnJlZSB1cCBtZW1yb3J5IGFuZCByZXBvcnQgdGhlIG1lbW9yeSB1c2FnZS4KZ3JhcGhpY3Mub2ZmKCkKClN5cy5zZXRlbnYoTEFORyA9ICJlbiIpICMgRm9yIGVuZ2xpc2ggbGFuZ3VhZ2UKb3B0aW9ucyhzY2lwZW4gPSA1KSAjIFRvIGRlYWN0aXZhdGUgYW5ub3lpbmcgc2NpZW50aWZpYyBudW1iZXIgbm90YXRpb24KCiMjIyBMb2FkIHBhY2thZ2VzCmxpYnJhcnkodGlkeXZlcnNlKSAjIENvbGxlY3Rpb24gb2YgYWxsIHRoZSBnb29kIHN0dWZmIGxpa2UgZHBseXIsIGdncGxvdDIgZWN0LgpsaWJyYXJ5KG1hZ3JpdHRyKSAjIEZvciBleHRyYS1waXBpbmcgb3BlcmF0b3JzIChlZy4gJTw+JSkKCiMgRGVzY3JpcHRpdmVzCiNsaWJyYXJ5KHNraW1yKQpsaWJyYXJ5KHN0YXJnYXplcikKCiMgVml6CmxpYnJhcnkocGF0Y2h3b3JrKQoKIyBTdXJ2aXZhbCBhbmFseXNpcwpsaWJyYXJ5KHN1cnZpdmFsKQpsaWJyYXJ5KHN1cnZtaW5lcikKbGlicmFyeShnZ2ZvcnRpZnkpCmBgYAoKIyBMb2FkIGRhdGEKCmBgYHtyfQpkYXRhIDwtIHJlYWRfcmRzKCcuLi8uLi90ZW1wL2RhdGFfcmVnLnJkcycpCmBgYAoKCiMgUmVncmVzc2lvbiBkYXRhIHByZXAKCiMjIFNvcnRpbmcgZXRjCgpgYGB7cn0KIyBKdXN0IHRvIGJlIHN1cmUKZGF0YSAlPD4lCiAgZGlzdGluY3QoQUlELCB5ZWFyLCAua2VlcF9hbGwgPSBUUlVFKSAlPiUKICByZWxvY2F0ZShBSUQsIHllYXIsIHR5cGUsIHRyYW5zaXRpb24sIHRyYW5zaXRlZF90LCBzZW5pb3JpdHkpIApgYGAKCiMjIExhZ2dlZCB2YXJpYWJsZXMKCmBgYHtyfQojIERlY2lkZSB3aGF0IHRvIGxhZwpkYXRhICU8PiUKICBhcnJhbmdlKEFJRCwgeWVhcikgJT4lCiAgZ3JvdXBfYnkoQUlEKSAlPiUKICBtdXRhdGUoCiAgICBhY3Jvc3MoYyhjb25jZXB0cywKICAgICAgICAgICAgIERMLAogICAgICAgICAgICAgcGFwZXJfbiwgCiAgICAgICAgICAgICBjaXRhdGlvbl9uLCAKICAgICAgICAgICAgIGF1dGhvcl9tZWFuLAogICAgICAgICAgICAgb2FfbWVhbiwgCiAgICAgICAgICAgICBub3ZlbHR5X21lYW4sIAogICAgICAgICAgICAgZGVnX2NlbiwgCiAgICAgICAgICAgICBkZWdfY2VuX2NvbXAsIAogICAgICAgICAgICAgbm92ZWx0eV9mdywgCiAgICAgICAgICAgICBjaXRhdGlvbl9mdywKICAgICAgICAgICAgIGFmZl9jaXRhdGlvbl9mdywKICAgICAgICAgICAgIGFmZl9ub3ZlbHR5X2Z3CiAgICAgICAgICAgICApLCB+IGxhZygueCwgMSkpCiAgKSAlPiUKICB1bmdyb3VwKCkKYGBgCgpgYGB7cn0KIyBTb21lIGxhc3QgcHJlcHJvY2Vzc2luZwpkYXRhICU8PiUKICBmaWx0ZXIoeWVhciA+PSAyMDAwLAogICAgICAgICB5ZWFyIDw9IDIwMjEpICU+JQogIG11dGF0ZShjb19hdXRob3JfaW5kdXN0cnkgPSBkZWdfY2VuX2NvbXAgPiAwKSAlPiUgIyx5ZWFyX21pbiA9IGlmZWxzZSh5ZWFyX21pbiA8IDIwMDAsIDIwMDAsIHllYXJfbWluKSkKICAgIGdyb3VwX2J5KEFJRCkgJT4lCiAgbXV0YXRlKHQgPSAxOm4oKSwKICAgICAgICAgdF9tYXggPSBuKCkpICU+JQogIHVuZ3JvdXAoKQpgYGAKCmBgYHtyfQojIENoZWNrIG1pc3NpbmcgZGF0YQpkYXRhICAlPiUgbmFuaWFyOjpnZ19taXNzX3ZhcigpCmBgYAoKYGBge3J9CiMgUmVwbGFjZSBhZ2FpbiBtaXNzaW5nCmRhdGEgJTw+JSAgIAogIGdyb3VwX2J5KEFJRCkgJT4lCiAgICBhcnJhbmdlKEFJRCwgeWVhcikgJT4lCiAgICBmaWxsKERMLCBjb25jZXB0cywgCiAgICAgICAgIGFmZl9pZCwgYWZmX3R5cGUsIGFmZl9ub3ZlbHR5X2Z3LCBhZmZfY2l0YXRpb25fZncsIAogICAgICAgICBub3ZlbHR5X2Z3LCBjaXRhdGlvbl9mdywgcGFwZXJfbiwgb2FfbWVhbiwgbm92ZWx0eV9tZWFuLCBkZWdfY2VuX2NvbXAsIGRlZ19jZW4sICMgSVMgbm90IHJlYWxseSBjb3JyZWN0LCBidXQgY2FuIGJlIGRvbmUuIENvbnNpZGVyCiAgICAgICAgIGNvX2F1dGhvcl9pbmR1c3RyeSwgY2l0YXRpb25fbiwgYXV0aG9yX21lYW4sICMgSVMgbm90IHJlYWxseSBjb3JyZWN0LCBidXQgY2FuIGJlIGRvbmUuIENvbnNpZGVyCiAgICAgICAgIC5kaXJlY3Rpb24gPSAiZG93bnVwIikgJT4lCiAgdW5ncm91cCgpIApgYGAKCmBgYHtyfQojIFJlcGxhY2UgTkEuIEFsbCBvdGhlcnMgYXJlIGJ5IGNvbnN0cnVjdGlvbgpkYXRhICU8PiUKICByZXBsYWNlX25hKGxpc3QoREwgPSAwLCBjb25jZXB0cyA9ICd1bmtub3duJykpCmBgYAoKYGBge3J9CmRhdGEgJT4lIGNvdW50KGNvbmNlcHRzLCBzb3J0ID0gVFJVRSkgJT4lIAogIG11dGF0ZShyYW5rX3BjdCA9IHBlcmNlbnRfcmFuayhuKSkKYGBgCgojIFN1cnZpdmFsIGFuYWx5c2lzCgpgYGB7cn0KZGF0YV9zdXJ2IDwtIGRhdGEgJT4lIAogICMgRmlsdGVyIGZvciBsYXN0IG9ic2VydmF0aW9uICg9cmlnaHQgY2VybnNvcmluZyBvciB0cmFuc2l0aW9uKQogIGZpbHRlcihpcy5uYSh0cmFuc2l0ZWRfdCkgfCB0cmFuc2l0ZWRfdCA8PSAxKSAlPiUKICBncm91cF9ieShBSUQpICU+JQogIHNsaWNlX21heChvcmRlcl9ieSA9IHQsIG49IDEsIHdpdGhfdGllcyA9IEZBTFNFKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgIyBBZGQgc29tZSB2YXJpYWJsZXMKICBtdXRhdGUoYXV0aF9zdGFyID0gY2l0YXRpb25fZncgPj0gMC45LAogICAgICAgICBhZmZfc3RhciA9IGFmZl9jaXRhdGlvbl9mdyA+PSAwLjksCiAgICAgICAgICkKCgojIFByZXZpb3VzIGZpbHRlcmluZyBhcHByb2FjaDoKIyBmaWx0ZXIoICAodHlwZSA9PSAnZWR1Y2F0aW9uJyAmIHllYXIgPT0geWVhcl9tYXgpIHwgKHR5cGUgPT0gJ3N3aXRjaGVyJyAmIHRyYW5zaXRpb24gPT0gMSkpICU+JQpgYGAKCmBgYHtyfQpkYXRhX3N1cnYgJT4lIGNvdW50KHR5cGUpCmBgYAoKYGBge3J9CiMgU3VyZiBvYmplY3QKc3Vydl9vYmplY3QgPC0gU3Vydih0aW1lID0gZGF0YV9zdXJ2JHQsIGV2ZW50ID0gZGF0YV9zdXJ2JHRyYW5zaXRpb24pCmBgYAoKYGBge3J9CnRhYmxlKHN1cnZfb2JqZWN0KQpgYGAKCiMjIEthcGxhbi1NZWllciBNZXRob2QgYW5kIExvZyBSYW5rIFRlc3QKCmBgYHtyfQpmaXRfa20wIDwtIHN1cnZmaXQoc3Vydl9vYmplY3QgfiAxLCAKICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3N1cnYpCmZpdF9rbTEgPC0gc3VydmZpdChzdXJ2X29iamVjdCB+IERMLCAKICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3N1cnYpCmZpdF9rbTIgPC0gc3VydmZpdChzdXJ2X29iamVjdCB+IGF1dGhfc3RhciwgCiAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YV9zdXJ2KQpmaXRfa20zIDwtIHN1cnZmaXQoc3Vydl9vYmplY3QgfiBhZmZfc3RhciwKICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3N1cnYpCmBgYAoKYGBge3J9CnAxIDwtIGZpdF9rbTAgJT4lIGF1dG9wbG90KCkgKyBsYWJzKHRpdGxlPSAnS006IGJhc2VsaW5lJykKcDIgPC0gZml0X2ttMSAlPiUgYXV0b3Bsb3QoKSArIGxhYnModGl0bGU9ICdLTTogREwgcmVzZWFyY2hlcicpCnAzIDwtIGZpdF9rbTIgJT4lIGF1dG9wbG90KCkgKyBsYWJzKHRpdGxlPSAnS006IFN0YXIgcmVzZWFyY2hlcicpCnA0IDwtIGZpdF9rbTMgJT4lIGF1dG9wbG90KCkgKyBsYWJzKHRpdGxlPSAnS006IFN0YXIgaW5zdGl0dXRpb24nKQoKKHAxICsgcDIpIC8gKHAzICsgcDQpICsgIHBsb3RfbGF5b3V0KGd1aWRlcyA9ICJjb2xsZWN0IikgJiB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAnYm90dG9tJykgJiBsYWJzKHggPSAnVGltZScsIHkgPSAnU3Vydml2YWwgUHJvYmFiaWxpdHknKQpgYGAKCmBgYHtyfQpybShmaXRfa20wLCBmaXRfa20xLCBmaXRfa20yLCBmaXRfa20zLAogICBwMSwgcDIsIHAzLCBwNCkKYGBgCgoKIyMgQ294IFByb3BvcnRpb25hbCBIYXphcmQgTW9kZWwKCmBgYHtyfQojIyMgRml0IENveCBwcm9wb3J0aW9uYWwgaGF6YXJkIG1vZGVsCnNldC5zZWVkKDEzMzcpCgojQmFzZWxpbmUKZml0X2NveDAgPC0gY294cGgoc3Vydl9vYmplY3QgfiBzZW5pb3JpdHkgKyBjb25jZXB0cyArIHllYXIsCiAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3N1cnYpCgpmaXRfY294MSA8LSBjb3hwaChzdXJ2X29iamVjdCB+IHNlbmlvcml0eSArIGNvbmNlcHRzICsgeWVhciAKICAgICAgICAgICAgICAgICAgKyBETCwKICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGFfc3VydikKCmZpdF9jb3gyIDwtIGNveHBoKHN1cnZfb2JqZWN0IH4gc2VuaW9yaXR5ICsgY29uY2VwdHMgKyB5ZWFyIAogICAgICAgICAgICAgICAgICArIGRlZ19jZW4gKyBkZWdfY2VuX2NvbXAsCiAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3N1cnYpCgpmaXRfY294MyA8LSBjb3hwaChzdXJ2X29iamVjdCB+IHNlbmlvcml0eSArIGNvbmNlcHRzICsgeWVhciAKICAgICAgICAgICAgICAgICAgKyBjaXRhdGlvbl9mdyArIG5vdmVsdHlfZncsCiAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3N1cnYpCgpmaXRfY294NCA8LSBjb3hwaChzdXJ2X29iamVjdCB+IHNlbmlvcml0eSArIGNvbmNlcHRzICsgeWVhciAKICAgICAgICAgICAgICAgICAgKyBhZmZfY2l0YXRpb25fZncsCiAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3N1cnYpCgpmaXRfY294NSA8LSBjb3hwaChzdXJ2X29iamVjdCB+IHNlbmlvcml0eSArIGNvbmNlcHRzICsgeWVhciAKICAgICAgICAgICAgICAgICAgKyBETCArIGRlZ19jZW4gKyBkZWdfY2VuX2NvbXAgKyBjaXRhdGlvbl9mdyArIG5vdmVsdHlfZncgKyBhZmZfY2l0YXRpb25fZncsCiAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhX3N1cnYpCmBgYAoKCmBgYHtyfQojc3RhcmdhemVyKGZpdF9jb3gwLCBmaXRfY294MSwgZml0X2NveDIsIGZpdF9jb3gzLCBmaXRfY294NCwgZml0X2NveDUsIHR5cGUgPSAnbGF0ZXgnLCAKIyBvbWl0ID0gYyggJ2NvbmNlcHRzJywgJ3llYXInLCAnQ29uc3RhbnQnKSwgb3V0ID0nLi4vLi4vb3V0cHV0L3N1cnZfcmVzMS50ZXgnKQpgYGAKCmBgYHtyfQojc3RhcmdhemVyKGZpdF9jb3gwLCBmaXRfY294MSwgZml0X2NveDIsIGZpdF9jb3gzLCBmaXRfY294NCwgZml0X2NveDUsIHR5cGUgPSAndGV4dCcsICBvbWl0ID0gYyggJ2NvbmNlcHRzJywgJ3llYXInLCAnQ29uc3RhbnQnKSkKYGBgCgpgYGB7ciwgcmVzdWx0cz0nYXNpcyd9CnN0YXJnYXplcihmaXRfY294MCwgZml0X2NveDEsIGZpdF9jb3gyLCBmaXRfY294MywgZml0X2NveDQsIGZpdF9jb3g1LCB0eXBlID0gJ2h0bWwnLCBvbWl0ID0gYyggJ2NvbmNlcHRzJywgJ3llYXInLCAnQ29uc3RhbnQnKSkKYGBgCgpgYGB7cn0KI2ZpdF9jb3g1ICU+JSBnZ2ZvcmVzdChkYXRhID0gZGF0YV9zdXJ2KQpgYGAKCmBgYHtyfQojc2F2ZSBtb2RlbHMKbGlzdChmaXRfY294MCwgZml0X2NveDEsIGZpdF9jb3gyLCBmaXRfY294MywgZml0X2NveDQsIGZpdF9jb3g1KSAlPiUgd3JpdGVfcmRzKCcuLi8uLi90ZW1wL3JlZ19zdXJ2MS5yZHMnKQpgYGAKCmBgYHtyfQojcm0oZml0X2NveDAsIGZpdF9jb3gxLCBmaXRfY294MiwgZml0X2NveDMsIGZpdF9jb3g0LCBmaXRfY294NSkKYGBgCgojIFByb3BlbnNpdHkgU2NvcmUgbWF0Y2hpbmcgCgpgYGB7cn0KbGlicmFyeShNYXRjaEl0KQpgYGAKCmBgYHtyfQpkYXRhX21hdGNoIDwtIGRhdGEgJT4lCiAgZmlsdGVyKHR5cGUgPT0gJ2VkdWNhdGlvbicgfCB0eXBlID09ICdzd2l0Y2hlcicgJiB0cmFuc2l0aW9uID09IDEpICU+JQogIGxlZnRfam9pbihyZWFkX3JkcygnLi4vLi4vdGVtcC9hdXRob3JfY29uY2VwdHNfbWFpbi5yZHMnKSAlPiUgc2VsZWN0KEFJRCwgY29uY2VwdHMpICU+JSByZW5hbWUoY29uY2VwdF9tYWluID0gY29uY2VwdHMpLCBieSA9ICdBSUQnKSAlPiUKICBzZWxlY3QoLXRyYW5zaXRpb24sIC10cmFuc2l0ZWRfdCwgLXllYXJfdHJhbnNpdCkgJT4lCiAgbXV0YXRlKHR5cGUgPSAodHlwZSAlPiUgZmFjdG9yKCkgJT4lIGFzLm51bWVyaWMoKSkgLTEsCiAgICAgICAgIGFmZl9pZCA9IGFmZl9pZCAlPiUgZmFjdG9yKCksCiAgICAgICAgIGNvbmNlcHRzID0gY29uY2VwdHMgJT4lIGZhY3RvcigpLAogICAgICAgICBjb25jZXB0X21haW4gPSBjb25jZXB0X21haW4gJT4lIGZhY3RvcigpKSAlPiUKICBkcm9wX25hKCkKYGBgCgpgYGB7cn0KIyBEbyB0aGUgUFNNCnNldC5zZWVkKDEzMzcpCm1hdGNoX291dCA8LSAgZGF0YV9tYXRjaCAlPiUgCiAgIyBNYXRjaGluZwogIG1hdGNoaXQodHlwZSB+IHBhcGVyX24gKyBhdXRob3JfbWVhbiArIG9hX21lYW4gKyBETCArIHQgKyB0X21heCArIGNvX2F1dGhvcl9pbmR1c3RyeSArIGFmZl9jaXRhdGlvbl9mdyArIGFmZl9jaXRhdGlvbl9mdywgZXhhY3QgPSBjKCd5ZWFyJywgJ3Nlbmlvcml0eScsICdjb25jZXB0X21haW4nKSwKICAgICAgICAgIGRhdGEgPSAuLCB2ZXJib3NlID0gRkFMU0UsIG1ldGhvZCA9ICJuZWFyZXN0IiwgcmF0aW8gPSAxKSAjIE9SIG1ldGhvZCAgImdlbmV0aWMiIC4uLiB0YWtlcyBmb3JldmVyLi4uLi4KYGBgCgpgYGB7cn0KIyBHRXQgdGhlIG1hdGNoZWQgcGFpcnMKbWF0Y2hlZF9wYWlycyAgPC0gYmluZF9jb2xzKGRhdGFfbWF0Y2hbcm93Lm5hbWVzKG1hdGNoX291dCRtYXRjaC5tYXRyaXgpLCJBSUQiXSAsIGRhdGFfbWF0Y2hbbWF0Y2hfb3V0JG1hdGNoLm1hdHJpeCwiQUlEIl0gKSAlPiUKICByZW5hbWUob3JpZ19BSUQgPSBgQUlELi4uMWAsCiAgICAgICAgIG1hdGNoX0FJRCA9IGBBSUQuLi4yYCkgCmBgYAoKYGBge3J9CiMgY29uc3RydWN0IHRoZSBtYXRjaGVkIGRhdGFzZXQKZGF0YV9kaWQgPC0gbWF0Y2hlZF9wYWlycyAlPiUgCiAgbXV0YXRlKHBhaXJfaWQgPSAxOm4oKSkKCmRhdGFfZGlkIDwtIGRhdGFfZGlkICU+JQogIHNlbGVjdChvcmlnX0FJRCwgcGFpcl9pZCkgJT4lCiAgcmVuYW1lKEFJRCA9IG9yaWdfQUlEKSAlPiUKICBiaW5kX3Jvd3MoZGF0YV9kaWQgJT4lCiAgc2VsZWN0KG1hdGNoX0FJRCwgcGFpcl9pZCkgJT4lCiAgcmVuYW1lKEFJRCA9IG1hdGNoX0FJRCkgKSAlPiUKICBhcnJhbmdlKHBhaXJfaWQpICU+JQogIGxlZnRfam9pbihkYXRhLCBieSA9ICdBSUQnKQpgYGAKCmBgYHtyfQojIGNvbXB1dGUgdHJhbnNpdGlvbiBwb2ludCBmb3IgbWF0Y2hlZCBwYXJ0bmVyCmRhdGFfZGlkICU8PiUKICBncm91cF9ieShwYWlyX2lkKSAlPiUKICBtdXRhdGUoc3dpdGNoZXIgPSB0eXBlID09ICdzd2l0Y2hlcicsCiAgICAgICAgIHllYXJfdHJhbnNpdCA9IG1heCh5ZWFyX3RyYW5zaXQsIG5hLnJtID0gVFJVRSksCiAgICAgICAgIHRyYW5zaXRpb24gPSB5ZWFyID09IHllYXJfdHJhbnNpdCwKICAgICAgICAgdHJhbnNpdGVkID0geWVhciA+PSB5ZWFyX3RyYW5zaXQsCiAgICAgICAgIHRyYW5zaXRlZF90ID0geWVhciAtIHllYXJfdHJhbnNpdCArIDEpICU+JQogIG11dGF0ZShhY3Jvc3MoYyh5ZWFyLCBjb25jZXB0cywgdHJhbnNpdGVkKSwgfiBmYWN0b3IoLngpKSkgJT4lCiAgbXV0YXRlKHRyYW5zaXRlZF90ID0gaWZlbHNlKHRyYW5zaXRlZF90ID4gMCwgdHJhbnNpdGVkX3QsIDApKSAlPiUKICBkcm9wX25hKCkgJT4lCiAgdW5ncm91cCgpCmBgYAoKYGBge3J9CmRhdGFfZGlkICU+JSBzYXZlUkRTKCcuLi90ZW1wX3JlZy9yZWdfZGF0YV9kaWQucmRzJykKYGBgCgojIERpZmYtaW4tRGlmZgoKYGBge3J9CiMgRGVsZXRlIGFsbCBvYmplY3RzCnJtKGxpc3QgPSBscyhhbGwubmFtZXMgPSBUUlVFKSkgI3dpbGwgY2xlYXIgYWxsIG9iamVjdHMgaW5jbHVkZXMgaGlkZGVuIG9iamVjdHMuCmdjKCkgI2ZyZWUgdXAgbWVtcm9yeSBhbmQgcmVwb3J0IHRoZSBtZW1vcnkgdXNhZ2UuCgpkYXRhX2RpZCA8LSByZWFkX3JkcygnLi4vdGVtcF9yZWcvcmVnX2RhdGFfZGlkLnJkcycpCmBgYAoKYGBge3J9CiMgRm9yIHRoZSBpbnRlcmFjdGlvbiBwbG90IGNvZGUgbG9naWNhbCB0byBudW1lcmljCiMgZGF0YV9kaWQgJTw+JSAgbXV0YXRlKHN3aXRjaGVyID0gc3dpdGNoZXIgJT4lIGFzLm51bWVyaWMoKSwgdHJhbnNpdGVkID0gdHJhbnNpdGVkICU+JSBhcy5udW1lcmljKCkpCmBgYAoKYGBge3J9CmRhdGFfZGlkICU+JSAKICBjb3VudChjb25jZXB0cywgc29ydCA9IFRSVUUpICU+JSAKICBtdXRhdGUocmFua19wY3QgPSBwZXJjZW50X3JhbmsobikpCmBgYAoKCgojIyBNb2RlbHMKCmBgYHtyfQojIGZpdF9kaWRfMCA8LSBsbShjaXRhdGlvbl9yYW5rIH4gc3dpdGNoZXIgKyBmaWVsZF9vZl9zdHVkeV9uYW1lLCBkYXRhID0gZGF0YV9kaWQpCgpmaXRfZGlkXzEgPC0gbG0oY2l0YXRpb25fZncgfiAodHlwZSArIHRyYW5zaXRlZCleMiArIHllYXIgKyBzZW5pb3JpdHkgKyB5ZWFyLCAjICsgY29uY2VwdHMsIAogICAgICAgICAgICAgICAgZGF0YSA9IGRhdGFfZGlkKQoKZml0X2RpZF8yIDwtIGxtKGNpdGF0aW9uX2Z3IH4gKHR5cGUgKyB0cmFuc2l0ZWQpXjIgKyAodHlwZSArIHRyYW5zaXRlZF90KV4yICsgeWVhciAgKyBzZW5pb3JpdHksICMgKyBjb25jZXB0cywgCiAgICAgICAgICAgICAgICBkYXRhID0gZGF0YV9kaWQpCgpmaXRfZGlkXzMgPC0gbG0obm92ZWx0eV9mdyB+ICh0eXBlICsgdHJhbnNpdGVkKV4yICsgeWVhciArIHNlbmlvcml0eSArIHllYXIsICMgKyBjb25jZXB0cywgCiAgICAgICAgICAgICAgICBkYXRhID0gZGF0YV9kaWQpCgpmaXRfZGlkXzQgPC0gbG0obm92ZWx0eV9mdyB+ICh0eXBlICsgdHJhbnNpdGVkKV4yICsgKHR5cGUgKyB0cmFuc2l0ZWRfdCleMiArIHllYXIgKyBzZW5pb3JpdHksICMgKyBjb25jZXB0cyAsIAogICAgICAgICAgICAgICAgZGF0YSA9IGRhdGFfZGlkKQoKIyArIHBhcGVyX24gPwpgYGAKCmBgYHtyfQojc3RhcmdhemVyKGZpdF9kaWRfMSwgZml0X2RpZF8yLCBmaXRfZGlkXzMsIGZpdF9kaWRfNCwgdHlwZSA9ICdsYXRleCcsIG9taXQgPSBjKCAnY29uY2VwdHMnLCAneWVhcicsICdDb25zdGFudCcpLCBvdXQgPScuLi8uLi9vdXRwdXQvZGlkX3JlczEudGV4JykKYGBgCgpgYGB7cn0Kc3RhcmdhemVyKGZpdF9kaWRfMSwgZml0X2RpZF8yLCBmaXRfZGlkXzMsIGZpdF9kaWRfNCwgdHlwZSA9ICd0ZXh0Jywgb21pdCA9IGMoJ3llYXInLCAnQ29uc3RhbnQnKSkKYGBgCgpgYGB7ciwgcmVzdWx0cz0nYXNpcyd9CnN0YXJnYXplcihmaXRfZGlkXzEsIGZpdF9kaWRfMiwgZml0X2RpZF8zLCBmaXRfZGlkXzQsIHR5cGUgPSAnaHRtbCcsIG9taXQgPSBjKCd5ZWFyJywgJ0NvbnN0YW50JykpCmBgYAoKCgo8IS0tLQojIyMgVGVtcGxhdGUgbmV3IHBsb3R0aW5nIG1vZGVsCgpgYGB7cn0KI2xpYnJhcnkoaW50ZXJwbG90KQojZml0X2RpZF8yICU+JSBpbnRlcnBsb3QodmFyMSA9InN3aXRjaGVyIiwgdmFyMiA9ICJ0cmFuc2l0ZWRfdCIsIGhpc3QgPSBUUlVFKSAKYGBgCgpgYGB7cn0KbGlicmFyeShpbnRlcmFjdGlvbnMpCmZpdF9kaWRfMiAlPiUgaW50ZXJhY3RfcGxvdChwcmVkID0gdHJhbnNpdGVkX3QsIG1vZHggPSBzd2l0Y2hlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVydmFsID0gVFJVRSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdib3R0b20nKQpgYGAKCmBgYHtyfQpnZ3NhdmUoJy4uLy4uL291dHB1dC9maWdfaW50ZXJhY3Rpb25fMS5wbmcnLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA3LjUsIHVuaXRzID0gJ2NtJykKYGBgCgoKYGBge3J9CmxpYnJhcnkoaW50ZXJhY3Rpb25zKQpmaXRfZGlkXzIgJT4lIGludGVyYWN0X3Bsb3QocHJlZCA9IHRyYW5zaXRlZF90LCBtb2R4ID0gc3dpdGNoZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbCA9IFRSVUUsIGxpbmVhcml0eS5jaGVjayA9IFRSVUUpCmBgYAoKCi0tLT4KCiMgRGVzY3JpcHRpdmVzCgo8IS0tLQoKIyMgQWxsIGRhdGEKCmBgYHtyLCByZXN1bHRzPSdhc2lzJ30KZGF0YSAlPiUgc2VsZWN0KHNlbmlvcml0eSwgZGVnX2NlbiwgZGVnX2Nlbl9jb21wLCBjb19hdXRob3JfaW5kdXN0cnksIERMLCBwYXBlcl9uLCBhdXRob3JfbWVhbiwgY2l0YXRpb25fZncsIG5vdmVsdHlfZncsIGFmZl9jaXRhdGlvbl9mdywgYWZmX25vdmVsdHlfZncpICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgc3RhcmdhemVyKHN1bW1hcnkgPSBUUlVFLCB0eXBlID0gJ2h0bWwnKQpgYGAKCiMjIEJ5IHVuaXZlcnNpdHkgdnMuIHN3aXRjaGVyIGNhcmVlcgoKYGBge3IsIHJlc3VsdHM9J2FzaXMnfQpkYXRhICU+JSAKICBzZWxlY3QodHlwZSwgc2VuaW9yaXR5LCBkZWdfY2VuLCBkZWdfY2VuX2NvbXAsIGNvX2F1dGhvcl9pbmR1c3RyeSwgREwsIHBhcGVyX24sIGF1dGhvcl9tZWFuLCBjaXRhdGlvbl9mdywgbm92ZWx0eV9mdywgYWZmX2NpdGF0aW9uX2Z3LCBhZmZfbm92ZWx0eV9mdykgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIHNwbGl0KC4kdHlwZSkgJT4lIAogIHdhbGsofiBzdGFyZ2F6ZXIoLiwgc3VtbWFyeSA9IFRSVUUsIHR5cGUgPSAnaHRtbCcpKQpgYGAKCgpgYGB7cn0KZGF0YSAlPiUgCiAgZmlsdGVyKHRyYW5zaXRlZF90IDw9IDApICU+JQogIG11dGF0ZShhdXRoX3N0YXIgPSBjaXRhdGlvbl9mdyA+PSAwLjksCiAgICAgICAgIGFmZl9zdGFyID0gYWZmX2NpdGF0aW9uX2Z3ID49IDAuOSkKYGBgCgoKLS0+CgoKCg==