1 Custom functions

rm(list = ls())

fpackage.check <- function(packages) {
    lapply(packages, FUN = function(x) {
        if (!require(x, character.only = TRUE)) {
            install.packages(x, dependencies = TRUE)
            library(x, character.only = TRUE)
        }
    })
}

fsave <- function(x, file = NULL, location = "./data/processed/") {
    ifelse(!dir.exists("data"), dir.create("data"), FALSE)
    ifelse(!dir.exists("data/processed"), dir.create("data/processed"), FALSE)
    if (is.null(file))
        file = deparse(substitute(x))
    datename <- substr(gsub("[:-]", "", Sys.time()), 1, 8)
    totalname <- paste(location, file, "_", datename,  ".rda", sep = "")
    save(x, file = totalname)  #need to fix if file is reloaded as input name, not as x. 
}

fload <- function(filename) {
    load(filename)
    get(ls()[ls() != "filename"])
}

fshowdf <- function(x, ...) {
    knitr::kable(x, digits = 3, "html", ...) %>%
        kableExtra::kable_styling(bootstrap_options = c("striped", "hover")) %>%
        kableExtra::scroll_box(width = "100%", height = "300px")
}

colorize <- function(x, color) {sprintf("<span style='color: %s;'>%s</span>", color, x) }

2 Packages

packages = c("ggplot2", "ggpubr", "tidyverse", "RColorBrewer", "stringdist", "stringi", "future.apply",
    "gamlss", "gamlss.dist", "gamlss.tr", "splines", "splines2", "psych", "MASS", "dplyr", "flextable",
    "fastDummies", "fixest", "ggtext")

# load dplyr last otherwise conflict with select from MASS
fpackage.check(packages)

3 Input

We use three processed datasets.

  • 20240717df_ppf.rda: person period file for main analysis
  • 20240717df_pubs.rda: publications for descriptives
  • 20240711linked_pubs_oa_fields.rda: publications linked to fields
df_ppf <- fload(file = "./data/processed/20240717df_ppf.rda")

df_pubs <- fload(file = "./data/processed/20240717df_pubs.rda")

df_fields <- fload(file = "./data/processed/20240711linked_pubs_oa_fields.rda")

4 Data wrangling

4.1 Domain

I will use all publications. Also the publications of 2020 and later, as I think this indicates the field/domain the author was working in during Covid.

I don’t pick the top domain, but calculate a percentage within domain. This does imho more justice to multidisciplinary and also takes into account possible arbitrariness in the black box of openalex domain identifier.

domain <- df_fields %>% dplyr::select("domain", "id") %>% #select conflicts with MASS
                filter(!is.na(domain)) %>%
                mutate(domain2 = as.numeric(as.factor(domain))) %>% #make numeric of domain variable
                group_by(id)  %>%
                mutate(npubs_domain = n(), #number of publications domain is based
                       health_domain = sum(domain2 == 1) / npubs_domain, #domain as proportions
                       life_domain = sum(domain2 == 2) / npubs_domain,
                       physical_domain = sum(domain2 == 3) / npubs_domain,
                       social_domain = sum(domain2 == 4) / npubs_domain) %>%
                ungroup() %>% #only keep one record per id
                mutate(id.dup =ifelse(duplicated(id), 1,0)) %>% 
                filter(id.dup == 0) %>%
                dplyr::select("id", "npubs_domain", "health_domain", "life_domain", "physical_domain", "social_domain")

#describe(domain)

add to our df_ppf

df_ppf <- df_ppf %>%
    left_join(domain)

4.2 Gender

df_gender <- df_pubs %>%
    ungroup() %>%
    mutate(id.dup = ifelse(duplicated(id), 1, 0)) %>%
    filter(id.dup == 0) %>%
    dplyr::select("id", "gender_2", "firstname", "lastname") %>%
    mutate(gender2 = ifelse(is.na(firstname) & is.na(gender_2), 3, gender_2))

df_gender$gender2[is.na(df_gender$gender2)] <- 4
df_gender$gender2 <- as.factor(df_gender$gender2)
levels(df_gender$gender2) <- c("men", "women", "no first name", "missing")
df_ppf <- df_ppf %>%
    left_join(df_gender)

4.3 Time (career age)

df_ppf$time <- df_ppf$pub_year - df_ppf$phd_year

df_ppf$covid <- as.numeric(df_ppf$pub_year == 2020 | df_ppf$pub_year == 2021)
df_ppf$covid2020 <- as.numeric(df_ppf$pub_year == 2020)
df_ppf$covid2021 <- as.numeric(df_ppf$pub_year == 2021)

df_ppf$age25 <- as.numeric(df_ppf$phd_year > 2010)
df_ppf$age25_2 <- as.numeric(df_ppf$phd_year > 2015)

df_ppf$phd_year0 <- df_ppf$phd_year - 1990

df_ppf$stem <- ifelse((df_ppf$field == "Biological and Health Sciences" | df_ppf$field == "Physical and Mathematical Sciences" |
    df_ppf$field == "Engineering" | df_ppf$field == "Agricultural Sciences"), "STEM-M", ifelse(df_ppf$field ==
    "missing", "missing", "NON-STEM-M"))

df_ppf$ethnicity <- as.factor(df_ppf$ethnicity)
df_ppf$ethnicity <- relevel(df_ppf$ethnicity, 2)
# levels(df_ppf$ethnicity)

df_ppf$multidisc <- 1 - (df_ppf$health_domain^2 + df_ppf$life_domain^2 + df_ppf$physical_domain^2 + df_ppf$social_domain^2)

5 Robustness checks

5.1 Model 2 separate per domain

5.1.1 Strict selection

I am currently making strict selections on domain. Namely, authors who only publish in a specific domain. A different strategy would be to use >.5 as criteria or classifying scholars based on highest score across the domains.

df3 <- df_ppf[, c("npubs", "npubs_a", "npubs_first_a", "npubs_last_a", "time", "id", "covid", "covid2020",
    "covid2021", "gender2", "phd_year0", "ethnicity", "uni", "health_domain", "life_domain", "physical_domain",
    "social_domain")]
df3 <- na.omit(df3)

knots5 <- quantile(df3$time, probs = seq(0, 1, 0.25))[2:4]
con <- gamlss.control(n.cyc = 150)


df3_d1 <- df3[df3$health_domain == 1, ]
df3_d2 <- df3[df3$life_domain == 1, ]
df3_d3 <- df3[df3$physical_domain == 1, ]
df3_d4 <- df3[df3$social_domain == 1, ]

m2_d1 <- gamlss(npubs ~ bSpline(time, knots = knots5, df = 3) + phd_year0 + covid + gender2 + ethnicity +
    uni + covid * gender2, data = df3_d1, family = BNB, control = con)
fsave(m2_d1, "m2_d1")
sm2_d1 <- summary(m2_d1)
fsave(sm2_d1, "sm2_d1")

m2_d2 <- gamlss(npubs ~ bSpline(time, knots = knots5, df = 3) + phd_year0 + covid + gender2 + ethnicity +
    uni + covid * gender2, data = df3_d2, family = BNB, control = con)
fsave(m2_d2, "m2_d2")
sm2_d2 <- summary(m2_d2)
fsave(sm2_d2, "sm2_d2")

m2_d3 <- gamlss(npubs ~ bSpline(time, knots = knots5, df = 3) + phd_year0 + covid + gender2 + ethnicity +
    uni + covid * gender2, data = df3_d3, family = BNB, control = con)
fsave(m2_d3, "m2_d3")
sm2_d3 <- summary(m2_d3)
fsave(sm2_d3, "sm2_d3")

m2_d4 <- gamlss(npubs ~ bSpline(time, knots = knots5, df = 3) + phd_year0 + covid + gender2 + ethnicity +
    uni + covid * gender2, data = df3_d4, family = BNB, control = con)
fsave(m2_d4, "m2_d4")
sm2_d4 <- summary(m2_d4)
fsave(sm2_d4, "sm2_d4")
names <- c("Intercept: mu", "bSpline(time, knots = knots5, df = 3)1", "bSpline(time, knots = knots5, df = 3)2",
    "bSpline(time, knots = knots5, df = 3)3", "bSpline(time, knots = knots5, df = 3)4", "bSpline(time, knots = knots5, df = 3)5",
    "bSpline(time, knots = knots5, df = 3)6", "PhD-cohort", "COVID-19 years", "gender: women", "gender: no first name",
    "gender: missing", "ethnicity: minority I", "ethnicity: minority II", "ethnicity: missing", "university: LU",
    "university: RU", "university: RUG", "university: TUE", "university: TI", "university: UM", "university: UT",
    "university: UU", "university: UvA", "university: VU", "university: WUR", "COVID*women", "COVID*no first name",
    "COVID*missing", "Intercept: sigma", "Intercept: nu")
rownames(sm2_d1) <- names

names <- c("Intercept: mu", "bSpline(time, knots = knots5, df = 3)1", "bSpline(time, knots = knots5, df = 3)2",
    "bSpline(time, knots = knots5, df = 3)3", "bSpline(time, knots = knots5, df = 3)4", "bSpline(time, knots = knots5, df = 3)5",
    "bSpline(time, knots = knots5, df = 3)6", "PhD-cohort", "COVID-19 years", "gender: women", "gender: no first name",
    "gender: missing", "ethnicity: minority I", "ethnicity: minority II", "ethnicity: missing", "university: LU",
    "university: RU", "university: RUG", "university: UM", "university: UT", "university: UU", "university: UvA",
    "university: VU", "university: WUR", "COVID*women", "COVID*no first name", "COVID*missing", "Intercept: sigma",
    "Intercept: nu")
rownames(sm2_d2) <- names

names <- c("Intercept: mu", "bSpline(time, knots = knots5, df = 3)1", "bSpline(time, knots = knots5, df = 3)2",
    "bSpline(time, knots = knots5, df = 3)3", "bSpline(time, knots = knots5, df = 3)4", "bSpline(time, knots = knots5, df = 3)5",
    "bSpline(time, knots = knots5, df = 3)6", "PhD-cohort", "COVID-19 years", "gender: women", "gender: no first name",
    "gender: missing", "ethnicity: minority I", "ethnicity: minority II", "ethnicity: missing", "university: LU",
    "university: RU", "university: RUG", "university: TUD", "university: TUE", "university: UM", "university: UT",
    "university: UU", "university: UvA", "university: VU", "university: WUR", "COVID*women", "COVID*no first name",
    "COVID*missing", "Intercept: sigma", "Intercept: nu")
rownames(sm2_d3) <- names

names <- c("Intercept: mu", "bSpline(time, knots = knots5, df = 3)1", "bSpline(time, knots = knots5, df = 3)2",
    "bSpline(time, knots = knots5, df = 3)3", "bSpline(time, knots = knots5, df = 3)4", "bSpline(time, knots = knots5, df = 3)5",
    "bSpline(time, knots = knots5, df = 3)6", "PhD-cohort", "COVID-19 years", "gender: women", "gender: no first name",
    "gender: missing", "ethnicity: minority I", "ethnicity: minority II", "ethnicity: missing", "university: LU",
    "university: RU", "university: RUG", "university: TUD", "university: TUE", "university: TI", "university: UM",
    "university: UT", "university: UU", "university: UvA", "university: VU", "university: WUR", "COVID*women",
    "COVID*no first name", "COVID*missing", "Intercept: sigma", "Intercept: nu")
rownames(sm2_d4) <- names


