library(tidyverse)
library(haven)
library(lme4)
library(broom)
library(broom.mixed)
library(emmeans)
library(modelsummary)
library(kableExtra)
library(patchwork)
library(here)

ssq <- read_stata(here("data", "Final.9.26.2016.dta"))

coef_lookup <- tribble(
  ~raw, ~clean,
  "wingos", "Women's INGO linkages",
  "whrnoposmgoldtotal", "Shaming",
  "wingos:whrnoposmgoldtotal", "Women's INGO linkages × Shaming",
  "cedaw_rat_1", "CEDAW",
  "log_gdp", "GDP",
  "log_pop", "Population",
  "polity2", "Polity",
  "overallglobalizationindex", "Globalization",
  "(Intercept)", "Constant"
)

coef_mapping <- coef_lookup$clean %>% 
  set_names(coef_lookup$raw)

gof_mapping_probit <- tribble(
  ~raw, ~clean, ~fmt,
  "logLik", "Log likelihood", 3,
  "nobs", "Observations", 0
)

gof_mapping_ols <- tribble(
  ~raw, ~clean, ~fmt,
  "adj.r.squared", "R²", 2,
  "nobs", "Observations", 0
)

Replication data

Replication data and Stata code for this paper is available at Sam Bell’s website.

Table 2

Effect of women’s INGO linkages, human rights shaming, and their interaction on the probability that a country is a source of (1) prostitution trafficking and (2) any kind of trafficking

Original results

Original table 2 from @BellBanks:2018

Figure 1: Original table 2 from Bell and Banks (2018)

Original Stata code

use "Final.9.26.2016.dta", clear

xtset ccode year

xtprobit f_psource_di wingos whrnoposmgoldtotal wingos_shaming cedaw_rat_1 log_gdp log_pop polity2 overallglobalizationindex, re
xtprobit f_source wingos whrnoposmgoldtotal wingos_shaming cedaw_rat_1  log_gdp log_pop  polity2 overallglobalizationindex, re

Replicated models

Using lme4::glmer() works, but there are all sorts of warnings about unidentifiability because of scaling issues, as well as convergence issues.

table2_1 <- glmer(f_psource_di ~ wingos + whrnoposmgoldtotal + 
                    (wingos * whrnoposmgoldtotal) + 
                    cedaw_rat_1 + log_gdp + log_pop + polity2 + 
                    overallglobalizationindex + (1 | ccode),
                  data = ssq, 
                  family = binomial(link = "probit"))

table2_2 <- glmer(f_source ~ wingos + whrnoposmgoldtotal + 
                    (wingos * whrnoposmgoldtotal) + 
                    cedaw_rat_1 + log_gdp + log_pop + polity2 + 
                    overallglobalizationindex + (1 | ccode),
                  data = ssq,
                  family = binomial(link = "probit"))
modelsummary(list("Sex Work" = table2_1, "All" = table2_2), 
             coef_map = coef_mapping, gof_map = gof_mapping_probit, fmt = 4,
             stars = TRUE, notes = c("SEs in parentheses"))
Sex Work All
Women’s INGO linkages 0.0023 0.0062
(0.0117) (0.0119)
Shaming −0.0022 0.0146
(0.0213) (0.0255)
Women’s INGO linkages × Shaming −0.0005 −0.0007
(0.0004) (0.0005)
CEDAW −1.8598 −1.2812
(1.4889) (1.9523)
GDP −2.7069*** −2.9043***
(0.4406) (0.6369)
Population 0.3029 0.5444*
(0.2195) (0.2708)
Polity 0.1177* 0.2029**
(0.0485) (0.0627)
Globalization 0.1370*** 0.0650
(0.0348) (0.0436)
Constant 11.0696* 13.2870*
(4.4853) (5.4300)
Log likelihood −249.497 −146.283
Observations 776 776
+ p < 0.1, * p < 0.05, ** p < 0.01, *** p < 0.001
SEs in parentheses

Replicated marginal effects

Original figure 1 from @BellBanks:2018

Figure 2: Original figure 1 from Bell and Banks (2018)

ame_a <- table2_1 %>% 
  emtrends(~ wingos,
           var = "whrnoposmgoldtotal",
           at = list(wingos = seq(0, 107, 1)))

plot_ame_a <- ame_a %>% 
  as_tibble() %>% 
  ggplot(aes(x = wingos)) +
  geom_hline(yintercept = 0, size = 0.5, color = "#FF4136") +
  geom_ribbon(aes(ymin = asymp.LCL, ymax = asymp.UCL),
              alpha = 0.05) +
  geom_line(aes(y = whrnoposmgoldtotal.trend)) +
  geom_line(aes(y = asymp.LCL), linetype = "99") +
  geom_line(aes(y = asymp.UCL), linetype = "99") +
  labs(x = "Women's INGO presence", y = "Marginal effect of shaming",
       title = "Panel A: Sex Work Trafficking Source") +
  coord_cartesian(ylim = c(-0.1, 0.1)) +
  theme_bw() +
  theme(panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.minor.y = element_blank())


