library(tidyverse)
library(targets)
library(lme4)
library(lmtest)  # For log ratio tests
library(performance)
library(modelsummary)
library(scales)
library(janitor)
library(here)

# Generated via random.org
set.seed(9936)

# Load data
# Need to use this withr thing because tar_read() and tar_load() need to see the
# _targets folder in the current directory, but this .Rmd file is in a subfolder
withr::with_dir(here::here(), {
  source(tar_read(plot_funs))
  
  canary <- tar_read(panel_lagged)
})

# Goodness-of-fit measures to include
gm <- tribble(
  ~raw, ~clean, ~fmt,
  "nobs", "Num.Obs.", 3,
  "icc", "ICC", 3
)

Check if multilevel models are warranted

First we can start with a simple null model to see what the effect of country and year is on our outcome (i.e. how much do country and year alone explain the variation in repression?)

m0_pts <- lmer(PTS_lead1 ~ (1 | year) + (1 | gwcode),
               REML = FALSE, data = canary)
m0_lhr <- lmer(latent_hr_mean_lead1 ~ (1 | year) + (1 | gwcode),
               REML = FALSE, data = canary)

We then calculate the intraclass correlation coefficients (ICC) for year and country:

modelsummary(list(m0_pts, m0_lhr),
             estimate = "{estimate}", statistic = NULL,
             group = group + term ~ model,
             gof_map = gm)
Model 1 Model 2
(Intercept) 2.610 0.246
gwcode SD (Intercept) 0.986 1.266
year 0.058 0.208
Residual SD (Observations) 0.605 0.486
Num.Obs. 3779.000 3794.000
ICC 0.727 0.875

These values represent the variation in the outcome variable that can be explained by the country/year structure, which is a ton! For the PTS model, for instance, the ICC is 0.7272, meaning that the random effects structure explains 73% of the variation in PTS.

We can also look at how each of the levels are related to the outcome

performance::icc(m0_pts, by_group = TRUE)
Group ICC
gwcode 0.7247167
year 0.0024885
performance::icc(m0_lhr, by_group = TRUE)
Group ICC
gwcode 0.8517684
year 0.0229567

It looks like pretty much all the variability in PTS is explained at a country level and not at a year level, which makes sense, since there’s probably a ton of autocorrelation in human rights practices within a country, while global human rights levels probably don’t move simultaneously across years.

Just because the bulk of the relative variation is at at the country level doesn’t mean that there isn’t significant variability within countries over time. However, the lagged DV seems to soak up pretty much all year-based variability, so we should really use a multilevel model because the country structure matters a lot when explaining human rights abuses. There aren’t really too many gains in efficiency or predictive power when including (1 | year) though.

Gradually build up the model

Understanding all the different country/year dynamics can get complicated, so John Poe suggests slowly building up the model and inspecting it to see what’s going on.

# First we add the main variable of interest (civil society repression here)
m1 <- lmer(PTS_lead1 ~ v2csreprss + (1 | year) + (1 | gwcode),
           REML = FALSE, data = canary)
modelsummary(list("Null model" = m1),
             group = group + term ~ model,
             coef_omit = "sd__", gof_map = gm)
Null model
(Intercept) 2.834
(0.070)
v2csreprss −0.265
(0.017)
gwcode SD (Intercept) 0.831
year 0.081
Residual SD (Observations) 0.590
Num.Obs. 3779.000
ICC 0.667

On average, increasing civil society repression by a point leads to a decrease of 0.265 points of human rights repression in the following year.

Finally, we can see if adding v2csreprss is an improvement over the null m0_pts model:

lrtest(m0_pts, m1) %>% as_tibble()
#Df LogLik Df Chisq Pr(>Chisq)
4 -3806.965
5 -3695.701 1 222.5279 0

It is! m1 is definitely an improvement over m0_pts (p < 0.001).

Next, we can split civil society repression into its within and between versions and see how that performs and how it changes the results

m2 <- lmer(PTS_lead1 ~ v2csreprss_within + v2csreprss_between +
             (1 | year) + (1 | gwcode),
           REML = FALSE, data = canary)

modelsummary(list("Null model" = m1, "Within/between model" = m2),
             group = group + term ~ model,
             coef_omit = "sd__", gof_map = gm)