fshowdf(sm2_d1)
fshowdf(sm2_d2)
fshowdf(sm2_d3)
fshowdf(sm2_d4)
Estimate Std. Error t value Pr(>|t|)
Intercept: mu 1.550 0.081 19.219 0.000
bSpline(time, knots = knots5, df = 3)1 -0.733 0.110 -6.681 0.000
bSpline(time, knots = knots5, df = 3)2 -0.894 0.093 -9.604 0.000
bSpline(time, knots = knots5, df = 3)3 -1.150 0.096 -12.033 0.000
bSpline(time, knots = knots5, df = 3)4 -1.094 0.172 -6.372 0.000
bSpline(time, knots = knots5, df = 3)5 -1.004 0.284 -3.539 0.000
bSpline(time, knots = knots5, df = 3)6 -2.475 0.385 -6.427 0.000
PhD-cohort -0.033 0.003 -10.614 0.000
COVID-19 years -0.485 0.080 -6.089 0.000
gender: women -0.240 0.036 -6.722 0.000
gender: no first name 0.835 0.174 4.812 0.000
gender: missing 0.411 0.405 1.016 0.310
ethnicity: minority I 0.094 0.159 0.589 0.556
ethnicity: minority II 0.016 0.068 0.241 0.810
ethnicity: missing -0.242 0.066 -3.660 0.000
university: LU -0.146 0.354 -0.412 0.680
university: RU 0.278 0.045 6.205 0.000
university: RUG 0.382 0.152 2.519 0.012
university: TUE -1.607 0.461 -3.482 0.000
university: TI 0.629 0.174 3.619 0.000
university: UM 0.309 0.056 5.519 0.000
university: UT -0.299 0.103 -2.897 0.004
university: UU 0.273 0.062 4.427 0.000
university: UvA 0.296 0.079 3.733 0.000
university: VU 0.391 0.095 4.130 0.000
university: WUR 0.666 0.089 7.506 0.000
COVID*women -0.125 0.109 -1.142 0.254
COVID*no first name 0.531 0.569 0.934 0.350
COVID*missing 0.026 0.809 0.032 0.974
Intercept: sigma -1.642 0.093 -17.620 0.000
Intercept: nu -1.426 0.175 -8.161 0.000
Estimate Std. Error t value Pr(>|t|)
Intercept: mu 1.711 0.145 11.783 0.000
bSpline(time, knots = knots5, df = 3)1 -0.782 0.171 -4.568 0.000
bSpline(time, knots = knots5, df = 3)2 -0.879 0.127 -6.896 0.000
bSpline(time, knots = knots5, df = 3)3 -1.184 0.138 -8.580 0.000
bSpline(time, knots = knots5, df = 3)4 -0.757 0.199 -3.801 0.000
bSpline(time, knots = knots5, df = 3)5 -1.305 0.258 -5.051 0.000
bSpline(time, knots = knots5, df = 3)6 -1.509 0.260 -5.796 0.000
PhD-cohort -0.058 0.004 -14.754 0.000
COVID-19 years -0.571 0.083 -6.863 0.000
gender: women -0.096 0.049 -1.972 0.049
gender: no first name -0.649 0.337 -1.927 0.054
gender: missing -0.608 1.061 -0.573 0.567
ethnicity: minority I -0.412 0.237 -1.738 0.082
ethnicity: minority II -0.260 0.079 -3.299 0.001
ethnicity: missing -0.271 0.059 -4.564 0.000
university: LU 0.031 0.256 0.121 0.904
university: RU 0.129 0.103 1.246 0.213
university: RUG 1.013 0.172 5.892 0.000
university: UM 0.018 0.129 0.140 0.889
university: UT -0.471 0.351 -1.342 0.180
university: UU -0.029 0.128 -0.226 0.821
university: UvA 0.313 0.106 2.956 0.003
university: VU 0.391 0.125 3.115 0.002
university: WUR 0.588 0.093 6.355 0.000
COVID*women 0.200 0.120 1.662 0.097
COVID*no first name -0.359 0.851 -0.422 0.673
COVID*missing -34.642 70710.678 0.000 1.000
Intercept: sigma -2.510 0.127 -19.708 0.000
Intercept: nu -0.958 0.147 -6.511 0.000
Estimate Std. Error t value Pr(>|t|)
Intercept: mu 2.118 0.310 6.842 0.000
bSpline(time, knots = knots5, df = 3)1 -0.702 0.102 -6.848 0.000
bSpline(time, knots = knots5, df = 3)2 -0.740 0.087 -8.547 0.000
bSpline(time, knots = knots5, df = 3)3 -0.971 0.087 -11.184 0.000
bSpline(time, knots = knots5, df = 3)4 -0.262 0.147 -1.783 0.075
bSpline(time, knots = knots5, df = 3)5 -1.068 0.216 -4.934 0.000
bSpline(time, knots = knots5, df = 3)6 -1.225 0.237 -5.164 0.000
PhD-cohort -0.035 0.003 -11.758 0.000
COVID-19 years -0.570 0.058 -9.880 0.000
gender: women 0.039 0.041 0.957 0.339
gender: no first name -0.287 0.155 -1.849 0.064
gender: missing 0.600 0.153 3.910 0.000
ethnicity: minority I -0.232 0.118 -1.962 0.050
ethnicity: minority II -0.214 0.052 -4.108 0.000
ethnicity: missing -0.026 0.039 -0.674 0.500
university: LU 0.096 0.318 0.301 0.763
university: RU 0.188 0.304 0.619 0.536
university: RUG 0.685 0.331 2.066 0.039
university: TUD 0.594 0.317 1.878 0.060
university: TUE 0.459 0.303 1.518 0.129
university: UM -1.017 0.434 -2.347 0.019
university: UT -0.236 0.302 -0.781 0.435
university: UU 0.154 0.302 0.510 0.610
university: UvA 0.380 0.302 1.259 0.208
university: VU -0.012 0.305 -0.040 0.968
university: WUR 0.014 0.303 0.047 0.963
COVID*women 0.135 0.109 1.245 0.213
COVID*no first name -0.355 0.738 -0.481 0.630
COVID*missing -0.412 0.749 -0.549 0.583
Intercept: sigma -0.376 0.049 -7.695 0.000
Intercept: nu -0.788 0.133 -5.926 0.000
Estimate Std. Error t value Pr(>|t|)
Intercept: mu 1.232 0.105 11.711 0.000
bSpline(time, knots = knots5, df = 3)1 -0.438 0.079 -5.560 0.000
bSpline(time, knots = knots5, df = 3)2 -0.478 0.063 -7.597 0.000
bSpline(time, knots = knots5, df = 3)3 -0.670 0.063 -10.644 0.000
bSpline(time, knots = knots5, df = 3)4 -1.006 0.108 -9.331 0.000
bSpline(time, knots = knots5, df = 3)5 -1.125 0.180 -6.256 0.000
bSpline(time, knots = knots5, df = 3)6 -2.696 0.255 -10.580 0.000
PhD-cohort -0.044 0.002 -20.955 0.000
COVID-19 years -0.571 0.056 -10.196 0.000
gender: women -0.088 0.023 -3.814 0.000
gender: no first name -0.327 0.107 -3.050 0.002
gender: missing -0.146 0.295 -0.494 0.621
ethnicity: minority I -0.103 0.104 -0.991 0.322
ethnicity: minority II -0.184 0.046 -3.982 0.000
ethnicity: missing -0.031 0.032 -0.949 0.343
university: LU 0.592 0.115 5.162 0.000
university: RU 0.570 0.097 5.887 0.000
university: RUG 0.855 0.099 8.620 0.000
university: TUD 0.235 0.539 0.435 0.663
university: TUE 0.178 0.167 1.065 0.287
university: TI 0.695 0.117 5.930 0.000
university: UM 0.661 0.099 6.698 0.000
university: UT 0.554 0.105 5.270 0.000
university: UU 0.469 0.103 4.540 0.000
university: UvA 0.677 0.096 7.029 0.000
university: VU 0.632 0.098 6.426 0.000
university: WUR 0.467 0.145 3.225 0.001
COVID*women 0.060 0.078 0.762 0.446
COVID*no first name -0.190 0.401 -0.473 0.636
COVID*missing 1.200 0.615 1.950 0.051
Intercept: sigma -1.887 0.080 -23.494 0.000
Intercept: nu -1.643 0.185 -8.871 0.000

5.2 Fixed effects career age and person id

df3 <- df_ppf[, c("npubs", "npubs_a", "npubs_first_a", "npubs_last_a", "time", "pub_year", "id", "covid",
    "covid2020", "covid2021", "gender2", "phd_year0", "phd_year", "ethnicity", "uni", "life_domain",
    "physical_domain", "social_domain")]
df3 <- na.omit(df3)

df3$log_npubs <- log(df3$npubs + 1)
m_fe <- feols(log_npubs ~ 1 + covid + i(gender2, covid, ref = c("men")) | id + time, data = df3)
fshowdf(summary(m_fe)$coeftable)
Estimate Std. Error t value Pr(>|t|)
covid -0.284 0.009 -33.260 0.000
gender2::women:covid 0.039 0.013 3.041 0.002
gender2::no first name:covid -0.097 0.059 -1.643 0.100
gender2::missing:covid 0.026 0.103 0.249 0.804

Based on this modelling strategy we would conclude that women were significantly less negatively impacted by COVID-19 with respect to their absolute number of yearly articles.

5.3 Table 4

Staying close to modelling strategy of Madsen et al. (2022).

We do not use year of first pub to define career age but phd_year

df3 <- df_ppf[, c("npubs", "npubs_a", "npubs_first_a", "npubs_last_a", "time", "pub_year", "id", "covid",
    "covid2020", "covid2021", "gender2", "phd_year", "phd_year0", "ethnicity", "uni", "life_domain",
    "physical_domain", "social_domain")]

df3$log_npubs_a <- log(df3$npubs_a + 1)

df3_mid <- df3[df3$phd_year == 2008 | df3$phd_year == 2009 | df3$phd_year == 2010, ]
df3_early <- df3[df3$phd_year == 2014 | df3$phd_year == 2015 | df3$phd_year == 2016, ]

# remove missings on gender
df3_early <- df3_early[df3_early$gender2 == "men" | df3_early$gender2 == "women", ]
df3_mid <- df3_mid[df3_mid$gender2 == "men" | df3_mid$gender2 == "women", ]

df3_early$women <- ifelse(df3_early$gender2 == "women", 1, 0)
df3_mid$women <- ifelse(df3_mid$gender2 == "women", 1, 0)

5.3.1 observations

print("N_persons (early career)")
length(unique(df3_early$id))
print("N_observations (early career)")
nrow(df3_early)

print("N_persons (mid career)")
length(unique(df3_mid$id))
print("N_observations (mid career)")
nrow(df3_mid)
#> [1] "N_persons (early career)"
#> [1] 1310
#> [1] "N_observations (early career)"
#> [1] 8888
#> [1] "N_persons (mid career)"
#> [1] 1242
#> [1] "N_observations (mid career)"
#> [1] 14959
m_fe_e <- feols(log_npubs_a ~ 1 + i(pub_year, women, ref = "2019") | id + pub_year, data = df3_early)
m_fe_m <- feols(log_npubs_a ~ 1 + i(pub_year, women, ref = "2019") | id + pub_year, data = df3_mid)

5.3.2 fit measures

r2 <- c(fixest::r2(m_fe_e, "r2"), fixest::r2(m_fe_m, "r2"))  #overal r2
wr2 <- c(fixest::r2(m_fe_e, "wr2"), fixest::r2(m_fe_m, "wr2"))  #within r2

df_fitst4 <- data.frame(r2 = r2, wr2 = wr2)
# fsave(df_fitst4, 'df_fitst4')
smfee <- as.data.frame(coeftable(m_fe_e))
smfee$names <- rownames(smfee)
smfem <- as.data.frame(coeftable(m_fe_m))
smfem$names <- rownames(smfem)
res <- right_join(smfee, smfem, by = "names")
res <- res[order(res$names), ]

res <- res[, -c(3, 8)]
res <- res[, c(4, 1:3, 5:7)]
res$names <- c("year2009*women", "year2010*women", "year2011*women", "year2012*women", "year2013*women",
    "year2014*women", "year2015*women", "year2016*women", "year2017*women", "year2018*women", "year2020*women",
    "year2021*women", "year2022*women")

colnames(res) <- as.character(1:7)

# fsave(res, 'Table4_raw')
Table4_raw <- res