ame_b <- table2_1 %>% 
  emtrends(~ whrnoposmgoldtotal,
           var = "wingos",
           at = list(whrnoposmgoldtotal = seq(0, 107, 1)))

plot_ame_b <- ame_b %>% 
  as_tibble() %>% 
  ggplot(aes(x = whrnoposmgoldtotal)) +
  geom_hline(yintercept = 0, size = 0.5, color = "#FF4136") +
  geom_ribbon(aes(ymin = asymp.LCL, ymax = asymp.UCL),
              alpha = 0.05) +
  geom_line(aes(y = wingos.trend)) +
  geom_line(aes(y = asymp.LCL), linetype = "99") +
  geom_line(aes(y = asymp.UCL), linetype = "99") +
  labs(x = "Women's INGO shaming", y = "Marginal effect of INGO presence",
       title = "Panel B: Sex Work Trafficking Source") +
  coord_cartesian(ylim = c(-0.15, 0.1)) +
  theme_bw() +
  theme(panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.minor.y = element_blank())


ame_c <- table2_2 %>% 
  emtrends(~ wingos,
           var = "whrnoposmgoldtotal",
           at = list(wingos = seq(0, 107, 1)))

plot_ame_c <- ame_c %>% 
  as_tibble() %>% 
  ggplot(aes(x = wingos)) +
  geom_hline(yintercept = 0, size = 0.5, color = "#FF4136") +
  geom_ribbon(aes(ymin = asymp.LCL, ymax = asymp.UCL),
              alpha = 0.05) +
  geom_line(aes(y = whrnoposmgoldtotal.trend)) +
  geom_line(aes(y = asymp.LCL), linetype = "99") +
  geom_line(aes(y = asymp.UCL), linetype = "99") +
  labs(x = "Women's INGO presence", y = "Marginal effect of shaming",
       title = "Panel C: All Trafficking Source") +
  coord_cartesian(ylim = c(-0.15, 0.1)) +
  theme_bw() +
  theme(panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.minor.y = element_blank())


ame_d <- table2_2 %>% 
  emtrends(~ whrnoposmgoldtotal,
           var = "wingos",
           at = list(whrnoposmgoldtotal = seq(0, 107, 1)))

plot_ame_d <- ame_d %>% 
  as_tibble() %>% 
  ggplot(aes(x = whrnoposmgoldtotal)) +
  geom_hline(yintercept = 0, size = 0.5, color = "#FF4136") +
  geom_ribbon(aes(ymin = asymp.LCL, ymax = asymp.UCL),
              alpha = 0.05) +
  geom_line(aes(y = wingos.trend)) +
  geom_line(aes(y = asymp.LCL), linetype = "99") +
  geom_line(aes(y = asymp.UCL), linetype = "99") +
  labs(x = "Women's INGO shaming", y = "Marginal effect of INGO presence",
       title = "Panel D: All Trafficking Source") +
  coord_cartesian(ylim = c(-0.2, 0.1)) +
  theme_bw() +
  theme(panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.minor.y = element_blank())

(plot_ame_a | plot_ame_b) / (plot_ame_c | plot_ame_d)
Replicated figure 1. `emtrends()` apparently struggles with `glmer()` so it's not picking up on the nonlinear changes in AMEs?

Figure 3: Replicated figure 1. emtrends() apparently struggles with glmer() so it’s not picking up on the nonlinear changes in AMEs?

Table 3

Effect of women’s INGO linkages, human rights shaming, and their interaction on the a country’s 3P trafficking index (which ranges from 1–15; higher values = better prosecution, prevention, and protection)

Original results

Original table 3 from @BellBanks:2018

Figure 4: Original table 3 from Bell and Banks (2018)

Original Stata code

use "Final.9.26.2016.dta", clear

xtset ccode year

xtreg f_Overall3P wingos whrnoposmgoldtotal wingos_shaming cedaw_rat_1 log_gdp log_pop polity2 overallglobalizationindex, re

Replicated model

Using lme4::glmer() works and only gives a warning about scaling issues; the model converges.

table3 <- lmer(f_Overall3P ~ wingos + whrnoposmgoldtotal + 
                    (wingos * whrnoposmgoldtotal) + 
                 cedaw_rat_1 + log_gdp + log_pop + polity2 +
                 overallglobalizationindex + (1 | ccode), 
               REML = FALSE,
               data = ssq)
modelsummary(list("Overall 3P Index" = table3), 
             coef_map = coef_mapping, gof_map = gof_mapping_ols, fmt = 4,
             notes = c("SEs in parentheses", 
                       "No stars here because <code>lmer()</code> doesn't output p-values",
                       "No R² here because <code>lmer()</code> doesn't use it (and Stata fakes it)"))