Null model Within/between model
(Intercept) 2.834 2.978 group
(0.070) (0.077)
v2csreprss −0.265
(0.017)
v2csreprss_within −0.242
(0.018)
v2csreprss_between −0.435
(0.048)

On average, a one-unit increase beyond a country’s average level of civil society repression (i.e. the within-country effect) is associated with a 0.242 point decrease in overall repression the following year

Also, the v2csreprss_between coefficient can be interpreted somehow, but I’m not 100% sure how. (I think something like “as a country’s average civil society repression increases, general repression worsens by 0.435” or something).

And we can check if m2 is an improvement over m1 (it is!):

lrtest(m1, m2) %>% as_tibble()
#Df LogLik Df Chisq Pr(>Chisq)
5 -3695.701
6 -3688.881 1 13.63967 0.0002215

Thus…

So, using a Mundlak within/between split of time-varying covariates is warranted, as is using a country/year random effects structure. Woot.

BUT for the sake of computational efficiency, we omit the within/between split. It takes 30-120 minutes to run one within/between model, and running dozens can take all day. The predictive results are nearly identical to models without the split, and since we’re more interested in prediction than in individual coefficient effects, we don’t need to wait hours for the same results we’d get with the original non-demeaned values.

Interpretation reminders

NB: We ultimately don’t use this within/between difference since the random effects within/between models take forever to run and provide no improvement over the more basic models, but I’ll keep this here as a reminder to future me in future projects:

I always forget how to interpret these dang within/between coefficients in REWB models, so here’s a reminder:

  • “Within” coefficients show what happens as you move up and down from the average level.
    • Template = increasing 1 unit of x above the average in a typical country is associated with a β change in y
  • “Between” coefficients show what happens as you move the whole average up. They’re trickier (and less important) to interpret. This post explains more, along with Bell, Fairbrother, and Jones (2018).