table4ft <- flextable(Table4_raw)  %>% add_header_row(values=c(" ", rep(c("B", "S.E.", "P"), 2)), top=FALSE) %>% delete_rows(i=1,part="header") %>% 
  #set_caption( "Fixed-Effects model for yearly article output (logtransformed; Gaussian)") %>% 
  add_footer_lines(value = c("Notes: \nFor reasons of parsimony, the estimates of the fixed effects are not shown: scholars; year. Scholars with missing values on gender were removed from the analysis.\nEarly career: N_observations 8,888; N_persons 1,310 \n Mid career: N_obervations 14,959; N_persons: 1,242")) %>%
   add_header_row(values = c(" ", "early career PhDs", "mid-career PhDs"),  colwidths = c(1, 3, 3)) %>%
 align(i = 1, align = "center", part = "header") %>%
  align(i = 2, align = "center", part = "header") %>%
  colformat_double(digits = 3) %>% 
  fontsize(size = 8, part = "all" )  %>%
  set_table_properties(opts_pdf = list(arraystretch = 1)) %>% #to adjust row height
  width(j = 1, width = 1.3) %>%
  width(j = 2:7 , width = .4) 


table4ft <- add_body_row(table4ft,
  values = c("overall R-squared",round(df_fitst4$r2,3)),
  colwidths = c(1,rep(3, 2)), top = FALSE
  ) %>% 
  align(i = 14, j=c(2:7), align = "center", part = "body") 

table4ft <- add_body_row(table4ft,
  values = c("within R-squared", round(df_fitst4$wr2,3)),
  colwidths = c(1,rep(3, 2)), top = FALSE
  ) %>% 
  align(i = 15, j=c(2:7), align = "center", part = "body") 
  
table4ft  %>% 
  border_inner_h(border = fp_border_default(width = 0), part = "body") %>% 
   hline(i = 13) 
Table 4. Fixed-Effects model for yearly article output (logtransformed; Gaussian)

early career PhDs

mid-career PhDs

B

S.E.

P

B

S.E.

P

year2009*women

-0.066

0.080

0.411

year2010*women

-0.062

0.067

0.354

year2011*women

-0.074

0.057

0.194

year2012*women

-0.040

0.053

0.454

year2013*women

-0.041

0.049

0.404

year2014*women

-0.039

0.049

0.431

year2015*women

0.071

0.065

0.276

-0.009

0.045

0.836

year2016*women

0.084

0.046

0.070

-0.032

0.042

0.452

year2017*women

0.033

0.039

0.394

-0.027

0.041

0.514

year2018*women

0.007

0.037

0.858

-0.018

0.037

0.637

year2020*women

0.003

0.038

0.935

0.007

0.039

0.852

year2021*women

0.025

0.039

0.529

0.074

0.043

0.086

year2022*women

0.085

0.039

0.030

0.041

0.044

0.349

overall R-squared

0.53

0.524

within R-squared

0.001

0.001

Notes:
For reasons of parsimony, the estimates of the fixed effects are not shown: scholars; year. Scholars with missing values on gender were removed from the analysis.
Early career: N_observations 8,888; N_persons 1,310
Mid career: N_obervations 14,959; N_persons: 1,242


Based on this modelling strategy we conclude that the gender gaps in publication were not more severe for women during COVID-19 than in pre- or post-COVID-19 years.

5.3.3 ATT

Dashed line is counterfactual. The difference between the blue dashed line and the solid dashed line is what (Madsen et al. 2022) interpret as the ATT.

5.3.3.1 Early career

df3_early$preds <- exp(predict(m_fe_e) - 1)

df3_early_new <- df3_early

df3_early_new <- df3_early_new %>%
    mutate(women = case_when(pub_year > 2018 ~ 0, .default = women))

df3_early_new$preds2 <- exp(predict(m_fe_e, newdata = df3_early_new) - 1)


df3_early_new$women <- df3_early$women
df3_early_ag <- df3_early_new %>%
    group_by(women, pub_year) %>%
    summarise(yhat_mean = mean(preds), yhat_mean_c = mean(preds2))


5.3.3.2 Mid career

df3_mid$preds <- exp(predict(m_fe_m) - 1)

df3_mid_new <- df3_mid

df3_mid_new <- df3_mid_new %>%
    mutate(women = case_when(pub_year > 2018 ~ 0, .default = women))

df3_mid_new$preds2 <- exp(predict(m_fe_m, newdata = df3_mid_new) - 1)

df3_mid_new$women <- df3_mid$women
df3_mid_ag <- df3_mid_new %>%
    group_by(women, pub_year) %>%
    summarise(yhat_mean = mean(preds), yhat_mean_c = mean(preds2))


gec <- ggplot(df3_early_ag, aes(x = pub_year, y = yhat_mean)) + geom_line(aes(color = as.factor(women)),
    show.legend = FALSE) + geom_line(aes(y = yhat_mean_c, color = as.factor(women)), show.legend = FALSE,
    linetype = "dashed") + ylim(0, 1.5) + xlab("year") + ylab("publication count") + theme_minimal() +
    theme(plot.caption = element_text(hjust = 0)) + theme(plot.margin = margin(t = 1, r = 1, b = 1, l = 1,
    unit = "cm"))


gmc <- ggplot(df3_mid_ag, aes(x = pub_year, y = yhat_mean)) + geom_line(aes(color = as.factor(women)),
    show.legend = TRUE) + geom_line(aes(y = yhat_mean_c, color = as.factor(women)), show.legend = FALSE,
    linetype = "dashed") + ylim(0, 1.5) + xlab("year") + ylab("publication count") + scale_colour_discrete(name = "Gender",
    breaks = c("0", "1"), labels = c("men", "women")) + theme_minimal() + theme(plot.caption = element_text(hjust = 0)) +
    theme(plot.margin = margin(t = 1, r = 1, b = 1, l = 1, unit = "cm"))


Figure_RR2 <- ggarrange(gec, gmc, ncol = 2, labels = c("early career", "mid career"), hjust = c(-0.5,
    -0.5), nrow = 1, common.legend = TRUE, legend = "right")


Figure_RR2 <- annotate_figure(Figure_RR2, bottom = text_grob("This figure shows the (mean) predicted publishing rates for men and women authors, with solid lines showing \nthe trend per gender, and the dashed blue line showing the counterfactual trend for women if they had similar \n2019–2022 trajectories as men. The difference between the dashed blue line and the straight blue line is \ninterpreted by Madsen et al. (2022) as the average treatment effect for women.",
    color = "black", just = "left", x = 0.05, y = 1, size = 10, lineheight = 1))

Figure_RR2

# now find a way to save correctly { pdf(file = './data/processed/20250729FigureRR2.pdf', width =
# 10, height =10) Figure_RR2 } dev.off() { png(file = './data/processed/20250729FigureRR2.png',
# width = 1600, height = 1600, units = 'px', res = 200) Figure_RR2 } dev.off()

Based on these figure we conclude that the ‘ATT’ for women is negative, women were less (negatively) impacted by COVID-19 than men.