Overall 3P Index
Women’s INGO linkages 0.0176
(0.0062)
Shaming −0.0176
(0.0103)
Women’s INGO linkages × Shaming 0.0002
(0.0002)
CEDAW 1.0144
(0.5793)
GDP −0.2018
(0.1641)
Population 0.1965
(0.1140)
Polity 0.0711
(0.0237)
Globalization 0.0919
(0.0155)
Constant 0.4125
(2.2411)
Observations 901
SEs in parentheses
No stars here because lmer() doesn’t output p-values
No R² here because lmer() doesn’t use it (and Stata fakes it)

Replicated marginal effects

Original figure 2 from @BellBanks:2018

Figure 5: Original figure 2 from Bell and Banks (2018)

ame_tbl3_a <- table3 %>% 
  emtrends(~ whrnoposmgoldtotal,
           var = "wingos",
           at = list(whrnoposmgoldtotal = seq(0, 107, 1)))

plot_ame_tbl3_a <- ame_tbl3_a %>% 
  as_tibble() %>% 
  ggplot(aes(x = whrnoposmgoldtotal)) +
  geom_hline(yintercept = 0, size = 0.5, color = "#FF4136") +
  geom_ribbon(aes(ymin = lower.CL, ymax = upper.CL),
              alpha = 0.05) +
  geom_line(aes(y = wingos.trend)) +
  geom_line(aes(y = lower.CL), linetype = "99") +
  geom_line(aes(y = upper.CL), linetype = "99") +
  labs(x = "Women's INGO shaming", y = "Marginal effect of INGO presence",
       title = "Panel A: 3P index") +
  coord_cartesian(ylim = c(-0.05, 0.1)) +
  theme_bw() +
  theme(panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.minor.y = element_blank())


ame_tbl3_b <- table3 %>% 
  emtrends(~ wingos,
           var = "whrnoposmgoldtotal",
           at = list(wingos = seq(0, 107, 1)))

plot_ame_tbl3_b <- ame_tbl3_b %>% 
  as_tibble() %>% 
  ggplot(aes(x = wingos)) +
  geom_hline(yintercept = 0, size = 0.5, color = "#FF4136") +
  geom_ribbon(aes(ymin = lower.CL, ymax = upper.CL),
              alpha = 0.05) +
  geom_line(aes(y = whrnoposmgoldtotal.trend)) +
  geom_line(aes(y = lower.CL), linetype = "99") +
  geom_line(aes(y = upper.CL), linetype = "99") +
  labs(x = "Women's INGO presence", y = "Marginal effect of shaming",
       title = "Panel B: 3P index") +
  coord_cartesian(ylim = c(-0.05, 0.05)) +
  theme_bw() +
  theme(panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.minor.y = element_blank())

plot_ame_tbl3_a | plot_ame_tbl3_b
Replicated figure 2. This is pretty close!

Figure 6: Replicated figure 2. This is pretty close!

References