LS0tCnRpdGxlOiAiTW9kZWxpbmcgY2hvaWNlcyIKYXV0aG9yOiAiU3VwYXJuYSBDaGF1ZGhyeSBhbmQgQW5kcmV3IEhlaXNzIgpkYXRlOiAiTGFzdCBydW46IGByIGZvcm1hdChTeXMudGltZSgpLCAnJUYnKWAiCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZm9sZGluZzogc2hvdwplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGNvbnNvbGUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShrbml0cikKbGlicmFyeShrYWJsZUV4dHJhKQprbml0X3ByaW50LmRhdGEuZnJhbWUgPC0gZnVuY3Rpb24oeCwgLi4uKSB7CiAgcmVzIDwtIHBhc3RlKGMoJycsICcnLCBrYWJsZV9zdHlsaW5nKGthYmxlKHgsIGJvb2t0YWJzID0gVFJVRSkpKSwgY29sbGFwc2UgPSAnXG4nKQogIGFzaXNfb3V0cHV0KHJlcykKfQoKcmVnaXN0ZXJTM21ldGhvZCgia25pdF9wcmludCIsICJkYXRhLmZyYW1lIiwga25pdF9wcmludC5kYXRhLmZyYW1lKQpyZWdpc3RlclMzbWV0aG9kKCJrbml0X3ByaW50IiwgImdyb3VwZWRfZGYiLCBrbml0X3ByaW50LmRhdGEuZnJhbWUpCgprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLnJldGluYSA9IDMsCiAgICAgICAgICAgICAgICAgICAgICB0aWR5Lm9wdHMgPSBsaXN0KHdpZHRoLmN1dG9mZiA9IDEyMCksICAjIEZvciBjb2RlCiAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zKHdpZHRoID0gOTApLCAgIyBGb3Igb3V0cHV0CiAgICAgICAgICAgICAgICAgICAgICBmaWcuYXNwID0gMC42MTgsIGZpZy53aWR0aCA9IDcsIAogICAgICAgICAgICAgICAgICAgICAgZmlnLmFsaWduID0gImNlbnRlciIsIG91dC53aWR0aCA9ICI4NSUiKQoKb3B0aW9ucyhkcGx5ci5zdW1tYXJpc2UuaW5mb3JtID0gRkFMU0UsCiAgICAgICAga25pdHIua2FibGUuTkEgPSAiIikKYGBgCgpgYGB7ciBsb2FkLWxpYnJhcmllcy1kYXRhLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0YXJnZXRzKQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkobG10ZXN0KSAgIyBGb3IgbG9nIHJhdGlvIHRlc3RzCmxpYnJhcnkocGVyZm9ybWFuY2UpCmxpYnJhcnkobW9kZWxzdW1tYXJ5KQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShqYW5pdG9yKQpsaWJyYXJ5KGhlcmUpCgojIEdlbmVyYXRlZCB2aWEgcmFuZG9tLm9yZwpzZXQuc2VlZCg5OTM2KQoKIyBMb2FkIGRhdGEKIyBOZWVkIHRvIHVzZSB0aGlzIHdpdGhyIHRoaW5nIGJlY2F1c2UgdGFyX3JlYWQoKSBhbmQgdGFyX2xvYWQoKSBuZWVkIHRvIHNlZSB0aGUKIyBfdGFyZ2V0cyBmb2xkZXIgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5LCBidXQgdGhpcyAuUm1kIGZpbGUgaXMgaW4gYSBzdWJmb2xkZXIKd2l0aHI6OndpdGhfZGlyKGhlcmU6OmhlcmUoKSwgewogIHNvdXJjZSh0YXJfcmVhZChwbG90X2Z1bnMpKQogIAogIGNhbmFyeSA8LSB0YXJfcmVhZChwYW5lbF9sYWdnZWQpCn0pCgojIEdvb2RuZXNzLW9mLWZpdCBtZWFzdXJlcyB0byBpbmNsdWRlCmdtIDwtIHRyaWJibGUoCiAgfnJhdywgfmNsZWFuLCB+Zm10LAogICJub2JzIiwgIk51bS5PYnMuIiwgMywKICAiaWNjIiwgIklDQyIsIDMKKQpgYGAKCiMgQ2hlY2sgaWYgbXVsdGlsZXZlbCBtb2RlbHMgYXJlIHdhcnJhbnRlZAoKRmlyc3Qgd2UgY2FuIHN0YXJ0IHdpdGggYSBzaW1wbGUgbnVsbCBtb2RlbCB0byBzZWUgd2hhdCB0aGUgZWZmZWN0IG9mIGNvdW50cnkgYW5kIHllYXIgaXMgb24gb3VyIG91dGNvbWUgKGkuZS4gaG93IG11Y2ggZG8gY291bnRyeSBhbmQgeWVhciBhbG9uZSBleHBsYWluIHRoZSB2YXJpYXRpb24gaW4gcmVwcmVzc2lvbj8pCgpgYGB7ciBudWxsLW1vZGVsc30KbTBfcHRzIDwtIGxtZXIoUFRTX2xlYWQxIH4gKDEgfCB5ZWFyKSArICgxIHwgZ3djb2RlKSwKICAgICAgICAgICAgICAgUkVNTCA9IEZBTFNFLCBkYXRhID0gY2FuYXJ5KQptMF9saHIgPC0gbG1lcihsYXRlbnRfaHJfbWVhbl9sZWFkMSB+ICgxIHwgeWVhcikgKyAoMSB8IGd3Y29kZSksCiAgICAgICAgICAgICAgIFJFTUwgPSBGQUxTRSwgZGF0YSA9IGNhbmFyeSkKYGBgCgpXZSB0aGVuIGNhbGN1bGF0ZSB0aGUgaW50cmFjbGFzcyBjb3JyZWxhdGlvbiBjb2VmZmljaWVudHMgKElDQykgZm9yIHllYXIgYW5kIGNvdW50cnk6CgpgYGB7ciBpY2MtbW9kZWxzfQptb2RlbHN1bW1hcnkobGlzdChtMF9wdHMsIG0wX2xociksCiAgICAgICAgICAgICBlc3RpbWF0ZSA9ICJ7ZXN0aW1hdGV9Iiwgc3RhdGlzdGljID0gTlVMTCwKICAgICAgICAgICAgIGdyb3VwID0gZ3JvdXAgKyB0ZXJtIH4gbW9kZWwsCiAgICAgICAgICAgICBnb2ZfbWFwID0gZ20pCmBgYAoKVGhlc2UgdmFsdWVzIHJlcHJlc2VudCB0aGUgdmFyaWF0aW9uIGluIHRoZSBvdXRjb21lIHZhcmlhYmxlIHRoYXQgY2FuIGJlIGV4cGxhaW5lZCBieSB0aGUgY291bnRyeS95ZWFyIHN0cnVjdHVyZSwgd2hpY2ggaXMgYSAqdG9uKiEgRm9yIHRoZSBQVFMgbW9kZWwsIGZvciBpbnN0YW5jZSwgdGhlIElDQyBpcyBgciByb3VuZChwZXJmb3JtYW5jZTo6aWNjKG0wX3B0cykkSUNDX2FkanVzdGVkLCA0KWAsIG1lYW5pbmcgdGhhdCB0aGUgcmFuZG9tIGVmZmVjdHMgc3RydWN0dXJlIGV4cGxhaW5zIGByIHBlcmNlbnQocGVyZm9ybWFuY2U6OmljYyhtMF9wdHMpJElDQ19hZGp1c3RlZClgIG9mIHRoZSB2YXJpYXRpb24gaW4gUFRTLgoKV2UgY2FuIGFsc28gbG9vayBhdCBob3cgZWFjaCBvZiB0aGUgbGV2ZWxzIGFyZSByZWxhdGVkIHRvIHRoZSBvdXRjb21lCgpgYGB7ciBpY2MtbW9kZWxzLWJ5LWdyb3VwfQpwZXJmb3JtYW5jZTo6aWNjKG0wX3B0cywgYnlfZ3JvdXAgPSBUUlVFKQpwZXJmb3JtYW5jZTo6aWNjKG0wX2xociwgYnlfZ3JvdXAgPSBUUlVFKQpgYGAKCkl0IGxvb2tzIGxpa2UgcHJldHR5IG11Y2ggYWxsIHRoZSB2YXJpYWJpbGl0eSBpbiBQVFMgaXMgZXhwbGFpbmVkIGF0IGEgY291bnRyeSBsZXZlbCBhbmQgbm90IGF0IGEgeWVhciBsZXZlbCwgd2hpY2ggbWFrZXMgc2Vuc2UsIHNpbmNlIHRoZXJlJ3MgcHJvYmFibHkgYSB0b24gb2YgYXV0b2NvcnJlbGF0aW9uIGluIGh1bWFuIHJpZ2h0cyBwcmFjdGljZXMgd2l0aGluIGEgY291bnRyeSwgd2hpbGUgZ2xvYmFsIGh1bWFuIHJpZ2h0cyBsZXZlbHMgcHJvYmFibHkgZG9uJ3QgbW92ZSBzaW11bHRhbmVvdXNseSBhY3Jvc3MgeWVhcnMuCgpKdXN0IGJlY2F1c2UgdGhlIGJ1bGsgb2YgdGhlIHJlbGF0aXZlIHZhcmlhdGlvbiBpcyBhdCBhdCB0aGUgY291bnRyeSBsZXZlbCBkb2Vzbid0IG1lYW4gdGhhdCB0aGVyZSBpc24ndCBzaWduaWZpY2FudCB2YXJpYWJpbGl0eSB3aXRoaW4gY291bnRyaWVzIG92ZXIgdGltZS4gSG93ZXZlciwgdGhlIGxhZ2dlZCBEViBzZWVtcyB0byBzb2FrIHVwIHByZXR0eSBtdWNoIGFsbCB5ZWFyLWJhc2VkIHZhcmlhYmlsaXR5LCBzbyB3ZSBzaG91bGQgcmVhbGx5IHVzZSBhIG11bHRpbGV2ZWwgbW9kZWwgYmVjYXVzZSB0aGUgY291bnRyeSBzdHJ1Y3R1cmUgbWF0dGVycyAqYSBsb3QqIHdoZW4gZXhwbGFpbmluZyBodW1hbiByaWdodHMgYWJ1c2VzLiBUaGVyZSBhcmVuJ3QgcmVhbGx5IHRvbyBtYW55IGdhaW5zIGluIGVmZmljaWVuY3kgb3IgcHJlZGljdGl2ZSBwb3dlciB3aGVuIGluY2x1ZGluZyBgKDEgfCB5ZWFyKWAgdGhvdWdoLgoKCiMgR3JhZHVhbGx5IGJ1aWxkIHVwIHRoZSBtb2RlbAoKVW5kZXJzdGFuZGluZyBhbGwgdGhlIGRpZmZlcmVudCBjb3VudHJ5L3llYXIgZHluYW1pY3MgY2FuIGdldCBjb21wbGljYXRlZCwgc28gW0pvaG4gUG9lXShodHRwOi8vd3d3LmpvaG5kYXZpZHBvZS5jb20vKSBzdWdnZXN0cyBzbG93bHkgYnVpbGRpbmcgdXAgdGhlIG1vZGVsIGFuZCBpbnNwZWN0aW5nIGl0IHRvIHNlZSB3aGF0J3MgZ29pbmcgb24uCgpgYGB7ciBiYXNpYy1tb2RlbH0KIyBGaXJzdCB3ZSBhZGQgdGhlIG1haW4gdmFyaWFibGUgb2YgaW50ZXJlc3QgKGNpdmlsIHNvY2lldHkgcmVwcmVzc2lvbiBoZXJlKQptMSA8LSBsbWVyKFBUU19sZWFkMSB+IHYyY3NyZXByc3MgKyAoMSB8IHllYXIpICsgKDEgfCBnd2NvZGUpLAogICAgICAgICAgIFJFTUwgPSBGQUxTRSwgZGF0YSA9IGNhbmFyeSkKbW9kZWxzdW1tYXJ5KGxpc3QoIk51bGwgbW9kZWwiID0gbTEpLAogICAgICAgICAgICAgZ3JvdXAgPSBncm91cCArIHRlcm0gfiBtb2RlbCwKICAgICAgICAgICAgIGNvZWZfb21pdCA9ICJzZF9fIiwgZ29mX21hcCA9IGdtKQpgYGAKCmBgYHtyIG1vZGVsLWRldGFpbHMsIGluY2x1ZGU9RkFMU0V9Cm0xX291dCA8LSBicm9vbS5taXhlZDo6dGlkeShtMSkgJT4lIAogIGZpbHRlcihlZmZlY3QgPT0gImZpeGVkIikgJT4lIAogIG11dGF0ZSh0ZXJtID0gbWFrZV9jbGVhbl9uYW1lcyh0ZXJtKSkgJT4lIAogIHNwbGl0KC4kdGVybSkKCiMgRm9yIGZ1biwgd2UgY2FuIHNlZSB0aGUgZWZmZWN0cyBvZiBzcGVjaWZpYyBjb3VudHJpZXMveWVhcnMgd2l0aCByYW5lZigpCiMgbG1lNDo6cmFuZWYobTEpJGd3Y29kZSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCkgJT4lIGFzX3RpYmJsZSgpCiMgbG1lNDo6cmFuZWYobTEpJHllYXIgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigpICU+JSBhc190aWJibGUoKQpgYGAKCk9uIGF2ZXJhZ2UsIGluY3JlYXNpbmcgY2l2aWwgc29jaWV0eSByZXByZXNzaW9uIGJ5IGEgcG9pbnQgbGVhZHMgdG8gYSBkZWNyZWFzZSBvZiBgciBhYnMocm91bmQobTFfb3V0JHYyY3NyZXByc3MkZXN0aW1hdGUsIDMpKWAgcG9pbnRzIG9mIGh1bWFuIHJpZ2h0cyByZXByZXNzaW9uIGluIHRoZSBmb2xsb3dpbmcgeWVhci4KCkZpbmFsbHksIHdlIGNhbiBzZWUgaWYgYWRkaW5nIGB2MmNzcmVwcnNzYCBpcyBhbiBpbXByb3ZlbWVudCBvdmVyIHRoZSBudWxsIGBtMF9wdHNgIG1vZGVsOgoKYGBge3IgY2hlY2stYWdhaW5zdC1tMH0KbHJ0ZXN0KG0wX3B0cywgbTEpICU+JSBhc190aWJibGUoKQpgYGAKCkl0IGlzISBgbTFgIGlzIGRlZmluaXRlbHkgYW4gaW1wcm92ZW1lbnQgb3ZlciBgbTBfcHRzYCAocCA8IDAuMDAxKS4KCk5leHQsIHdlIGNhbiBzcGxpdCBjaXZpbCBzb2NpZXR5IHJlcHJlc3Npb24gaW50byBpdHMgd2l0aGluIGFuZCBiZXR3ZWVuIHZlcnNpb25zIGFuZCBzZWUgaG93IHRoYXQgcGVyZm9ybXMgYW5kIGhvdyBpdCBjaGFuZ2VzIHRoZSByZXN1bHRzCgpgYGB7ciBtdW5kbGFrLW1vZGVsfQptMiA8LSBsbWVyKFBUU19sZWFkMSB+IHYyY3NyZXByc3Nfd2l0aGluICsgdjJjc3JlcHJzc19iZXR3ZWVuICsKICAgICAgICAgICAgICgxIHwgeWVhcikgKyAoMSB8IGd3Y29kZSksCiAgICAgICAgICAgUkVNTCA9IEZBTFNFLCBkYXRhID0gY2FuYXJ5KQoKbW9kZWxzdW1tYXJ5KGxpc3QoIk51bGwgbW9kZWwiID0gbTEsICJXaXRoaW4vYmV0d2VlbiBtb2RlbCIgPSBtMiksCiAgICAgICAgICAgICBncm91cCA9IGdyb3VwICsgdGVybSB+IG1vZGVsLAogICAgICAgICAgICAgY29lZl9vbWl0ID0gInNkX18iLCBnb2ZfbWFwID0gZ20pCmBgYAoKYGBge3IgbTItZGV0YWlscywgaW5jbHVkZT1GQUxTRX0KbTJfb3V0IDwtIGJyb29tLm1peGVkOjp0aWR5KG0yKSAlPiUgCiAgZmlsdGVyKGVmZmVjdCA9PSAiZml4ZWQiKSAlPiUgCiAgbXV0YXRlKHRlcm0gPSBtYWtlX2NsZWFuX25hbWVzKHRlcm0pKSAlPiUgCiAgc3BsaXQoLiR0ZXJtKQpgYGAKCk9uIGF2ZXJhZ2UsIGEgb25lLXVuaXQgaW5jcmVhc2UgYmV5b25kIGEgY291bnRyeSdzIGF2ZXJhZ2UgbGV2ZWwgb2YgY2l2aWwgc29jaWV0eSByZXByZXNzaW9uIChpLmUuIHRoZSB3aXRoaW4tY291bnRyeSBlZmZlY3QpIGlzIGFzc29jaWF0ZWQgd2l0aCBhIGByIGFicyhyb3VuZChtMl9vdXQkdjJjc3JlcHJzc193aXRoaW4kZXN0aW1hdGUsIDMpKWAgcG9pbnQgZGVjcmVhc2UgaW4gb3ZlcmFsbCByZXByZXNzaW9uIHRoZSBmb2xsb3dpbmcgeWVhcgoKQWxzbywgdGhlIGB2MmNzcmVwcnNzX2JldHdlZW5gIGNvZWZmaWNpZW50IGNhbiBiZSBpbnRlcnByZXRlZCBzb21laG93LCBidXQgSSdtIG5vdCAxMDAlIHN1cmUgaG93LiAoSSB0aGluayBzb21ldGhpbmcgbGlrZSAiYXMgYSBjb3VudHJ5J3MgYXZlcmFnZSBjaXZpbCBzb2NpZXR5IHJlcHJlc3Npb24gaW5jcmVhc2VzLCBnZW5lcmFsIHJlcHJlc3Npb24gd29yc2VucyBieSBgciBhYnMocm91bmQobTJfb3V0JHYyY3NyZXByc3NfYmV0d2VlbiRlc3RpbWF0ZSwgMykpYCIgb3Igc29tZXRoaW5nKS4KCkFuZCB3ZSBjYW4gY2hlY2sgaWYgYG0yYCBpcyBhbiBpbXByb3ZlbWVudCBvdmVyIGBtMWAgKGl0IGlzISk6CgpgYGB7ciBjaGVjay1hZ2FpbnN0LW0xfQpscnRlc3QobTEsIG0yKSAlPiUgYXNfdGliYmxlKCkKYGBgCgojIFRodXPigKYKClNvLCB1c2luZyBhIE11bmRsYWsgd2l0aGluL2JldHdlZW4gc3BsaXQgb2YgdGltZS12YXJ5aW5nIGNvdmFyaWF0ZXMgaXMgd2FycmFudGVkLCBhcyBpcyB1c2luZyBhIGNvdW50cnkveWVhciByYW5kb20gZWZmZWN0cyBzdHJ1Y3R1cmUuIFdvb3QuCgpCVVQgZm9yIHRoZSBzYWtlIG9mIGNvbXB1dGF0aW9uYWwgZWZmaWNpZW5jeSwgd2Ugb21pdCB0aGUgd2l0aGluL2JldHdlZW4gc3BsaXQuIEl0IHRha2VzIDMwLTEyMCBtaW51dGVzIHRvIHJ1biBvbmUgd2l0aGluL2JldHdlZW4gbW9kZWwsIGFuZCBydW5uaW5nIGRvemVucyBjYW4gdGFrZSBhbGwgZGF5LiBUaGUgcHJlZGljdGl2ZSByZXN1bHRzIGFyZSBuZWFybHkgaWRlbnRpY2FsIHRvIG1vZGVscyB3aXRob3V0IHRoZSBzcGxpdCwgYW5kIHNpbmNlIHdlJ3JlIG1vcmUgaW50ZXJlc3RlZCBpbiBwcmVkaWN0aW9uIHRoYW4gaW4gaW5kaXZpZHVhbCBjb2VmZmljaWVudCBlZmZlY3RzLCB3ZSBkb24ndCBuZWVkIHRvIHdhaXQgaG91cnMgZm9yIHRoZSBzYW1lIHJlc3VsdHMgd2UnZCBnZXQgd2l0aCB0aGUgb3JpZ2luYWwgbm9uLWRlbWVhbmVkIHZhbHVlcy4gCgojIyBJbnRlcnByZXRhdGlvbiByZW1pbmRlcnMKCk5COiBXZSB1bHRpbWF0ZWx5IGRvbid0IHVzZSB0aGlzIHdpdGhpbi9iZXR3ZWVuIGRpZmZlcmVuY2Ugc2luY2UgdGhlIHJhbmRvbSBlZmZlY3RzIHdpdGhpbi9iZXR3ZWVuIG1vZGVscyB0YWtlIGZvcmV2ZXIgdG8gcnVuIGFuZCBwcm92aWRlIG5vIGltcHJvdmVtZW50IG92ZXIgdGhlIG1vcmUgYmFzaWMgbW9kZWxzLCBidXQgSSdsbCBrZWVwIHRoaXMgaGVyZSBhcyBhIHJlbWluZGVyIHRvIGZ1dHVyZSBtZSBpbiBmdXR1cmUgcHJvamVjdHM6CgpJIGFsd2F5cyBmb3JnZXQgaG93IHRvIGludGVycHJldCB0aGVzZSBkYW5nIHdpdGhpbi9iZXR3ZWVuIGNvZWZmaWNpZW50cyBpbiBSRVdCIG1vZGVscywgc28gaGVyZSdzIGEgcmVtaW5kZXI6CgotICJXaXRoaW4iIGNvZWZmaWNpZW50cyBzaG93IHdoYXQgaGFwcGVucyBhcyB5b3UgbW92ZSB1cCBhbmQgZG93biBmcm9tIHRoZSBhdmVyYWdlIGxldmVsLgogIC0gVGVtcGxhdGUgPSBpbmNyZWFzaW5nIDEgdW5pdCBvZiBgeGAgYWJvdmUgdGhlIGF2ZXJhZ2UgaW4gYSB0eXBpY2FsIGNvdW50cnkgaXMgYXNzb2NpYXRlZCB3aXRoIGEgzrIgY2hhbmdlIGluIGB5YAotICJCZXR3ZWVuIiBjb2VmZmljaWVudHMgc2hvdyB3aGF0IGhhcHBlbnMgYXMgeW91IG1vdmUgdGhlIHdob2xlIGF2ZXJhZ2UgdXAuIFRoZXkncmUgdHJpY2tpZXIgKGFuZCBsZXNzIGltcG9ydGFudCkgdG8gaW50ZXJwcmV0LiBbVGhpcyBwb3N0XShodHRwczovL3N0YXRpc3RpY2FsaG9yaXpvbnMuY29tL2JldHdlZW4td2l0aGluLWNvbnRleHR1YWwtZWZmZWN0cykgZXhwbGFpbnMgbW9yZSwgYWxvbmcgd2l0aCBbQmVsbCwgRmFpcmJyb3RoZXIsIGFuZCBKb25lcyAoMjAxOCldKGh0dHBzOi8vZG9pLm9yZy8xMC4xMDA3L3MxMTEzNS0wMTgtMDgwMi14KS4K