Madsen, Emil Bargmann, Mathias Wullum Nielsen, Josefine Bjørnholm, Reshma Jagsi, and Jens Peter Andersen. 2022. “Author-Level Data Confirm the Widening Gender Gap in Publishing Rates During COVID-19.” eLife 11 (March). https://doi.org/10.7554/elife.76559.
LS0tDQp0aXRsZTogIlJvYnVzdG5lc3MiDQpiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliDQotLS0NCg0KYGBge3IsIGdsb2JhbHNldHRpbmdzLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeShrbml0cikNCiNsaWJyYXJ5KHJnbCkNCm9wdHNfY2h1bmskc2V0KHRpZHkub3B0cz1saXN0KHdpZHRoLmN1dG9mZj0xMDApLHRpZHk9VFJVRSwgd2FybmluZyA9IEZBTFNFLCByZXN1bHRzPSdob2xkJywgbWVzc2FnZSA9IEZBTFNFLGNvbW1lbnQgPSAiIz4iLCBjYWNoZT1UUlVFLCBjbGFzcy5zb3VyY2U9YygidGVzdCIpLCBjbGFzcy5vdXRwdXQ9YygidGVzdDIiKSwgY2FjaGUubGF6eSA9IEZBTFNFKQ0Kb3B0aW9ucyh3aWR0aCA9IDEwMCkNCnJnbDo6c2V0dXBLbml0cigpDQoNCmNvbG9yaXplIDwtIGZ1bmN0aW9uKHgsIGNvbG9yKSB7c3ByaW50ZigiPHNwYW4gc3R5bGU9J2NvbG9yOiAlczsnPiVzPC9zcGFuPiIsIGNvbG9yLCB4KSB9DQoNCmBgYA0KDQpgYGB7ciBrbGlwcHksIGVjaG89RkFMU0UsIGluY2x1ZGU9VFJVRSwgZXZhbD1UUlVFfQ0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCd0b3AnLCAncmlnaHQnKSkNCiNrbGlwcHk6OmtsaXBweShjb2xvciA9ICdkYXJrcmVkJykNCiNrbGlwcHk6OmtsaXBweSh0b29sdGlwX21lc3NhZ2UgPSAnQ2xpY2sgdG8gY29weScsIHRvb2x0aXBfc3VjY2VzcyA9ICdEb25lJykNCmBgYA0KDQotLS0tDQoNCiMgQ3VzdG9tIGZ1bmN0aW9ucw0KDQpgYGB7ciwgcmVzdWx0cz0naGlkZSd9DQpybShsaXN0ID0gbHMoKSkNCg0KZnBhY2thZ2UuY2hlY2sgPC0gZnVuY3Rpb24ocGFja2FnZXMpIHsNCiAgICBsYXBwbHkocGFja2FnZXMsIEZVTiA9IGZ1bmN0aW9uKHgpIHsNCiAgICAgICAgaWYgKCFyZXF1aXJlKHgsIGNoYXJhY3Rlci5vbmx5ID0gVFJVRSkpIHsNCiAgICAgICAgICAgIGluc3RhbGwucGFja2FnZXMoeCwgZGVwZW5kZW5jaWVzID0gVFJVRSkNCiAgICAgICAgICAgIGxpYnJhcnkoeCwgY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQ0KICAgICAgICB9DQogICAgfSkNCn0NCg0KZnNhdmUgPC0gZnVuY3Rpb24oeCwgZmlsZSA9IE5VTEwsIGxvY2F0aW9uID0gIi4vZGF0YS9wcm9jZXNzZWQvIikgew0KICAgIGlmZWxzZSghZGlyLmV4aXN0cygiZGF0YSIpLCBkaXIuY3JlYXRlKCJkYXRhIiksIEZBTFNFKQ0KICAgIGlmZWxzZSghZGlyLmV4aXN0cygiZGF0YS9wcm9jZXNzZWQiKSwgZGlyLmNyZWF0ZSgiZGF0YS9wcm9jZXNzZWQiKSwgRkFMU0UpDQogICAgaWYgKGlzLm51bGwoZmlsZSkpDQogICAgICAgIGZpbGUgPSBkZXBhcnNlKHN1YnN0aXR1dGUoeCkpDQogICAgZGF0ZW5hbWUgPC0gc3Vic3RyKGdzdWIoIls6LV0iLCAiIiwgU3lzLnRpbWUoKSksIDEsIDgpDQogICAgdG90YWxuYW1lIDwtIHBhc3RlKGxvY2F0aW9uLCBmaWxlLCAiXyIsIGRhdGVuYW1lLCAgIi5yZGEiLCBzZXAgPSAiIikNCiAgICBzYXZlKHgsIGZpbGUgPSB0b3RhbG5hbWUpICAjbmVlZCB0byBmaXggaWYgZmlsZSBpcyByZWxvYWRlZCBhcyBpbnB1dCBuYW1lLCBub3QgYXMgeC4gDQp9DQoNCmZsb2FkIDwtIGZ1bmN0aW9uKGZpbGVuYW1lKSB7DQogICAgbG9hZChmaWxlbmFtZSkNCiAgICBnZXQobHMoKVtscygpICE9ICJmaWxlbmFtZSJdKQ0KfQ0KDQpmc2hvd2RmIDwtIGZ1bmN0aW9uKHgsIC4uLikgew0KICAgIGtuaXRyOjprYWJsZSh4LCBkaWdpdHMgPSAzLCAiaHRtbCIsIC4uLikgJT4lDQogICAgICAgIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpICU+JQ0KICAgICAgICBrYWJsZUV4dHJhOjpzY3JvbGxfYm94KHdpZHRoID0gIjEwMCUiLCBoZWlnaHQgPSAiMzAwcHgiKQ0KfQ0KDQpjb2xvcml6ZSA8LSBmdW5jdGlvbih4LCBjb2xvcikge3NwcmludGYoIjxzcGFuIHN0eWxlPSdjb2xvcjogJXM7Jz4lczwvc3Bhbj4iLCBjb2xvciwgeCkgfQ0KYGBgDQoNCg0KLS0tICANCg0KIyBQYWNrYWdlcw0KDQpgYGB7ciwgcmVzdWx0cz0naGlkZSd9DQpwYWNrYWdlcyA9IGMoImdncGxvdDIiLCAiZ2dwdWJyIiwgInRpZHl2ZXJzZSIsICJSQ29sb3JCcmV3ZXIiLCAic3RyaW5nZGlzdCIsICJzdHJpbmdpIiwgImZ1dHVyZS5hcHBseSIsDQogICAgICAgICAgICAgICJnYW1sc3MiLCAiZ2FtbHNzLmRpc3QiLCAiZ2FtbHNzLnRyIiwgInNwbGluZXMiLCAic3BsaW5lczIiLCAicHN5Y2giLCAiTUFTUyIsICJkcGx5ciIsICJmbGV4dGFibGUiLCAiZmFzdER1bW1pZXMiLCAiZml4ZXN0IiwgImdndGV4dCIpDQoNCiNsb2FkIGRwbHlyIGxhc3Qgb3RoZXJ3aXNlIGNvbmZsaWN0IHdpdGggc2VsZWN0IGZyb20gTUFTUw0KZnBhY2thZ2UuY2hlY2socGFja2FnZXMpDQoNCmBgYA0KDQoNCi0tLSANCg0KIyBJbnB1dA0KDQpXZSB1c2UgdGhyZWUgcHJvY2Vzc2VkIGRhdGFzZXRzLg0KDQoqIGAyMDI0MDcxN2RmX3BwZi5yZGFgOiBwZXJzb24gcGVyaW9kIGZpbGUgZm9yIG1haW4gYW5hbHlzaXMgICAgDQoqIGAyMDI0MDcxN2RmX3B1YnMucmRhYDogcHVibGljYXRpb25zIGZvciBkZXNjcmlwdGl2ZXMgIA0KKiBgMjAyNDA3MTFsaW5rZWRfcHVic19vYV9maWVsZHMucmRhYDogcHVibGljYXRpb25zIGxpbmtlZCB0byBmaWVsZHMNCg0KYGBge3IgZGF0YX0NCmRmX3BwZiA8LSBmbG9hZChmaWxlID0gIi4vZGF0YS9wcm9jZXNzZWQvMjAyNDA3MTdkZl9wcGYucmRhIikNCg0KZGZfcHVicyA8LSBmbG9hZChmaWxlID0gIi4vZGF0YS9wcm9jZXNzZWQvMjAyNDA3MTdkZl9wdWJzLnJkYSIpICANCg0KZGZfZmllbGRzIDwtIGZsb2FkKGZpbGUgPSAiLi9kYXRhL3Byb2Nlc3NlZC8yMDI0MDcxMWxpbmtlZF9wdWJzX29hX2ZpZWxkcy5yZGEiKQ0KYGBgDQoNCi0tLSANCg0KIyBEYXRhIHdyYW5nbGluZyANCg0KIyMgRG9tYWluIA0KDQpJIHdpbGwgdXNlIGFsbCBwdWJsaWNhdGlvbnMuIEFsc28gdGhlIHB1YmxpY2F0aW9ucyBvZiAyMDIwIGFuZCBsYXRlciwgYXMgSSB0aGluayB0aGlzIGluZGljYXRlcyB0aGUgZmllbGQvZG9tYWluIHRoZSBhdXRob3Igd2FzIHdvcmtpbmcgaW4gZHVyaW5nIENvdmlkLiANCg0KSSBkb24ndCBwaWNrIHRoZSB0b3AgZG9tYWluLCBidXQgY2FsY3VsYXRlIGEgcGVyY2VudGFnZSB3aXRoaW4gZG9tYWluLiBUaGlzIGRvZXMgaW1obyBtb3JlIGp1c3RpY2UgdG8gbXVsdGlkaXNjaXBsaW5hcnkgYW5kIGFsc28gdGFrZXMgaW50byBhY2NvdW50IHBvc3NpYmxlIGFyYml0cmFyaW5lc3MgaW4gdGhlIGJsYWNrIGJveCBvZiBvcGVuYWxleCBkb21haW4gaWRlbnRpZmllci4gDQoNCmBgYHtyIG1lc3NhZ2UgPSBGLCB3YXJuaW5nID0gRiwgZXZhbCA9IFR9DQpkb21haW4gPC0gZGZfZmllbGRzICU+JSBkcGx5cjo6c2VsZWN0KCJkb21haW4iLCAiaWQiKSAlPiUgI3NlbGVjdCBjb25mbGljdHMgd2l0aCBNQVNTDQogICAgICAgICAgICAgICAgZmlsdGVyKCFpcy5uYShkb21haW4pKSAlPiUNCiAgICAgICAgICAgICAgICBtdXRhdGUoZG9tYWluMiA9IGFzLm51bWVyaWMoYXMuZmFjdG9yKGRvbWFpbikpKSAlPiUgI21ha2UgbnVtZXJpYyBvZiBkb21haW4gdmFyaWFibGUNCiAgICAgICAgICAgICAgICBncm91cF9ieShpZCkgICU+JQ0KICAgICAgICAgICAgICAgIG11dGF0ZShucHVic19kb21haW4gPSBuKCksICNudW1iZXIgb2YgcHVibGljYXRpb25zIGRvbWFpbiBpcyBiYXNlZA0KICAgICAgICAgICAgICAgICAgICAgICBoZWFsdGhfZG9tYWluID0gc3VtKGRvbWFpbjIgPT0gMSkgLyBucHVic19kb21haW4sICNkb21haW4gYXMgcHJvcG9ydGlvbnMNCiAgICAgICAgICAgICAgICAgICAgICAgbGlmZV9kb21haW4gPSBzdW0oZG9tYWluMiA9PSAyKSAvIG5wdWJzX2RvbWFpbiwNCiAgICAgICAgICAgICAgICAgICAgICAgcGh5c2ljYWxfZG9tYWluID0gc3VtKGRvbWFpbjIgPT0gMykgLyBucHVic19kb21haW4sDQogICAgICAgICAgICAgICAgICAgICAgIHNvY2lhbF9kb21haW4gPSBzdW0oZG9tYWluMiA9PSA0KSAvIG5wdWJzX2RvbWFpbikgJT4lDQogICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JSAjb25seSBrZWVwIG9uZSByZWNvcmQgcGVyIGlkDQogICAgICAgICAgICAgICAgbXV0YXRlKGlkLmR1cCA9aWZlbHNlKGR1cGxpY2F0ZWQoaWQpLCAxLDApKSAlPiUgDQogICAgICAgICAgICAgICAgZmlsdGVyKGlkLmR1cCA9PSAwKSAlPiUNCiAgICAgICAgICAgICAgICBkcGx5cjo6c2VsZWN0KCJpZCIsICJucHVic19kb21haW4iLCAiaGVhbHRoX2RvbWFpbiIsICJsaWZlX2RvbWFpbiIsICJwaHlzaWNhbF9kb21haW4iLCAic29jaWFsX2RvbWFpbiIpDQoNCiNkZXNjcmliZShkb21haW4pDQpgYGANCg0KYWRkIHRvIG91ciBkZl9wcGYNCg0KYGBge3J9DQpkZl9wcGYgPC0gZGZfcHBmICU+JSBsZWZ0X2pvaW4oZG9tYWluKQ0KYGBgDQoNCiMjIEdlbmRlcg0KDQpgYGB7cn0NCmRmX2dlbmRlciA8LSBkZl9wdWJzICU+JSAgDQogIHVuZ3JvdXAoKSAlPiUNCiAgbXV0YXRlKGlkLmR1cCA9aWZlbHNlKGR1cGxpY2F0ZWQoaWQpLCAxLDApKSAlPiUgDQogIGZpbHRlcihpZC5kdXAgPT0gMCkgJT4lIA0KICBkcGx5cjo6c2VsZWN0KCJpZCIsICJnZW5kZXJfMiIsICJmaXJzdG5hbWUiLCAibGFzdG5hbWUiKSAlPiUgDQogIG11dGF0ZShnZW5kZXIyID0gaWZlbHNlKGlzLm5hKGZpcnN0bmFtZSkgJiBpcy5uYShnZW5kZXJfMiksIDMsIGdlbmRlcl8yKSkNCg0KZGZfZ2VuZGVyJGdlbmRlcjJbaXMubmEoZGZfZ2VuZGVyJGdlbmRlcjIpXSA8LSA0DQpkZl9nZW5kZXIkZ2VuZGVyMiA8LSBhcy5mYWN0b3IoZGZfZ2VuZGVyJGdlbmRlcjIpDQpsZXZlbHMoZGZfZ2VuZGVyJGdlbmRlcjIpIDwtIGMoIm1lbiIsICJ3b21lbiIsICJubyBmaXJzdCBuYW1lIiwgIm1pc3NpbmciKQ0KYGBgDQoNCmBgYHtyfQ0KZGZfcHBmIDwtIGRmX3BwZiAlPiUgbGVmdF9qb2luKGRmX2dlbmRlcikNCmBgYA0KDQoNCiMjIFRpbWUgKGNhcmVlciBhZ2UpDQoNCmBgYHtyfQ0KZGZfcHBmJHRpbWUgPC0gZGZfcHBmJHB1Yl95ZWFyIC0gZGZfcHBmJHBoZF95ZWFyDQoNCmRmX3BwZiRjb3ZpZCA8LSBhcy5udW1lcmljKGRmX3BwZiRwdWJfeWVhcj09MjAyMCB8IGRmX3BwZiRwdWJfeWVhcj09MjAyMSkNCmRmX3BwZiRjb3ZpZDIwMjAgPC0gYXMubnVtZXJpYyhkZl9wcGYkcHViX3llYXI9PTIwMjApDQpkZl9wcGYkY292aWQyMDIxIDwtIGFzLm51bWVyaWMoZGZfcHBmJHB1Yl95ZWFyPT0yMDIxKQ0KDQpkZl9wcGYkYWdlMjUgPC0gYXMubnVtZXJpYyhkZl9wcGYkcGhkX3llYXIgPiAyMDEwKQ0KZGZfcHBmJGFnZTI1XzIgPC0gYXMubnVtZXJpYyhkZl9wcGYkcGhkX3llYXIgPiAyMDE1KQ0KDQpkZl9wcGYkcGhkX3llYXIwIDwtIGRmX3BwZiRwaGRfeWVhciAtIDE5OTANCg0KZGZfcHBmJHN0ZW0gPC0gaWZlbHNlKChkZl9wcGYkZmllbGQgPT0gIkJpb2xvZ2ljYWwgYW5kIEhlYWx0aCBTY2llbmNlcyIgfA0KICAgICAgICAgICAgICAgICAgICAgIGRmX3BwZiRmaWVsZCA9PSAiUGh5c2ljYWwgYW5kIE1hdGhlbWF0aWNhbCBTY2llbmNlcyIgfCANCiAgICAgICAgICAgICAgICAgICAgICBkZl9wcGYkZmllbGQgPT0gICJFbmdpbmVlcmluZyIgfCANCiAgICAgICAgICAgICAgICAgICAgICBkZl9wcGYkZmllbGQgPT0gIkFncmljdWx0dXJhbCBTY2llbmNlcyIpLCAiU1RFTS1NIiwgaWZlbHNlKGRmX3BwZiRmaWVsZCA9PSAibWlzc2luZyIsICJtaXNzaW5nIiwgIk5PTi1TVEVNLU0iKSkNCg0KZGZfcHBmJGV0aG5pY2l0eSA8LSBhcy5mYWN0b3IoZGZfcHBmJGV0aG5pY2l0eSkNCmRmX3BwZiRldGhuaWNpdHkgPC0gcmVsZXZlbChkZl9wcGYkZXRobmljaXR5LCAyKQ0KI2xldmVscyhkZl9wcGYkZXRobmljaXR5KQ0KDQpkZl9wcGYkbXVsdGlkaXNjIDwtIDEgLSAoZGZfcHBmJGhlYWx0aF9kb21haW5eMiArICBkZl9wcGYkbGlmZV9kb21haW5eMiArIGRmX3BwZiRwaHlzaWNhbF9kb21haW5eMiArZGZfcHBmJHNvY2lhbF9kb21haW5eMikNCmBgYA0KDQotLS0gIA0KDQojIFJvYnVzdG5lc3MgY2hlY2tzICAgDQoNCiMjIE1vZGVsIDIgc2VwYXJhdGUgcGVyIGRvbWFpbg0KDQojIyMgU3RyaWN0IHNlbGVjdGlvbiAgDQoNCkkgYW0gY3VycmVudGx5IG1ha2luZyBzdHJpY3Qgc2VsZWN0aW9ucyBvbiBkb21haW4uIE5hbWVseSwgYXV0aG9ycyB3aG8gb25seSBwdWJsaXNoIGluIGEgc3BlY2lmaWMgZG9tYWluLiBBIGRpZmZlcmVudCBzdHJhdGVneSB3b3VsZCBiZSB0byB1c2UgPi41IGFzIGNyaXRlcmlhIG9yIGNsYXNzaWZ5aW5nIHNjaG9sYXJzIGJhc2VkIG9uIGhpZ2hlc3Qgc2NvcmUgYWNyb3NzIHRoZSBkb21haW5zLiANCg0KYGBge3IsIGV2YWwgPSBGQUxTRX0NCmRmMyA8LSBkZl9wcGZbLGMoIm5wdWJzIiwgIm5wdWJzX2EiLCAibnB1YnNfZmlyc3RfYSIsICJucHVic19sYXN0X2EiICwgInRpbWUiLCAiaWQiLCAiY292aWQiLCAiY292aWQyMDIwIiwgImNvdmlkMjAyMSIsICJnZW5kZXIyIiwgInBoZF95ZWFyMCIsICJldGhuaWNpdHkiLCAidW5pIiwgImhlYWx0aF9kb21haW4iLCAibGlmZV9kb21haW4iLCAicGh5c2ljYWxfZG9tYWluIiwgInNvY2lhbF9kb21haW4iKV0NCmRmMyA8LSBuYS5vbWl0KGRmMykNCg0Ka25vdHM1IDwtIHF1YW50aWxlKGRmMyR0aW1lLCBwcm9icz1zZXEoMCwxLDAuMjUpKVsyOjRdDQpjb248LWdhbWxzcy5jb250cm9sKCBuLmN5YyA9IDE1MCkNCg0KDQpkZjNfZDEgPC0gZGYzW2RmMyRoZWFsdGhfZG9tYWluID09IDEsXQ0KZGYzX2QyIDwtIGRmM1tkZjMkbGlmZV9kb21haW4gPT0gMSxdDQpkZjNfZDMgPC0gZGYzW2RmMyRwaHlzaWNhbF9kb21haW4gPT0gMSxdDQpkZjNfZDQgPC0gZGYzW2RmMyRzb2NpYWxfZG9tYWluID09IDEsXQ0KDQptMl9kMSA8LSBnYW1sc3MobnB1YnMgfiBiU3BsaW5lKHRpbWUsIGtub3RzPWtub3RzNSxkZj0zKSArIHBoZF95ZWFyMCArIGNvdmlkICsgZ2VuZGVyMiArIGV0aG5pY2l0eSArIHVuaSArIGNvdmlkKmdlbmRlcjIsIGRhdGEgPSBkZjNfZDEsIGZhbWlseSA9IEJOQiwgY29udHJvbD1jb24pDQpmc2F2ZShtMl9kMSwgIm0yX2QxIikNCnNtMl9kMSA8LSBzdW1tYXJ5KG0yX2QxKQ0KZnNhdmUoc20yX2QxLCAic20yX2QxIikNCg0KbTJfZDIgPC0gZ2FtbHNzKG5wdWJzIH4gYlNwbGluZSh0aW1lLCBrbm90cz1rbm90czUsZGY9MykgKyBwaGRfeWVhcjAgKyBjb3ZpZCArIGdlbmRlcjIgKyBldGhuaWNpdHkgKyB1bmkgKyBjb3ZpZCpnZW5kZXIyLCBkYXRhID0gZGYzX2QyLCBmYW1pbHkgPSBCTkIsIGNvbnRyb2w9Y29uKQ0KZnNhdmUobTJfZDIsICJtMl9kMiIpDQpzbTJfZDIgPC0gc3VtbWFyeShtMl9kMikNCmZzYXZlKHNtMl9kMiwgInNtMl9kMiIpDQoNCm0yX2QzIDwtIGdhbWxzcyhucHVicyB+IGJTcGxpbmUodGltZSwga25vdHM9a25vdHM1LGRmPTMpICsgcGhkX3llYXIwICsgY292aWQgKyBnZW5kZXIyICsgZXRobmljaXR5ICsgdW5pICsgY292aWQqZ2VuZGVyMiwgZGF0YSA9IGRmM19kMywgZmFtaWx5ID0gQk5CLCBjb250cm9sPWNvbikNCmZzYXZlKG0yX2QzLCAibTJfZDMiKQ0Kc20yX2QzIDwtIHN1bW1hcnkobTJfZDMpDQpmc2F2ZShzbTJfZDMsICJzbTJfZDMiKQ0KDQptMl9kNCA8LSBnYW1sc3MobnB1YnMgfiBiU3BsaW5lKHRpbWUsIGtub3RzPWtub3RzNSxkZj0zKSArIHBoZF95ZWFyMCArIGNvdmlkICsgZ2VuZGVyMiArIGV0aG5pY2l0eSArIHVuaSArIGNvdmlkKmdlbmRlcjIsIGRhdGEgPSBkZjNfZDQsIGZhbWlseSA9IEJOQiwgY29udHJvbD1jb24pDQpmc2F2ZShtMl9kNCwgIm0yX2Q0IikNCnNtMl9kNCA8LSBzdW1tYXJ5KG0yX2Q0KQ0KZnNhdmUoc20yX2Q0LCAic20yX2Q0IikNCg0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0Kc20yX2QxIDwtIGZsb2FkKCIuL2RhdGEvcHJvY2Vzc2VkL3NtMl9kMV8yMDI0MDgxNS5yZGEiKQ0Kc20yX2QyIDwtIGZsb2FkKCIuL2RhdGEvcHJvY2Vzc2VkL3NtMl9kMl8yMDI0MDgxNS5yZGEiKQ0Kc20yX2QzIDwtIGZsb2FkKCIuL2RhdGEvcHJvY2Vzc2VkL3NtMl9kM18yMDI0MDgxNS5yZGEiKQ0Kc20yX2Q0IDwtIGZsb2FkKCIuL2RhdGEvcHJvY2Vzc2VkL3NtMl9kNF8yMDI0MDgxNS5yZGEiKQ0KYGBgDQoNCg0KYGBge3J9DQpuYW1lcyA8LSBjKCJJbnRlcmNlcHQ6IG11IiwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpMSIsDQoiYlNwbGluZSh0aW1lLCBrbm90cyA9IGtub3RzNSwgZGYgPSAzKTIiICwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpMyIsDQoiYlNwbGluZSh0aW1lLCBrbm90cyA9IGtub3RzNSwgZGYgPSAzKTQiICwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpNSIsDQoiYlNwbGluZSh0aW1lLCBrbm90cyA9IGtub3RzNSwgZGYgPSAzKTYiICwNCiJQaEQtY29ob3J0IiAsICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIkNPVklELTE5IHllYXJzIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQoiZ2VuZGVyOiB3b21lbiIsICJnZW5kZXI6IG5vIGZpcnN0IG5hbWUiLCAiZ2VuZGVyOiBtaXNzaW5nIiwNCiJldGhuaWNpdHk6IG1pbm9yaXR5IEkiLCAiZXRobmljaXR5OiBtaW5vcml0eSBJSSIsICJldGhuaWNpdHk6IG1pc3NpbmciLA0KICJ1bml2ZXJzaXR5OiBMVSIsICJ1bml2ZXJzaXR5OiBSVSIsICJ1bml2ZXJzaXR5OiBSVUciLCAidW5pdmVyc2l0eTogVFVFIiwgInVuaXZlcnNpdHk6IFRJIiwgInVuaXZlcnNpdHk6IFVNIiAsICJ1bml2ZXJzaXR5OiBVVCIsICJ1bml2ZXJzaXR5OiBVVSIsICJ1bml2ZXJzaXR5OiBVdkEiLCAidW5pdmVyc2l0eTogVlUiLCAidW5pdmVyc2l0eTogV1VSIiwNCiJDT1ZJRCp3b21lbiIgICwgICAgICAgICAgICAgICAgICANCiJDT1ZJRCpubyBmaXJzdCBuYW1lIiAgLCAgICAgICAgICANCiJDT1ZJRCptaXNzaW5nIiAgICwgICAgICAgICAgICAgICAgDQoiSW50ZXJjZXB0OiBzaWdtYSIgLCAgICAgICAgICAgICAgICAgICAgICAgICAgDQoiSW50ZXJjZXB0OiBudSIgICkgIA0Kcm93bmFtZXMoc20yX2QxKSA8LSBuYW1lcw0KDQogIG5hbWVzIDwtIGMoIkludGVyY2VwdDogbXUiLA0KImJTcGxpbmUodGltZSwga25vdHMgPSBrbm90czUsIGRmID0gMykxIiwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpMiIgLA0KImJTcGxpbmUodGltZSwga25vdHMgPSBrbm90czUsIGRmID0gMykzIiwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpNCIgLA0KImJTcGxpbmUodGltZSwga25vdHMgPSBrbm90czUsIGRmID0gMyk1IiwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpNiIgLA0KIlBoRC1jb2hvcnQiICwgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQoiQ09WSUQtMTkgeWVhcnMiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiJnZW5kZXI6IHdvbWVuIiwgImdlbmRlcjogbm8gZmlyc3QgbmFtZSIsICJnZW5kZXI6IG1pc3NpbmciLA0KImV0aG5pY2l0eTogbWlub3JpdHkgSSIsICJldGhuaWNpdHk6IG1pbm9yaXR5IElJIiwgImV0aG5pY2l0eTogbWlzc2luZyIsDQogInVuaXZlcnNpdHk6IExVIiwgInVuaXZlcnNpdHk6IFJVIiwgInVuaXZlcnNpdHk6IFJVRyIsICJ1bml2ZXJzaXR5OiBVTSIgLCAidW5pdmVyc2l0eTogVVQiLCAidW5pdmVyc2l0eTogVVUiLCAidW5pdmVyc2l0eTogVXZBIiwgInVuaXZlcnNpdHk6IFZVIiwgInVuaXZlcnNpdHk6IFdVUiIsDQoiQ09WSUQqd29tZW4iICAsICAgICAgICAgICAgICAgICAgDQoiQ09WSUQqbm8gZmlyc3QgbmFtZSIgICwgICAgICAgICAgDQoiQ09WSUQqbWlzc2luZyIgICAsICAgICAgICAgICAgICAgIA0KIkludGVyY2VwdDogc2lnbWEiICwgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIkludGVyY2VwdDogbnUiICApICAgIA0Kcm93bmFtZXMoc20yX2QyKSA8LSBuYW1lcw0KDQpuYW1lcyA8LSBjKCJJbnRlcmNlcHQ6IG11IiwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpMSIsDQoiYlNwbGluZSh0aW1lLCBrbm90cyA9IGtub3RzNSwgZGYgPSAzKTIiICwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpMyIsDQoiYlNwbGluZSh0aW1lLCBrbm90cyA9IGtub3RzNSwgZGYgPSAzKTQiICwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpNSIsDQoiYlNwbGluZSh0aW1lLCBrbm90cyA9IGtub3RzNSwgZGYgPSAzKTYiICwNCiJQaEQtY29ob3J0IiAsICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KIkNPVklELTE5IHllYXJzIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQoiZ2VuZGVyOiB3b21lbiIsICJnZW5kZXI6IG5vIGZpcnN0IG5hbWUiLCAiZ2VuZGVyOiBtaXNzaW5nIiwNCiJldGhuaWNpdHk6IG1pbm9yaXR5IEkiLCAiZXRobmljaXR5OiBtaW5vcml0eSBJSSIsICJldGhuaWNpdHk6IG1pc3NpbmciLA0KICJ1bml2ZXJzaXR5OiBMVSIsICJ1bml2ZXJzaXR5OiBSVSIsICJ1bml2ZXJzaXR5OiBSVUciLCAidW5pdmVyc2l0eTogVFVEIiwgICJ1bml2ZXJzaXR5OiBUVUUiLA0KInVuaXZlcnNpdHk6IFVNIiAsICJ1bml2ZXJzaXR5OiBVVCIsICJ1bml2ZXJzaXR5OiBVVSIsICJ1bml2ZXJzaXR5OiBVdkEiLCAidW5pdmVyc2l0eTogVlUiLCAidW5pdmVyc2l0eTogV1VSIiwNCiJDT1ZJRCp3b21lbiIgICwgICAgICAgICAgICAgICAgICANCiJDT1ZJRCpubyBmaXJzdCBuYW1lIiAgLCAgICAgICAgICANCiJDT1ZJRCptaXNzaW5nIiAgICwgICAgICAgICAgICAgICAgDQoiSW50ZXJjZXB0OiBzaWdtYSIgLCAgICAgICAgICAgICAgICAgICAgICAgICAgDQoiSW50ZXJjZXB0OiBudSIgICkgICAgDQpyb3duYW1lcyhzbTJfZDMpIDwtIG5hbWVzDQoNCm5hbWVzIDwtIGMoIkludGVyY2VwdDogbXUiLA0KImJTcGxpbmUodGltZSwga25vdHMgPSBrbm90czUsIGRmID0gMykxIiwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpMiIgLA0KImJTcGxpbmUodGltZSwga25vdHMgPSBrbm90czUsIGRmID0gMykzIiwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpNCIgLA0KImJTcGxpbmUodGltZSwga25vdHMgPSBrbm90czUsIGRmID0gMyk1IiwNCiJiU3BsaW5lKHRpbWUsIGtub3RzID0ga25vdHM1LCBkZiA9IDMpNiIgLA0KIlBoRC1jb2hvcnQiICwgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQoiQ09WSUQtMTkgeWVhcnMiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiJnZW5kZXI6IHdvbWVuIiwgImdlbmRlcjogbm8gZmlyc3QgbmFtZSIsICJnZW5kZXI6IG1pc3NpbmciLA0KImV0aG5pY2l0eTogbWlub3JpdHkgSSIsICJldGhuaWNpdHk6IG1pbm9yaXR5IElJIiwgImV0aG5pY2l0eTogbWlzc2luZyIsDQogInVuaXZlcnNpdHk6IExVIiwgInVuaXZlcnNpdHk6IFJVIiwgInVuaXZlcnNpdHk6IFJVRyIsICJ1bml2ZXJzaXR5OiBUVUQiLCAgInVuaXZlcnNpdHk6IFRVRSIsICJ1bml2ZXJzaXR5OiBUSSIsDQoidW5pdmVyc2l0eTogVU0iICwgInVuaXZlcnNpdHk6IFVUIiwgInVuaXZlcnNpdHk6IFVVIiwgInVuaXZlcnNpdHk6IFV2QSIsICJ1bml2ZXJzaXR5OiBWVSIsICJ1bml2ZXJzaXR5OiBXVVIiLA0KIkNPVklEKndvbWVuIiAgLCAgICAgICAgICAgICAgICAgIA0KIkNPVklEKm5vIGZpcnN0IG5hbWUiICAsICAgICAgICAgIA0KIkNPVklEKm1pc3NpbmciICAgLCAgICAgICAgICAgICAgICANCiJJbnRlcmNlcHQ6IHNpZ21hIiAsICAgICAgICAgICAgICAgICAgICAgICAgICANCiJJbnRlcmNlcHQ6IG51IiAgKSAgDQpyb3duYW1lcyhzbTJfZDQpIDwtIG5hbWVzDQoNCiAgICAgICAgICAgICAgICAgICAgIA0KZnNob3dkZihzbTJfZDEpDQpmc2hvd2RmKHNtMl9kMikNCmZzaG93ZGYoc20yX2QzKQ0KZnNob3dkZihzbTJfZDQpDQpgYGANCg0KIyMgRml4ZWQgZWZmZWN0cyBjYXJlZXIgYWdlIGFuZCBwZXJzb24gaWQNCg0KYGBge3J9DQpkZjMgPC0gZGZfcHBmWyxjKCJucHVicyIsICJucHVic19hIiwgIm5wdWJzX2ZpcnN0X2EiLCAibnB1YnNfbGFzdF9hIiAsICJ0aW1lIiwgInB1Yl95ZWFyIiwgImlkIiwgImNvdmlkIiwgImNvdmlkMjAyMCIsICJjb3ZpZDIwMjEiLCAiZ2VuZGVyMiIsICJwaGRfeWVhcjAiLCAicGhkX3llYXIiLCAiZXRobmljaXR5IiwgInVuaSIsICJsaWZlX2RvbWFpbiIsICJwaHlzaWNhbF9kb21haW4iLCAic29jaWFsX2RvbWFpbiIpXQ0KZGYzIDwtIG5hLm9taXQoZGYzKQ0KDQpkZjMkbG9nX25wdWJzIDwtIGxvZyhkZjMkbnB1YnMgKyAxKQ0KbV9mZSA8LSBmZW9scyhsb2dfbnB1YnMgfiAxICsgY292aWQgKyBpKGdlbmRlcjIsIGNvdmlkLCByZWYgPSBjKCJtZW4iKSkgfCBpZCArIHRpbWUsIGRhdGEgPSBkZjMpDQpmc2hvd2RmKHN1bW1hcnkobV9mZSkkY29lZnRhYmxlKQ0KYGBgDQpCYXNlZCBvbiB0aGlzIG1vZGVsbGluZyBzdHJhdGVneSB3ZSB3b3VsZCBjb25jbHVkZSB0aGF0IHdvbWVuIHdlcmUgc2lnbmlmaWNhbnRseSBsZXNzIG5lZ2F0aXZlbHkgaW1wYWN0ZWQgYnkgQ09WSUQtMTkgd2l0aCByZXNwZWN0IHRvIHRoZWlyIGFic29sdXRlIG51bWJlciBvZiB5ZWFybHkgYXJ0aWNsZXMuIA0KDQoNCg0KYGBge3IsIGVjaG89RkFMU0UsIGV2YWw9RkFMU0V9DQojUGxheWluZyBhcm91bmQgd2l0aCBESUQNCiNkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImt5bGVidXR0cy9kaWRpbXB1dGF0aW9uIikNCmxpYnJhcnkoZGlkaW1wdXRhdGlvbikNCmxpYnJhcnkoZml4ZXN0KQ0KbGlicmFyeShnZ3Bsb3QyKQ0KDQojIExvYWQgRGF0YSBmcm9tIGRpZDJzIHBhY2thZ2UNCmRhdGEoImRmX2hldCIsIHBhY2thZ2UgPSAiZGlkaW1wdXRhdGlvbiIpDQpsb2FkKGRmX2hldCkNCg0KIyBTdGF0aWMNCnN0YXRpYyA8LSBkaWRfaW1wdXRhdGlvbihkYXRhID0gZGZfaGV0LCB5bmFtZSA9ICJkZXBfdmFyIiwgZ25hbWUgPSAiZyIsIHRuYW1lID0gInllYXIiLCBpZG5hbWUgPSAidW5pdCIpDQoNCmVzIDwtIGRpZF9pbXB1dGF0aW9uKA0KICBkYXRhID0gZGZfaGV0LCB5bmFtZSA9ICJkZXBfdmFyIiwgZ25hbWUgPSAiZyIsDQogIHRuYW1lID0gInllYXIiLCBpZG5hbWUgPSAidW5pdCIsDQogICMgZXZlbnQtc3R1ZHkNCiAgaG9yaXpvbiA9IFRSVUUNCikNCg0KDQp0YWJsZShkZjMkZ2VuZGVyMikNCiNyZW1vdmUgbWlzc2luZyBnZW5kZXINCmRmM19zZWwgPC0gZGYzW2RmMyRnZW5kZXIyID09ICJtZW4iIHwgZGYzJGdlbmRlcjIgPT0gIndvbWVuIiwgXQ0KZGYzX3NlbCR3b21lbiA8LSBpZmVsc2UoZGYzX3NlbCRnZW5kZXIyID09ICJ3b21lbiIsIDEsIDApDQojbWFrZSB0cmVhdG1lbnQgdmFyDQpkZjNfc2VsJHRyZWF0IDwtIGRmM19zZWwkcHViX3llYXI+MjAxOQ0KZGYzX3NlbCR0cmVhdCA8LSBkZjNfc2VsJGNvdmlkDQoNCiNtYWtlIGdyb3VwIHZhcg0KZGYzX3NlbCRncm91cCA8LSAyMDIwIC0gZGYzX3NlbCRwaGRfeWVhcg0KDQpzdGF0aWNfcCA8LSBkaWRfaW1wdXRhdGlvbihkYXRhID0gZGYzX3NlbCwgeW5hbWUgPSAibG9nX25wdWJzIiwgZ25hbWUgPSAiZ3JvdXAiLCB0bmFtZSA9ICJ0aW1lIiwgaWRuYW1lID0gImlkIikNCnN0YXRpY19wDQpybShzdGF0aWNfcCkNCg0KI2NvbXBhcmUgd2l0aCB0d293YXkgRkUNCm1fZmUgPC0gZmVvbHMobG9nX25wdWJzIH4gMSArIHRyZWF0IHwgaWQgKyB0aW1lLCBkYXRhID0gZGYzX3NlbCkNCmZzaG93ZGYoc3VtbWFyeShtX2ZlKSRjb2VmdGFibGUpDQoNCg0KZXMgPC0gZGlkX2ltcHV0YXRpb24oDQogIGRhdGEgPSBkZjNfc2VsLCB5bmFtZSA9ICJsb2dfbnB1YnMiLCBnbmFtZSA9ICJncm91cCIsDQogIHRuYW1lID0gInRpbWUiLCBpZG5hbWUgPSAiaWQiLA0KICAjIGV2ZW50LXN0dWR5DQogIGhvcml6b24gPSBUUlVFLCBwcmV0cmVuZHMgPSBUUlVFDQopDQoNCmVzDQoNCg0KI29rYXksIG5vdyB3aXRoIHB1Yl95ZWFyIGFzIHRpbWUgdmFyLiANCmRmM19zZWwkZ3JvdXAgPC0gMjAyMCAjd2Ugb25seSBoYXZlIG9uZSBncm91cA0Kc3RhdGljX3AgPC0gZGlkX2ltcHV0YXRpb24oZGF0YSA9IGRmM19zZWwsIHluYW1lID0gImxvZ19ucHVicyIsIGduYW1lID0gImdyb3VwIiwgdG5hbWUgPSAicHViX3llYXIiLCBpZG5hbWUgPSAiaWQiKQ0Kc3RhdGljX3AgI2RvZXMgbm90IHdvcmsNCnJtKHN0YXRpY19wKQ0KDQpgYGANCg0KDQojIyBUYWJsZSA0DQoNClN0YXlpbmcgY2xvc2UgdG8gbW9kZWxsaW5nIHN0cmF0ZWd5IG9mIEBtYWRzZW4yMDIyLg0KDQpXZSBkbyBub3QgdXNlIHllYXIgb2YgZmlyc3QgcHViIHRvIGRlZmluZSBjYXJlZXIgYWdlIGJ1dCBwaGRfeWVhcg0KDQpgYGB7cn0NCmRmMyA8LSBkZl9wcGZbLGMoIm5wdWJzIiwgIm5wdWJzX2EiLCAibnB1YnNfZmlyc3RfYSIsICJucHVic19sYXN0X2EiICwgInRpbWUiLCAicHViX3llYXIiLCAiaWQiLCAiY292aWQiLCAiY292aWQyMDIwIiwgImNvdmlkMjAyMSIsICJnZW5kZXIyIiwgInBoZF95ZWFyIiwgInBoZF95ZWFyMCIsICJldGhuaWNpdHkiLCAidW5pIiwgImxpZmVfZG9tYWluIiwgInBoeXNpY2FsX2RvbWFpbiIsICJzb2NpYWxfZG9tYWluIildDQoNCmRmMyRsb2dfbnB1YnNfYSA8LSBsb2coZGYzJG5wdWJzX2EgKyAxKQ0KDQpkZjNfbWlkIDwtIGRmM1tkZjMkcGhkX3llYXIgPT0gMjAwOCB8IGRmMyRwaGRfeWVhciA9PSAyMDA5IHwgZGYzJHBoZF95ZWFyID09IDIwMTAsXQ0KZGYzX2Vhcmx5IDwtIGRmM1tkZjMkcGhkX3llYXIgPT0gMjAxNCB8IGRmMyRwaGRfeWVhciA9PSAyMDE1IHwgZGYzJHBoZF95ZWFyID09IDIwMTYsXQ0KDQojcmVtb3ZlIG1pc3NpbmdzIG9uIGdlbmRlcg0KZGYzX2Vhcmx5IDwtIGRmM19lYXJseVtkZjNfZWFybHkkZ2VuZGVyMiA9PSAibWVuIiB8IGRmM19lYXJseSRnZW5kZXIyID09ICJ3b21lbiIsIF0NCmRmM19taWQgPC0gZGYzX21pZFtkZjNfbWlkJGdlbmRlcjIgPT0gIm1lbiIgfCBkZjNfbWlkJGdlbmRlcjIgPT0gIndvbWVuIiwgXQ0KDQpkZjNfZWFybHkkd29tZW4gPC0gaWZlbHNlKGRmM19lYXJseSRnZW5kZXIyID09ICJ3b21lbiIsIDEsIDApDQpkZjNfbWlkJHdvbWVuIDwtIGlmZWxzZShkZjNfbWlkJGdlbmRlcjIgPT0gIndvbWVuIiwgMSwgMCkNCmBgYCAgDQoNCiMjIyBvYnNlcnZhdGlvbnMNCg0KYGBge3IsIHJlc3VsdHM9J2hvbGQnfQ0KcHJpbnQoIk5fcGVyc29ucyAoZWFybHkgY2FyZWVyKSIpDQpsZW5ndGgodW5pcXVlKGRmM19lYXJseSRpZCkpDQpwcmludCgiTl9vYnNlcnZhdGlvbnMgKGVhcmx5IGNhcmVlcikiKQ0KbnJvdyhkZjNfZWFybHkpDQoNCnByaW50KCJOX3BlcnNvbnMgKG1pZCBjYXJlZXIpIikNCmxlbmd0aCh1bmlxdWUoZGYzX21pZCRpZCkpDQpwcmludCgiTl9vYnNlcnZhdGlvbnMgKG1pZCBjYXJlZXIpIikNCm5yb3coZGYzX21pZCkNCg0KYGBgDQoNCg0KYGBge3J9DQptX2ZlX2UgPC0gZmVvbHMobG9nX25wdWJzX2EgfiAxICsgaShwdWJfeWVhciwgd29tZW4sIHJlZiA9ICIyMDE5IikgfCBpZCArIHB1Yl95ZWFyLCBkYXRhID0gZGYzX2Vhcmx5KQ0KbV9mZV9tIDwtIGZlb2xzKGxvZ19ucHVic19hIH4gMSArIGkocHViX3llYXIsIHdvbWVuLCByZWYgPSAiMjAxOSIpIHwgaWQgKyBwdWJfeWVhciwgZGF0YSA9IGRmM19taWQpDQpgYGANCg0KDQoNCg0KDQojIyMgZml0IG1lYXN1cmVzIA0KDQpgYGB7cn0NCnIyIDwtIGMoZml4ZXN0OjpyMihtX2ZlX2UsICJyMiIpLCBmaXhlc3Q6OnIyKG1fZmVfbSwgInIyIikpICNvdmVyYWwgcjINCndyMiA8LSBjKGZpeGVzdDo6cjIobV9mZV9lLCAid3IyIiksIGZpeGVzdDo6cjIobV9mZV9tLCAid3IyIikpICN3aXRoaW4gcjINCg0KZGZfZml0c3Q0IDwtIGRhdGEuZnJhbWUocjI9cjIsIHdyMj13cjIpDQojZnNhdmUoZGZfZml0c3Q0LCAiZGZfZml0c3Q0IikNCmBgYA0KDQoNCmBgYHtyfQ0Kc21mZWUgPC0gYXMuZGF0YS5mcmFtZShjb2VmdGFibGUobV9mZV9lKSkNCnNtZmVlJG5hbWVzIDwtIHJvd25hbWVzKHNtZmVlKQ0Kc21mZW0gPC0gYXMuZGF0YS5mcmFtZShjb2VmdGFibGUobV9mZV9tKSkNCnNtZmVtJG5hbWVzIDwtIHJvd25hbWVzKHNtZmVtKQ0KcmVzIDwtIHJpZ2h0X2pvaW4oc21mZWUsIHNtZmVtLCBieSA9ICJuYW1lcyIpDQpyZXMgPC0gcmVzW29yZGVyKHJlcyRuYW1lcyksXQ0KDQpyZXMgPC0gcmVzWywgLWMoMyw4KV0NCnJlcyA8LSByZXNbLCBjKDQsMTozLCA1OjcpXQ0KcmVzJG5hbWVzIDwtIGMoInllYXIyMDA5KndvbWVuIiwNCiAgICAgICAgICAgICAgICJ5ZWFyMjAxMCp3b21lbiIsDQogICAgICAgICAgICAgICAieWVhcjIwMTEqd29tZW4iLA0KICAgICAgICAgICAgICAgInllYXIyMDEyKndvbWVuIiwNCiAgICAgICAgICAgICAgICJ5ZWFyMjAxMyp3b21lbiIgLA0KICAgICAgICAgICAgICAgInllYXIyMDE0KndvbWVuIiAsDQogICAgICAgICAgICAgICAieWVhcjIwMTUqd29tZW4iICwNCiAgICAgICAgICAgICAgICJ5ZWFyMjAxNip3b21lbiIsDQogICAgICAgICAgICAgICAgInllYXIyMDE3KndvbWVuIiwgDQogICAgICAgICAgICAgICAgInllYXIyMDE4KndvbWVuIiwNCiAgICAgICAgICAgICAgICAieWVhcjIwMjAqd29tZW4iLA0KICAgICAgICAgICAgICAgICJ5ZWFyMjAyMSp3b21lbiIsDQogICAgICAgICAgICAgICAgInllYXIyMDIyKndvbWVuIikNCg0KY29sbmFtZXMocmVzKSA8LSBhcy5jaGFyYWN0ZXIoMTo3KQ0KIA0KI2ZzYXZlKHJlcywgIlRhYmxlNF9yYXciKQ0KVGFibGU0X3JhdyA8LSByZXMNCmBgYA0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCBldmFsID0gVH0NClRhYmxlNF9yYXcgPC0gZmxvYWQoIi4vZGF0YS9wcm9jZXNzZWQvVGFibGU0X3Jhd18yMDI0MTIyMS5yZGEiKQ0KZGZfZml0c3Q0IDwtIGZsb2FkKCIuL2RhdGEvcHJvY2Vzc2VkL2RmX2ZpdHN0NF8yMDI1MDYwMy5yZGEiKQ0KYGBgDQo8YnI+IA0KYGBge3IgIlRhYmxlXzQiLCB0YWIuY2FwID0gIlRhYmxlIDQuIEZpeGVkLUVmZmVjdHMgbW9kZWwgZm9yIHllYXJseSBhcnRpY2xlIG91dHB1dCAobG9ndHJhbnNmb3JtZWQ7IEdhdXNzaWFuKSIgfQ0KdGFibGU0ZnQgPC0gZmxleHRhYmxlKFRhYmxlNF9yYXcpICAlPiUgYWRkX2hlYWRlcl9yb3codmFsdWVzPWMoIiAiLCByZXAoYygiQiIsICJTLkUuIiwgIlAiKSwgMikpLCB0b3A9RkFMU0UpICU+JSBkZWxldGVfcm93cyhpPTEscGFydD0iaGVhZGVyIikgJT4lIA0KICAjc2V0X2NhcHRpb24oICJGaXhlZC1FZmZlY3RzIG1vZGVsIGZvciB5ZWFybHkgYXJ0aWNsZSBvdXRwdXQgKGxvZ3RyYW5zZm9ybWVkOyBHYXVzc2lhbikiKSAlPiUgDQogIGFkZF9mb290ZXJfbGluZXModmFsdWUgPSBjKCJOb3RlczogXG5Gb3IgcmVhc29ucyBvZiBwYXJzaW1vbnksIHRoZSBlc3RpbWF0ZXMgb2YgdGhlIGZpeGVkIGVmZmVjdHMgYXJlIG5vdCBzaG93bjogc2Nob2xhcnM7IHllYXIuIFNjaG9sYXJzIHdpdGggbWlzc2luZyB2YWx1ZXMgb24gZ2VuZGVyIHdlcmUgcmVtb3ZlZCBmcm9tIHRoZSBhbmFseXNpcy5cbkVhcmx5IGNhcmVlcjogTl9vYnNlcnZhdGlvbnMgOCw4ODg7IE5fcGVyc29ucyAxLDMxMCBcbiBNaWQgY2FyZWVyOiBOX29iZXJ2YXRpb25zIDE0LDk1OTsgTl9wZXJzb25zOiAxLDI0MiIpKSAlPiUNCiAgIGFkZF9oZWFkZXJfcm93KHZhbHVlcyA9IGMoIiAiLCAiZWFybHkgY2FyZWVyIFBoRHMiLCAibWlkLWNhcmVlciBQaERzIiksICBjb2x3aWR0aHMgPSBjKDEsIDMsIDMpKSAlPiUNCiBhbGlnbihpID0gMSwgYWxpZ24gPSAiY2VudGVyIiwgcGFydCA9ICJoZWFkZXIiKSAlPiUNCiAgYWxpZ24oaSA9IDIsIGFsaWduID0gImNlbnRlciIsIHBhcnQgPSAiaGVhZGVyIikgJT4lDQogIGNvbGZvcm1hdF9kb3VibGUoZGlnaXRzID0gMykgJT4lIA0KICBmb250c2l6ZShzaXplID0gOCwgcGFydCA9ICJhbGwiICkgICU+JQ0KICBzZXRfdGFibGVfcHJvcGVydGllcyhvcHRzX3BkZiA9IGxpc3QoYXJyYXlzdHJldGNoID0gMSkpICU+JSAjdG8gYWRqdXN0IHJvdyBoZWlnaHQNCiAgd2lkdGgoaiA9IDEsIHdpZHRoID0gMS4zKSAlPiUNCiAgd2lkdGgoaiA9IDI6NyAsIHdpZHRoID0gLjQpIA0KDQoNCnRhYmxlNGZ0IDwtIGFkZF9ib2R5X3Jvdyh0YWJsZTRmdCwNCiAgdmFsdWVzID0gYygib3ZlcmFsbCBSLXNxdWFyZWQiLHJvdW5kKGRmX2ZpdHN0NCRyMiwzKSksDQogIGNvbHdpZHRocyA9IGMoMSxyZXAoMywgMikpLCB0b3AgPSBGQUxTRQ0KICApICU+JSANCiAgYWxpZ24oaSA9IDE0LCBqPWMoMjo3KSwgYWxpZ24gPSAiY2VudGVyIiwgcGFydCA9ICJib2R5IikgDQoNCnRhYmxlNGZ0IDwtIGFkZF9ib2R5X3Jvdyh0YWJsZTRmdCwNCiAgdmFsdWVzID0gYygid2l0aGluIFItc3F1YXJlZCIsIHJvdW5kKGRmX2ZpdHN0NCR3cjIsMykpLA0KICBjb2x3aWR0aHMgPSBjKDEscmVwKDMsIDIpKSwgdG9wID0gRkFMU0UNCiAgKSAlPiUgDQogIGFsaWduKGkgPSAxNSwgaj1jKDI6NyksIGFsaWduID0gImNlbnRlciIsIHBhcnQgPSAiYm9keSIpIA0KICANCnRhYmxlNGZ0ICAlPiUgDQogIGJvcmRlcl9pbm5lcl9oKGJvcmRlciA9IGZwX2JvcmRlcl9kZWZhdWx0KHdpZHRoID0gMCksIHBhcnQgPSAiYm9keSIpICU+JSANCiAgIGhsaW5lKGkgPSAxMykgDQoNCmBgYCAgDQo8YnI+IA0KDQpCYXNlZCBvbiB0aGlzIG1vZGVsbGluZyBzdHJhdGVneSB3ZSBjb25jbHVkZSB0aGF0IHRoZSBnZW5kZXIgZ2FwcyBpbiBwdWJsaWNhdGlvbiB3ZXJlICpub3QqIG1vcmUgc2V2ZXJlIGZvciB3b21lbiBkdXJpbmcgQ09WSUQtMTkgdGhhbiBpbiBwcmUtIG9yIHBvc3QtQ09WSUQtMTkgeWVhcnMuIA0KDQojIyMgQVRUDQoNCkRhc2hlZCBsaW5lIGlzIGNvdW50ZXJmYWN0dWFsLiANClRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGJsdWUgZGFzaGVkIGxpbmUgYW5kIHRoZSBzb2xpZCBkYXNoZWQgbGluZSBpcyB3aGF0IFtAbWFkc2VuMjAyMl0gaW50ZXJwcmV0IGFzIHRoZSBBVFQuIA0KDQojIyMjIEVhcmx5IGNhcmVlciANCg0KYGBge3IgIkZpZ3VyZV9SUjJhIiAsIGZpZy5jYXAgPSAiRmlndXJlIFJSMmEuIFByZWRpY3RlZCBwdWJsaXNoaW5nIHJhdGVzIGVhcmx5IGNhcmVlciBzY2hvbGFycyJ9DQpkZjNfZWFybHkkcHJlZHMgPC0gZXhwKHByZWRpY3QobV9mZV9lKSAtIDEpDQoNCmRmM19lYXJseV9uZXcgPC0gZGYzX2Vhcmx5DQoNCmRmM19lYXJseV9uZXcgPC0gZGYzX2Vhcmx5X25ldyAlPiUgDQogIG11dGF0ZSh3b21lbiA9IGNhc2Vfd2hlbihwdWJfeWVhciA+IDIwMTggfiAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLmRlZmF1bHQgPSB3b21lbikpDQoNCmRmM19lYXJseV9uZXckcHJlZHMyIDwtIGV4cChwcmVkaWN0KG1fZmVfZSwgbmV3ZGF0YSA9IGRmM19lYXJseV9uZXcpIC0gMSkNCg0KDQpkZjNfZWFybHlfbmV3JHdvbWVuIDwtIGRmM19lYXJseSR3b21lbg0KZGYzX2Vhcmx5X2FnIDwtIGRmM19lYXJseV9uZXcgJT4lIGdyb3VwX2J5KHdvbWVuLCBwdWJfeWVhcikgJT4lIA0KICBzdW1tYXJpc2UoeWhhdF9tZWFuID0gbWVhbihwcmVkcyksDQogICAgICAgICAgICB5aGF0X21lYW5fYyA9IG1lYW4ocHJlZHMyKSkNCg0KYGBgDQo8YnI+IA0KDQojIyMjIE1pZCBjYXJlZXIgIA0KDQpgYGB7ciAiRmlndXJlX1JSMmIiLCBmaWcuY2FwID0gIkZpZ3VyZSBSUjJiLiBQcmVkaWN0ZWQgcHVibGlzaGluZyByYXRlcyBtaWQgY2FyZWVyIHNjaG9sYXJzIn0NCmRmM19taWQkcHJlZHMgPC0gZXhwKHByZWRpY3QobV9mZV9tKSAtIDEpIA0KDQpkZjNfbWlkX25ldyA8LSBkZjNfbWlkDQoNCmRmM19taWRfbmV3IDwtIGRmM19taWRfbmV3ICU+JSANCiAgbXV0YXRlKHdvbWVuID0gY2FzZV93aGVuKHB1Yl95ZWFyID4gMjAxOCB+IDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAuZGVmYXVsdCA9IHdvbWVuKSkNCg0KZGYzX21pZF9uZXckcHJlZHMyIDwtIGV4cChwcmVkaWN0KG1fZmVfbSwgbmV3ZGF0YSA9IGRmM19taWRfbmV3KSAtIDEpDQoNCmRmM19taWRfbmV3JHdvbWVuIDwtIGRmM19taWQkd29tZW4NCmRmM19taWRfYWcgPC0gZGYzX21pZF9uZXcgJT4lIGdyb3VwX2J5KHdvbWVuLCBwdWJfeWVhcikgJT4lIA0KICBzdW1tYXJpc2UoeWhhdF9tZWFuID0gbWVhbihwcmVkcyksDQogICAgICAgICAgICB5aGF0X21lYW5fYyA9IG1lYW4ocHJlZHMyKSkNCg0KDQpgYGANCg0KPGJyPiANCg0KYGBge3J9DQpnZWMgPC0gZ2dwbG90KGRmM19lYXJseV9hZywgYWVzKHg9cHViX3llYXIsIHk9eWhhdF9tZWFuKSkgKyANCiAgZ2VvbV9saW5lKGFlcyhjb2xvcj1hcy5mYWN0b3Iod29tZW4pKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKw0KICBnZW9tX2xpbmUoYWVzKHk9eWhhdF9tZWFuX2MsIGNvbG9yPWFzLmZhY3Rvcih3b21lbikpLCAgc2hvdy5sZWdlbmQgPSBGQUxTRSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKyANCiAgeWxpbSgwLDEuNSkgKyANCiAgeGxhYigieWVhciIpICsgDQogIHlsYWIoInB1YmxpY2F0aW9uIGNvdW50IikgICsNCiB0aGVtZV9taW5pbWFsKCkgKyANCiAgdGhlbWUocGxvdC5jYXB0aW9uPWVsZW1lbnRfdGV4dChoanVzdD0wKSkgKw0KICB0aGVtZShwbG90Lm1hcmdpbiA9IG1hcmdpbih0ID0gMSwgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICByID0gMSwgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiID0gMSwgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsID0gMSwgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml0ID0gImNtIikpDQoNCg0KZ21jIDwtIGdncGxvdChkZjNfbWlkX2FnLCBhZXMoeD1wdWJfeWVhciwgeT15aGF0X21lYW4pKSArIA0KICBnZW9tX2xpbmUoYWVzKGNvbG9yPWFzLmZhY3Rvcih3b21lbikpLCBzaG93LmxlZ2VuZCA9IFRSVUUpICsNCiAgZ2VvbV9saW5lKGFlcyh5PXloYXRfbWVhbl9jLCBjb2xvcj1hcy5mYWN0b3Iod29tZW4pKSwgc2hvdy5sZWdlbmQgPSBGQUxTRSwgbGluZXR5cGUgPSAiZGFzaGVkIikgKyANCiAgeWxpbSgwLDEuNSkgKyANCiAgeGxhYigieWVhciIpICsgDQogIHlsYWIoInB1YmxpY2F0aW9uIGNvdW50IikgICsNCiAgc2NhbGVfY29sb3VyX2Rpc2NyZXRlKG5hbWU9IkdlbmRlciIsIGJyZWFrcz1jKCIwIiwgIjEiKSwgbGFiZWxzPWMoIm1lbiIsICJ3b21lbiIpKSArDQogIHRoZW1lX21pbmltYWwoKSArIA0KICB0aGVtZShwbG90LmNhcHRpb249ZWxlbWVudF90ZXh0KGhqdXN0PTApKSArDQogIHRoZW1lKHBsb3QubWFyZ2luID0gbWFyZ2luKHQgPSAxLCAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHIgPSAxLCAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGIgPSAxLCAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGwgPSAxLCAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuaXQgPSAiY20iKSkNCg0KDQpGaWd1cmVfUlIyIDwtICAgICAgDQogIGdnYXJyYW5nZShnZWMsIGdtYywgbmNvbCA9IDIsIGxhYmVscyA9IGMoImVhcmx5IGNhcmVlciIsICJtaWQgY2FyZWVyIiksIGhqdXN0ID0gYygtMC41LC0wLjUpLCAgbnJvdyA9IDEsICAgICAgDQogIGNvbW1vbi5sZWdlbmQgPSBUUlVFLCBsZWdlbmQgPSAicmlnaHQiKQ0KDQoNCkZpZ3VyZV9SUjIgPC0gYW5ub3RhdGVfZmlndXJlKEZpZ3VyZV9SUjIsDQogICAgICAgICAgICAgICAgYm90dG9tID0gdGV4dF9ncm9iKCJUaGlzIGZpZ3VyZSBzaG93cyB0aGUgKG1lYW4pIHByZWRpY3RlZCBwdWJsaXNoaW5nIHJhdGVzIGZvciBtZW4gYW5kIHdvbWVuIGF1dGhvcnMsIHdpdGggc29saWQgbGluZXMgc2hvd2luZyBcbnRoZSB0cmVuZCBwZXIgZ2VuZGVyLCBhbmQgdGhlIGRhc2hlZCBibHVlIGxpbmUgc2hvd2luZyB0aGUgY291bnRlcmZhY3R1YWwgdHJlbmQgZm9yIHdvbWVuIGlmIHRoZXkgaGFkIHNpbWlsYXIgXG4yMDE54oCTMjAyMiB0cmFqZWN0b3JpZXMgYXMgbWVuLiBUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBkYXNoZWQgYmx1ZSBsaW5lIGFuZCB0aGUgc3RyYWlnaHQgYmx1ZSBsaW5lIGlzIFxuaW50ZXJwcmV0ZWQgYnkgTWFkc2VuIGV0IGFsLiAoMjAyMikgYXMgdGhlIGF2ZXJhZ2UgdHJlYXRtZW50IGVmZmVjdCBmb3Igd29tZW4uIiwgY29sb3IgPSAiYmxhY2siLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBqdXN0ID0gImxlZnQiLCB4ID0gMC4wNSwgeSA9IDEsIHNpemUgPSAxMCwgbGluZWhlaWdodCA9IDEuMCkpDQoNCkZpZ3VyZV9SUjINCg0KI25vdyBmaW5kIGEgd2F5IHRvIHNhdmUgY29ycmVjdGx5DQojIA0KIyB7DQojIHBkZihmaWxlID0gIi4vZGF0YS9wcm9jZXNzZWQvMjAyNTA3MjlGaWd1cmVSUjIucGRmIiwgd2lkdGggPSAxMCwgaGVpZ2h0ID0xMCkNCiMgICBGaWd1cmVfUlIyDQojIH0NCiMgZGV2Lm9mZigpDQojIA0KIyANCiMgew0KIyBwbmcoZmlsZSA9ICIuL2RhdGEvcHJvY2Vzc2VkLzIwMjUwNzI5RmlndXJlUlIyLnBuZyIsIHdpZHRoID0gMTYwMCwgaGVpZ2h0ID0gMTYwMCwgdW5pdHMgPSAicHgiLCByZXMgPSAyMDApDQojICAgRmlndXJlX1JSMg0KIyB9DQojIGRldi5vZmYoKQ0KDQoNCg0KYGBgDQoNCg0KQmFzZWQgb24gdGhlc2UgZmlndXJlIHdlIGNvbmNsdWRlIHRoYXQgdGhlICdBVFQnIGZvciB3b21lbiBpcyBuZWdhdGl2ZSwgd29tZW4gd2VyZSBsZXNzIChuZWdhdGl2ZWx5KSBpbXBhY3RlZCBieSBDT1ZJRC0xOSB0aGFuIG1lbi4gDQoNCi0tLSAgDQo=


Copyright © 2024- Jochem Tolsma