Bell, Sam R., and Victoria Banks. 2018. “Women’s Rights Organizations and Human Trafficking.” Social Science Quarterly 99 (1): 362–76. https://doi.org/10.1111/ssqu.12396.
LS0tCnRpdGxlOiAiUmVwbGljYXRpb24gb2YgQmVsbCBhbmQgQmFua3MgKDIwMTgpIgpiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliCmxpbmstY2l0YXRpb25zOiB5ZXMKb3V0cHV0OiAKICBib29rZG93bjo6aHRtbF9kb2N1bWVudDI6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQoKYGBge3IgbGlicmFyaWVzLWRhdGEsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGhhdmVuKQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkoYnJvb20pCmxpYnJhcnkoYnJvb20ubWl4ZWQpCmxpYnJhcnkoZW1tZWFucykKbGlicmFyeShtb2RlbHN1bW1hcnkpCmxpYnJhcnkoa2FibGVFeHRyYSkKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoaGVyZSkKCnNzcSA8LSByZWFkX3N0YXRhKGhlcmUoImRhdGEiLCAiRmluYWwuOS4yNi4yMDE2LmR0YSIpKQoKY29lZl9sb29rdXAgPC0gdHJpYmJsZSgKICB+cmF3LCB+Y2xlYW4sCiAgIndpbmdvcyIsICJXb21lbidzIElOR08gbGlua2FnZXMiLAogICJ3aHJub3Bvc21nb2xkdG90YWwiLCAiU2hhbWluZyIsCiAgIndpbmdvczp3aHJub3Bvc21nb2xkdG90YWwiLCAiV29tZW4ncyBJTkdPIGxpbmthZ2VzIMOXIFNoYW1pbmciLAogICJjZWRhd19yYXRfMSIsICJDRURBVyIsCiAgImxvZ19nZHAiLCAiR0RQIiwKICAibG9nX3BvcCIsICJQb3B1bGF0aW9uIiwKICAicG9saXR5MiIsICJQb2xpdHkiLAogICJvdmVyYWxsZ2xvYmFsaXphdGlvbmluZGV4IiwgIkdsb2JhbGl6YXRpb24iLAogICIoSW50ZXJjZXB0KSIsICJDb25zdGFudCIKKQoKY29lZl9tYXBwaW5nIDwtIGNvZWZfbG9va3VwJGNsZWFuICU+JSAKICBzZXRfbmFtZXMoY29lZl9sb29rdXAkcmF3KQoKZ29mX21hcHBpbmdfcHJvYml0IDwtIHRyaWJibGUoCiAgfnJhdywgfmNsZWFuLCB+Zm10LAogICJsb2dMaWsiLCAiTG9nIGxpa2VsaWhvb2QiLCAzLAogICJub2JzIiwgIk9ic2VydmF0aW9ucyIsIDAKKQoKZ29mX21hcHBpbmdfb2xzIDwtIHRyaWJibGUoCiAgfnJhdywgfmNsZWFuLCB+Zm10LAogICJhZGouci5zcXVhcmVkIiwgIlLCsiIsIDIsCiAgIm5vYnMiLCAiT2JzZXJ2YXRpb25zIiwgMAopCmBgYAoKIyMgUmVwbGljYXRpb24gZGF0YQoKUmVwbGljYXRpb24gZGF0YSBhbmQgU3RhdGEgY29kZSBmb3IgdGhpcyBwYXBlciBpcyBhdmFpbGFibGUgYXQgW1NhbSBCZWxsJ3Mgd2Vic2l0ZV0oaHR0cHM6Ly9zYW1yYmVsbC5jb20vcmVzZWFyY2gpLgoKCiMjIFRhYmxlIDIKCkVmZmVjdCBvZiB3b21lbidzIElOR08gbGlua2FnZXMsIGh1bWFuIHJpZ2h0cyBzaGFtaW5nLCBhbmQgdGhlaXIgaW50ZXJhY3Rpb24gb24gdGhlIHByb2JhYmlsaXR5IHRoYXQgYSBjb3VudHJ5IGlzIGEgc291cmNlIG9mICgxKSBwcm9zdGl0dXRpb24gdHJhZmZpY2tpbmcgYW5kICgyKSBhbnkga2luZCBvZiB0cmFmZmlja2luZwoKIyMjIE9yaWdpbmFsIHJlc3VsdHMKCmBgYHtyIG9yaWdpbmFsLXRhYmxlLTIsIGVjaG89RkFMU0UsIG91dC53aWR0aD0iNzUlIiwgZmlnLmFsaWduPSJjZW50ZXIifQojfCBmaWctY2FwOiAiT3JpZ2luYWwgdGFibGUgMiBmcm9tIEBCZWxsQmFua3M6MjAxOCIKa25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZSgiaW1nIiwgInRhYmxlLTIucG5nIikpCmBgYAoKIyMjIE9yaWdpbmFsIFN0YXRhIGNvZGUKCmBgYHN0YXRhCnVzZSAiRmluYWwuOS4yNi4yMDE2LmR0YSIsIGNsZWFyCgp4dHNldCBjY29kZSB5ZWFyCgp4dHByb2JpdCBmX3Bzb3VyY2VfZGkgd2luZ29zIHdocm5vcG9zbWdvbGR0b3RhbCB3aW5nb3Nfc2hhbWluZyBjZWRhd19yYXRfMSBsb2dfZ2RwIGxvZ19wb3AgcG9saXR5MiBvdmVyYWxsZ2xvYmFsaXphdGlvbmluZGV4LCByZQp4dHByb2JpdCBmX3NvdXJjZSB3aW5nb3Mgd2hybm9wb3NtZ29sZHRvdGFsIHdpbmdvc19zaGFtaW5nIGNlZGF3X3JhdF8xICBsb2dfZ2RwIGxvZ19wb3AgIHBvbGl0eTIgb3ZlcmFsbGdsb2JhbGl6YXRpb25pbmRleCwgcmUKYGBgCgojIyMgUmVwbGljYXRlZCBtb2RlbHMKClVzaW5nIGBsbWU0OjpnbG1lcigpYCB3b3JrcywgYnV0IHRoZXJlIGFyZSBhbGwgc29ydHMgb2Ygd2FybmluZ3MgYWJvdXQgdW5pZGVudGlmaWFiaWxpdHkgYmVjYXVzZSBvZiBzY2FsaW5nIGlzc3VlcywgYXMgd2VsbCBhcyBjb252ZXJnZW5jZSBpc3N1ZXMuCgpgYGB7ciB0YWJsZTItY29kZSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI3wgY2xhc3Muc291cmNlID0gImZvbGQtc2hvdyIKdGFibGUyXzEgPC0gZ2xtZXIoZl9wc291cmNlX2RpIH4gd2luZ29zICsgd2hybm9wb3NtZ29sZHRvdGFsICsgCiAgICAgICAgICAgICAgICAgICAgKHdpbmdvcyAqIHdocm5vcG9zbWdvbGR0b3RhbCkgKyAKICAgICAgICAgICAgICAgICAgICBjZWRhd19yYXRfMSArIGxvZ19nZHAgKyBsb2dfcG9wICsgcG9saXR5MiArIAogICAgICAgICAgICAgICAgICAgIG92ZXJhbGxnbG9iYWxpemF0aW9uaW5kZXggKyAoMSB8IGNjb2RlKSwKICAgICAgICAgICAgICAgICAgZGF0YSA9IHNzcSwgCiAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAicHJvYml0IikpCgp0YWJsZTJfMiA8LSBnbG1lcihmX3NvdXJjZSB+IHdpbmdvcyArIHdocm5vcG9zbWdvbGR0b3RhbCArIAogICAgICAgICAgICAgICAgICAgICh3aW5nb3MgKiB3aHJub3Bvc21nb2xkdG90YWwpICsgCiAgICAgICAgICAgICAgICAgICAgY2VkYXdfcmF0XzEgKyBsb2dfZ2RwICsgbG9nX3BvcCArIHBvbGl0eTIgKyAKICAgICAgICAgICAgICAgICAgICBvdmVyYWxsZ2xvYmFsaXphdGlvbmluZGV4ICsgKDEgfCBjY29kZSksCiAgICAgICAgICAgICAgICAgIGRhdGEgPSBzc3EsCiAgICAgICAgICAgICAgICAgIGZhbWlseSA9IGJpbm9taWFsKGxpbmsgPSAicHJvYml0IikpCmBgYAoKYGBge3IgdGFibGUyLXJlcGxpY2F0aW9uLCB3YXJuaW5nPUZBTFNFfQptb2RlbHN1bW1hcnkobGlzdCgiU2V4IFdvcmsiID0gdGFibGUyXzEsICJBbGwiID0gdGFibGUyXzIpLCAKICAgICAgICAgICAgIGNvZWZfbWFwID0gY29lZl9tYXBwaW5nLCBnb2ZfbWFwID0gZ29mX21hcHBpbmdfcHJvYml0LCBmbXQgPSA0LAogICAgICAgICAgICAgc3RhcnMgPSBUUlVFLCBub3RlcyA9IGMoIlNFcyBpbiBwYXJlbnRoZXNlcyIpKQpgYGAKCgojIyMgUmVwbGljYXRlZCBtYXJnaW5hbCBlZmZlY3RzCgpgYGB7ciBvcmlnaW5hbC1maWd1cmUtMSwgZWNobz1GQUxTRSwgb3V0LndpZHRoPSIxMDAlIiwgZmlnLmFsaWduPSJjZW50ZXIifQojfCBmaWcuY2FwOiAiT3JpZ2luYWwgZmlndXJlIDEgZnJvbSBAQmVsbEJhbmtzOjIwMTgiCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmUoImltZyIsICJmaWd1cmUtMS5wbmciKSkKYGBgCgpgYGB7ciBmaWd1cmUxLXJlcGxpY2F0aW9uLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD03LCBmaWcuYWxpZ249ImNlbnRlciJ9CiN8IGZpZy5jYXA6ICJSZXBsaWNhdGVkIGZpZ3VyZSAxLiBgZW10cmVuZHMoKWAgYXBwYXJlbnRseSBzdHJ1Z2dsZXMgd2l0aCAKI3wgICBgZ2xtZXIoKWAgc28gaXQncyBub3QgcGlja2luZyB1cCBvbiB0aGUgbm9ubGluZWFyIGNoYW5nZXMgaW4gQU1Fcz8iCgphbWVfYSA8LSB0YWJsZTJfMSAlPiUgCiAgZW10cmVuZHMofiB3aW5nb3MsCiAgICAgICAgICAgdmFyID0gIndocm5vcG9zbWdvbGR0b3RhbCIsCiAgICAgICAgICAgYXQgPSBsaXN0KHdpbmdvcyA9IHNlcSgwLCAxMDcsIDEpKSkKCnBsb3RfYW1lX2EgPC0gYW1lX2EgJT4lIAogIGFzX3RpYmJsZSgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSB3aW5nb3MpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgc2l6ZSA9IDAuNSwgY29sb3IgPSAiI0ZGNDEzNiIpICsKICBnZW9tX3JpYmJvbihhZXMoeW1pbiA9IGFzeW1wLkxDTCwgeW1heCA9IGFzeW1wLlVDTCksCiAgICAgICAgICAgICAgYWxwaGEgPSAwLjA1KSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gd2hybm9wb3NtZ29sZHRvdGFsLnRyZW5kKSkgKwogIGdlb21fbGluZShhZXMoeSA9IGFzeW1wLkxDTCksIGxpbmV0eXBlID0gIjk5IikgKwogIGdlb21fbGluZShhZXMoeSA9IGFzeW1wLlVDTCksIGxpbmV0eXBlID0gIjk5IikgKwogIGxhYnMoeCA9ICJXb21lbidzIElOR08gcHJlc2VuY2UiLCB5ID0gIk1hcmdpbmFsIGVmZmVjdCBvZiBzaGFtaW5nIiwKICAgICAgIHRpdGxlID0gIlBhbmVsIEE6IFNleCBXb3JrIFRyYWZmaWNraW5nIFNvdXJjZSIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLTAuMSwgMC4xKSkgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpKQoKCmFtZV9iIDwtIHRhYmxlMl8xICU+JSAKICBlbXRyZW5kcyh+IHdocm5vcG9zbWdvbGR0b3RhbCwKICAgICAgICAgICB2YXIgPSAid2luZ29zIiwKICAgICAgICAgICBhdCA9IGxpc3Qod2hybm9wb3NtZ29sZHRvdGFsID0gc2VxKDAsIDEwNywgMSkpKQoKcGxvdF9hbWVfYiA8LSBhbWVfYiAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHdocm5vcG9zbWdvbGR0b3RhbCkpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBzaXplID0gMC41LCBjb2xvciA9ICIjRkY0MTM2IikgKwogIGdlb21fcmliYm9uKGFlcyh5bWluID0gYXN5bXAuTENMLCB5bWF4ID0gYXN5bXAuVUNMKSwKICAgICAgICAgICAgICBhbHBoYSA9IDAuMDUpICsKICBnZW9tX2xpbmUoYWVzKHkgPSB3aW5nb3MudHJlbmQpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gYXN5bXAuTENMKSwgbGluZXR5cGUgPSAiOTkiKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gYXN5bXAuVUNMKSwgbGluZXR5cGUgPSAiOTkiKSArCiAgbGFicyh4ID0gIldvbWVuJ3MgSU5HTyBzaGFtaW5nIiwgeSA9ICJNYXJnaW5hbCBlZmZlY3Qgb2YgSU5HTyBwcmVzZW5jZSIsCiAgICAgICB0aXRsZSA9ICJQYW5lbCBCOiBTZXggV29yayBUcmFmZmlja2luZyBTb3VyY2UiKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC0wLjE1LCAwLjEpKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgoKYW1lX2MgPC0gdGFibGUyXzIgJT4lIAogIGVtdHJlbmRzKH4gd2luZ29zLAogICAgICAgICAgIHZhciA9ICJ3aHJub3Bvc21nb2xkdG90YWwiLAogICAgICAgICAgIGF0ID0gbGlzdCh3aW5nb3MgPSBzZXEoMCwgMTA3LCAxKSkpCgpwbG90X2FtZV9jIDwtIGFtZV9jICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gd2luZ29zKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIHNpemUgPSAwLjUsIGNvbG9yID0gIiNGRjQxMzYiKSArCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBhc3ltcC5MQ0wsIHltYXggPSBhc3ltcC5VQ0wpLAogICAgICAgICAgICAgIGFscGhhID0gMC4wNSkgKwogIGdlb21fbGluZShhZXMoeSA9IHdocm5vcG9zbWdvbGR0b3RhbC50cmVuZCkpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBhc3ltcC5MQ0wpLCBsaW5ldHlwZSA9ICI5OSIpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBhc3ltcC5VQ0wpLCBsaW5ldHlwZSA9ICI5OSIpICsKICBsYWJzKHggPSAiV29tZW4ncyBJTkdPIHByZXNlbmNlIiwgeSA9ICJNYXJnaW5hbCBlZmZlY3Qgb2Ygc2hhbWluZyIsCiAgICAgICB0aXRsZSA9ICJQYW5lbCBDOiBBbGwgVHJhZmZpY2tpbmcgU291cmNlIikgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygtMC4xNSwgMC4xKSkgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpKQoKCmFtZV9kIDwtIHRhYmxlMl8yICU+JSAKICBlbXRyZW5kcyh+IHdocm5vcG9zbWdvbGR0b3RhbCwKICAgICAgICAgICB2YXIgPSAid2luZ29zIiwKICAgICAgICAgICBhdCA9IGxpc3Qod2hybm9wb3NtZ29sZHRvdGFsID0gc2VxKDAsIDEwNywgMSkpKQoKcGxvdF9hbWVfZCA8LSBhbWVfZCAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHdocm5vcG9zbWdvbGR0b3RhbCkpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBzaXplID0gMC41LCBjb2xvciA9ICIjRkY0MTM2IikgKwogIGdlb21fcmliYm9uKGFlcyh5bWluID0gYXN5bXAuTENMLCB5bWF4ID0gYXN5bXAuVUNMKSwKICAgICAgICAgICAgICBhbHBoYSA9IDAuMDUpICsKICBnZW9tX2xpbmUoYWVzKHkgPSB3aW5nb3MudHJlbmQpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gYXN5bXAuTENMKSwgbGluZXR5cGUgPSAiOTkiKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gYXN5bXAuVUNMKSwgbGluZXR5cGUgPSAiOTkiKSArCiAgbGFicyh4ID0gIldvbWVuJ3MgSU5HTyBzaGFtaW5nIiwgeSA9ICJNYXJnaW5hbCBlZmZlY3Qgb2YgSU5HTyBwcmVzZW5jZSIsCiAgICAgICB0aXRsZSA9ICJQYW5lbCBEOiBBbGwgVHJhZmZpY2tpbmcgU291cmNlIikgKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygtMC4yLCAwLjEpKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgoocGxvdF9hbWVfYSB8IHBsb3RfYW1lX2IpIC8gKHBsb3RfYW1lX2MgfCBwbG90X2FtZV9kKQpgYGAKCgojIyBUYWJsZSAzCgpFZmZlY3Qgb2Ygd29tZW4ncyBJTkdPIGxpbmthZ2VzLCBodW1hbiByaWdodHMgc2hhbWluZywgYW5kIHRoZWlyIGludGVyYWN0aW9uIG9uIHRoZSBhIGNvdW50cnkncyAzUCB0cmFmZmlja2luZyBpbmRleCAod2hpY2ggcmFuZ2VzIGZyb20gMeKAkzE1OyBoaWdoZXIgdmFsdWVzID0gYmV0dGVyIHByb3NlY3V0aW9uLCBwcmV2ZW50aW9uLCBhbmQgcHJvdGVjdGlvbikKCiMjIyBPcmlnaW5hbCByZXN1bHRzCgpgYGB7ciBvcmlnaW5hbC10YWJsZS0zLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9Ijc1JSIsIGZpZy5hbGlnbj0iY2VudGVyIn0KI3wgZmlnLWNhcDogIk9yaWdpbmFsIHRhYmxlIDMgZnJvbSBAQmVsbEJhbmtzOjIwMTgiCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmUoImltZyIsICJ0YWJsZS0zLnBuZyIpKQpgYGAKCiMjIyBPcmlnaW5hbCBTdGF0YSBjb2RlCgpgYGBzdGF0YQp1c2UgIkZpbmFsLjkuMjYuMjAxNi5kdGEiLCBjbGVhcgoKeHRzZXQgY2NvZGUgeWVhcgoKeHRyZWcgZl9PdmVyYWxsM1Agd2luZ29zIHdocm5vcG9zbWdvbGR0b3RhbCB3aW5nb3Nfc2hhbWluZyBjZWRhd19yYXRfMSBsb2dfZ2RwIGxvZ19wb3AgcG9saXR5MiBvdmVyYWxsZ2xvYmFsaXphdGlvbmluZGV4LCByZQpgYGAKCiMjIyBSZXBsaWNhdGVkIG1vZGVsCgpVc2luZyBgbG1lNDo6Z2xtZXIoKWAgd29ya3MgYW5kIG9ubHkgZ2l2ZXMgYSB3YXJuaW5nIGFib3V0IHNjYWxpbmcgaXNzdWVzOyB0aGUgbW9kZWwgY29udmVyZ2VzLgoKYGBge3IgdGFibGUzLWNvZGUsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiN8IGNsYXNzLnNvdXJjZSA9ICJmb2xkLXNob3ciCnRhYmxlMyA8LSBsbWVyKGZfT3ZlcmFsbDNQIH4gd2luZ29zICsgd2hybm9wb3NtZ29sZHRvdGFsICsgCiAgICAgICAgICAgICAgICAgICAgKHdpbmdvcyAqIHdocm5vcG9zbWdvbGR0b3RhbCkgKyAKICAgICAgICAgICAgICAgICBjZWRhd19yYXRfMSArIGxvZ19nZHAgKyBsb2dfcG9wICsgcG9saXR5MiArCiAgICAgICAgICAgICAgICAgb3ZlcmFsbGdsb2JhbGl6YXRpb25pbmRleCArICgxIHwgY2NvZGUpLCAKICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLAogICAgICAgICAgICAgICBkYXRhID0gc3NxKQpgYGAKCmBgYHtyIHRhYmxlMy1yZXBsaWNhdGlvbiwgd2FybmluZz1GQUxTRX0KbW9kZWxzdW1tYXJ5KGxpc3QoIk92ZXJhbGwgM1AgSW5kZXgiID0gdGFibGUzKSwgCiAgICAgICAgICAgICBjb2VmX21hcCA9IGNvZWZfbWFwcGluZywgZ29mX21hcCA9IGdvZl9tYXBwaW5nX29scywgZm10ID0gNCwKICAgICAgICAgICAgIG5vdGVzID0gYygiU0VzIGluIHBhcmVudGhlc2VzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgIk5vIHN0YXJzIGhlcmUgYmVjYXVzZSA8Y29kZT5sbWVyKCk8L2NvZGU+IGRvZXNuJ3Qgb3V0cHV0IHAtdmFsdWVzIiwKICAgICAgICAgICAgICAgICAgICAgICAiTm8gUsKyIGhlcmUgYmVjYXVzZSA8Y29kZT5sbWVyKCk8L2NvZGU+IGRvZXNuJ3QgdXNlIGl0IChhbmQgU3RhdGEgZmFrZXMgaXQpIikpCmBgYAoKCiMjIyBSZXBsaWNhdGVkIG1hcmdpbmFsIGVmZmVjdHMKCmBgYHtyIG9yaWdpbmFsLWZpZ3VyZS0yLCBlY2hvPUZBTFNFLCBvdXQud2lkdGg9Ijc1JSIsIGZpZy5hbGlnbj0iY2VudGVyIn0KI3wgZmlnLmNhcDogIk9yaWdpbmFsIGZpZ3VyZSAyIGZyb20gQEJlbGxCYW5rczoyMDE4Igprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlKCJpbWciLCAiZmlndXJlLTIucG5nIikpCmBgYAoKYGBge3IgZmlndXJlMi1yZXBsaWNhdGlvbiwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9NC41LCBmaWcuYWxpZ249ImNlbnRlciIsIHdhcm5pbmc9RkFMU0V9CiN8IGZpZy5jYXA6ICJSZXBsaWNhdGVkIGZpZ3VyZSAyLiBUaGlzIGlzIHByZXR0eSBjbG9zZSEiCgphbWVfdGJsM19hIDwtIHRhYmxlMyAlPiUgCiAgZW10cmVuZHMofiB3aHJub3Bvc21nb2xkdG90YWwsCiAgICAgICAgICAgdmFyID0gIndpbmdvcyIsCiAgICAgICAgICAgYXQgPSBsaXN0KHdocm5vcG9zbWdvbGR0b3RhbCA9IHNlcSgwLCAxMDcsIDEpKSkKCnBsb3RfYW1lX3RibDNfYSA8LSBhbWVfdGJsM19hICU+JSAKICBhc190aWJibGUoKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gd2hybm9wb3NtZ29sZHRvdGFsKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIHNpemUgPSAwLjUsIGNvbG9yID0gIiNGRjQxMzYiKSArCiAgZ2VvbV9yaWJib24oYWVzKHltaW4gPSBsb3dlci5DTCwgeW1heCA9IHVwcGVyLkNMKSwKICAgICAgICAgICAgICBhbHBoYSA9IDAuMDUpICsKICBnZW9tX2xpbmUoYWVzKHkgPSB3aW5nb3MudHJlbmQpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gbG93ZXIuQ0wpLCBsaW5ldHlwZSA9ICI5OSIpICsKICBnZW9tX2xpbmUoYWVzKHkgPSB1cHBlci5DTCksIGxpbmV0eXBlID0gIjk5IikgKwogIGxhYnMoeCA9ICJXb21lbidzIElOR08gc2hhbWluZyIsIHkgPSAiTWFyZ2luYWwgZWZmZWN0IG9mIElOR08gcHJlc2VuY2UiLAogICAgICAgdGl0bGUgPSAiUGFuZWwgQTogM1AgaW5kZXgiKSArCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKC0wLjA1LCAwLjEpKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgoKYW1lX3RibDNfYiA8LSB0YWJsZTMgJT4lIAogIGVtdHJlbmRzKH4gd2luZ29zLAogICAgICAgICAgIHZhciA9ICJ3aHJub3Bvc21nb2xkdG90YWwiLAogICAgICAgICAgIGF0ID0gbGlzdCh3aW5nb3MgPSBzZXEoMCwgMTA3LCAxKSkpCgpwbG90X2FtZV90YmwzX2IgPC0gYW1lX3RibDNfYiAlPiUgCiAgYXNfdGliYmxlKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHdpbmdvcykpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBzaXplID0gMC41LCBjb2xvciA9ICIjRkY0MTM2IikgKwogIGdlb21fcmliYm9uKGFlcyh5bWluID0gbG93ZXIuQ0wsIHltYXggPSB1cHBlci5DTCksCiAgICAgICAgICAgICAgYWxwaGEgPSAwLjA1KSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gd2hybm9wb3NtZ29sZHRvdGFsLnRyZW5kKSkgKwogIGdlb21fbGluZShhZXMoeSA9IGxvd2VyLkNMKSwgbGluZXR5cGUgPSAiOTkiKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gdXBwZXIuQ0wpLCBsaW5ldHlwZSA9ICI5OSIpICsKICBsYWJzKHggPSAiV29tZW4ncyBJTkdPIHByZXNlbmNlIiwgeSA9ICJNYXJnaW5hbCBlZmZlY3Qgb2Ygc2hhbWluZyIsCiAgICAgICB0aXRsZSA9ICJQYW5lbCBCOiAzUCBpbmRleCIpICsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoLTAuMDUsIDAuMDUpKSArCiAgdGhlbWVfYncoKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpwbG90X2FtZV90YmwzX2EgfCBwbG90X2FtZV90YmwzX2IKYGBgCgoKIyMgUmVmZXJlbmNlcwo=