Set up

Packages

#library
library(tidyverse)
library(data.table)
library(igraph)#for egonetdata
library(furrr)

Import

load(file = "datafiles/data-processed/disaggregated_data/2023-06-12_liss-risk-data.rds")

Custom functions

#create function in which we can distinguish for dyads different spells
#so spell of first time drop, second time, dropped etc. 
# This way we can identify different dyad spells and also add
# how often an alter is already dropped. 

Ftimes_dropped <- function(x) {
  #x = data_list[[1]]
  #select variable that we need to use (in this case dropped)
  y <- x %>%
    select(dropped)
  
  #create empty list to loop over
  y_list <- list()
  
  #initiate loop
  for (i in 1:nrow(y)) {
    #i = 9
    if (i == 1) {
      a <- y[i, ]
      y_list[[i]] <- a
    }
    else {
      a <- y[i, ] + y_list[[i - 1]]
      y_list[[i]] <- a
    }
  }
  
  #reduce to one df
  y <- y_list %>%
    rbindlist() %>%
    rename(times_dropped = dropped) %>%
    mutate(times_dropped_rec = lag(times_dropped))
  
  #add df to group split
  return(cbind(x, y))
}

Repeated Risk Data

With this code we will now create a repeated risk data set. So we can identify how often a person is in the data and in what spell he or she is in.

Step 1: count number of drops per dyad

We first start with creation of such a count variable. This will count the number of dyad spells.

#for every dyad, count the number of drops 
nr_transition <- event_data %>%
  filter(transition == -1) %>%
  group_by(dyad_id) %>%
  count(dyad_id) %>%
  rename(number_transition = n) %>%
  ungroup()

#add the number of transitions to event_data
event_data <- event_data %>%
  left_join(nr_transition, by = "dyad_id")

Step 2: create spell count variable

Now we know the number of dyad spells we can start with our custom function for each dyad. For each dyad it will count the number of spells and for each observation of the dyad it will also note in which spell it is currently in.

#create the variable dropped
#based on transition, when transition is -1, alter is dropped.
data_list <- event_data %>%
  ungroup() %>% 
  mutate(dropped = ifelse(transition == -1, 1, 0)) %>%
  mutate(dropped = ifelse(is.na(dropped), 0, dropped)) %>%
  group_split(dyad_id)

plan(multisession, workers = 6)

data_list <- data_list %>%
  future_map(.f = ~ Ftimes_dropped(.x),
                 .progress = T)


#stop parallel session
plan(sequential)

#reset data to event_data df
repeated_event_data <- data_list %>%
  rbindlist()

#create a new repeated risk dataset
repeated_event_data <- repeated_event_data %>%
  select(!c(range, censor)) %>%
  mutate(
    times_dropped_rec = ifelse(survey_wave == 1, 0, times_dropped_rec),
    dropped = ifelse(is.na(selected), NA, dropped),
    dropped = ifelse(survey_wave < entered_network, NA, dropped),
    times_dropped_rec = ifelse(is.na(selected), NA, times_dropped_rec),
    times_dropped_rec = ifelse(survey_wave < entered_network, NA, times_dropped_rec),
    times_dropped_rec = ifelse(survey_wave == entered_network, 0, times_dropped_rec),
    process_id = paste0(dyad_id, times_dropped_rec)
  ) %>%
  filter(!is.na(dropped))

Step 3: Delete empty observations

We have created a counter for each dyad spell and also created a process id, which identifies the dyad spell. However, right now we also have observations in the data who are dropped and not in the data. These cannot be at the risk of deselection. Hence we need to drop them from the data as reocurrence is not part of study.

## filter out observations in which the dyad_id is not dropped from the network and also not selected
# in this instances the dyad is not at risk of being deselected.
repeated_event_data <- repeated_event_data %>%
  mutate(filter = dropped + selected) %>%
  filter(filter > 0)

Step 4: create a new censor variable.

#create censor variable for process_id
censor_process_id <- repeated_event_data %>%
  select(dyad_id, process_id, survey_wave, dropped, selected) %>%
  group_by(process_id) %>%
  mutate(max_wave = max(survey_wave)) %>%
  mutate(censor = ifelse((max_wave == survey_wave) & (selected == 1), 1, 0)) %>%
  summarize(censor_process = max(censor)) %>%
  ungroup()

#add censor to the data
repeated_event_data <- repeated_event_data %>%
  left_join(censor_process_id, by = "process_id")

Step 5: create a new time variable

We need a new time variable that calculates for every process_id how long it is and for every observation in which period it is of the full time range.

#calculate for every process id how long the process is
process_length <- repeated_event_data %>%
  group_by(process_id) %>%
  count() %>%
  rename(range = n) %>%
  ungroup()

## add the process length to the repeated_data
repeated_event_data <- repeated_event_data %>%
  #select(!range) %>%
  left_join(process_length, by = "process_id")

#create new time variable 
repeated_event_data <- repeated_event_data %>%
  group_by(process_id) %>%
  mutate(time = seq(from = 1, to = max(range))) %>%
  ungroup()

Step 6: create relationship length variable

I also want a variable which denotes how long an alter and an ego know each other. Two variations on this theme: first, calculate the total amount of time between entering the network and the final drop. Second, calculate the total number of times an alter was present in the network.

relationship_length <- repeated_event_data %>% 
  select(nomem_encr, survey_wave, dyad_id, time, entered_network, end_year, dropped) %>%
  filter(dropped == 0) %>% 
  group_by(dyad_id) %>% 
  mutate(length_rel_member = 1:n(),
         length_rel_total = survey_wave - entered_network + 1) %>% 
  ungroup() %>% 
  select(nomem_encr, survey_wave, dyad_id, length_rel_member, length_rel_total)

repeated_event_data <- repeated_event_data %>% 
  left_join(relationship_length, by = c("nomem_encr", "survey_wave", "dyad_id"))


#create a selection of the data
repeated_person_level <- repeated_event_data %>%
  select(process_id, dyad_id, nomem_encr, times_dropped_rec, censor_process, range) %>%
  distinct() %>%
  rename(times_dropped_earlier = times_dropped_rec)

Data export

Export the repeated risk data.

#save event data as 2022-09-02_risk-data.rds
save(repeated_event_data, file = "datafiles/data-processed/disaggregated_data/2023-06-12_liss-repeated-risk-data.rda")

#save person period data
save(repeated_person_level, file = "datafiles/data-processed/disaggregated_data/2023-06-12_liss-repeated-person-level.rda")
LS0tDQp0aXRsZTogJ1JlcGVhdGVkIFJpc2sgRGF0YSBQcmVwZXJhdGlvbicNCmF1dGhvcjogIlRoaWptZW4gSmVyb2Vuc2UiDQpkYXRlOiAiTGFzdCBjb21waWxlZCBvbiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoY2FjaGUgPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgcmVzdWx0cyA9ICJhc2lzIiwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYWxpZ24gPSAiY2VudGVyIikNCmBgYA0KDQojIFNldCB1cA0KDQojIyBQYWNrYWdlcw0KDQpgYGB7ciBsb2FkIGRhdGEgbGlicmFyeX0NCiNsaWJyYXJ5DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZGF0YS50YWJsZSkNCmxpYnJhcnkoaWdyYXBoKSNmb3IgZWdvbmV0ZGF0YQ0KbGlicmFyeShmdXJycikNCmBgYA0KDQojIyBJbXBvcnQgDQoNCmBgYHtyIGRhdGEgaW1wb3J0fQ0KbG9hZChmaWxlID0gImRhdGFmaWxlcy9kYXRhLXByb2Nlc3NlZC9kaXNhZ2dyZWdhdGVkX2RhdGEvMjAyMy0wNi0xMl9saXNzLXJpc2stZGF0YS5yZHMiKQ0KDQpgYGANCg0KIyMgQ3VzdG9tIGZ1bmN0aW9ucw0KDQpgYGB7ciBjdXN0b20gZnVuY3Rpb25zfQ0KDQojY3JlYXRlIGZ1bmN0aW9uIGluIHdoaWNoIHdlIGNhbiBkaXN0aW5ndWlzaCBmb3IgZHlhZHMgZGlmZmVyZW50IHNwZWxscw0KI3NvIHNwZWxsIG9mIGZpcnN0IHRpbWUgZHJvcCwgc2Vjb25kIHRpbWUsIGRyb3BwZWQgZXRjLiANCiMgVGhpcyB3YXkgd2UgY2FuIGlkZW50aWZ5IGRpZmZlcmVudCBkeWFkIHNwZWxscyBhbmQgYWxzbyBhZGQNCiMgaG93IG9mdGVuIGFuIGFsdGVyIGlzIGFscmVhZHkgZHJvcHBlZC4gDQoNCkZ0aW1lc19kcm9wcGVkIDwtIGZ1bmN0aW9uKHgpIHsNCiAgI3ggPSBkYXRhX2xpc3RbWzFdXQ0KICAjc2VsZWN0IHZhcmlhYmxlIHRoYXQgd2UgbmVlZCB0byB1c2UgKGluIHRoaXMgY2FzZSBkcm9wcGVkKQ0KICB5IDwtIHggJT4lDQogICAgc2VsZWN0KGRyb3BwZWQpDQogIA0KICAjY3JlYXRlIGVtcHR5IGxpc3QgdG8gbG9vcCBvdmVyDQogIHlfbGlzdCA8LSBsaXN0KCkNCiAgDQogICNpbml0aWF0ZSBsb29wDQogIGZvciAoaSBpbiAxOm5yb3coeSkpIHsNCiAgICAjaSA9IDkNCiAgICBpZiAoaSA9PSAxKSB7DQogICAgICBhIDwtIHlbaSwgXQ0KICAgICAgeV9saXN0W1tpXV0gPC0gYQ0KICAgIH0NCiAgICBlbHNlIHsNCiAgICAgIGEgPC0geVtpLCBdICsgeV9saXN0W1tpIC0gMV1dDQogICAgICB5X2xpc3RbW2ldXSA8LSBhDQogICAgfQ0KICB9DQogIA0KICAjcmVkdWNlIHRvIG9uZSBkZg0KICB5IDwtIHlfbGlzdCAlPiUNCiAgICByYmluZGxpc3QoKSAlPiUNCiAgICByZW5hbWUodGltZXNfZHJvcHBlZCA9IGRyb3BwZWQpICU+JQ0KICAgIG11dGF0ZSh0aW1lc19kcm9wcGVkX3JlYyA9IGxhZyh0aW1lc19kcm9wcGVkKSkNCiAgDQogICNhZGQgZGYgdG8gZ3JvdXAgc3BsaXQNCiAgcmV0dXJuKGNiaW5kKHgsIHkpKQ0KfQ0KDQoNCg0KYGBgDQoNCg0KIyBSZXBlYXRlZCBSaXNrIERhdGENCg0KV2l0aCB0aGlzIGNvZGUgd2Ugd2lsbCBub3cgY3JlYXRlIGEgcmVwZWF0ZWQgcmlzayBkYXRhIHNldC4gU28gd2UgY2FuIGlkZW50aWZ5IGhvdyBvZnRlbiBhIHBlcnNvbiBpcyBpbiB0aGUgZGF0YSBhbmQgaW4gd2hhdCBzcGVsbCBoZSBvciBzaGUgaXMgaW4uIA0KDQojIyBTdGVwIDE6IGNvdW50IG51bWJlciBvZiBkcm9wcyBwZXIgZHlhZA0KDQpXZSBmaXJzdCBzdGFydCB3aXRoIGNyZWF0aW9uIG9mIHN1Y2ggYSBjb3VudCB2YXJpYWJsZS4gVGhpcyB3aWxsIGNvdW50IHRoZSBudW1iZXIgb2YgZHlhZCBzcGVsbHMuIA0KDQpgYGB7ciByZXBlYXRlZCByaXNrIGRhdGEgMX0NCiNmb3IgZXZlcnkgZHlhZCwgY291bnQgdGhlIG51bWJlciBvZiBkcm9wcyANCm5yX3RyYW5zaXRpb24gPC0gZXZlbnRfZGF0YSAlPiUNCiAgZmlsdGVyKHRyYW5zaXRpb24gPT0gLTEpICU+JQ0KICBncm91cF9ieShkeWFkX2lkKSAlPiUNCiAgY291bnQoZHlhZF9pZCkgJT4lDQogIHJlbmFtZShudW1iZXJfdHJhbnNpdGlvbiA9IG4pICU+JQ0KICB1bmdyb3VwKCkNCg0KI2FkZCB0aGUgbnVtYmVyIG9mIHRyYW5zaXRpb25zIHRvIGV2ZW50X2RhdGENCmV2ZW50X2RhdGEgPC0gZXZlbnRfZGF0YSAlPiUNCiAgbGVmdF9qb2luKG5yX3RyYW5zaXRpb24sIGJ5ID0gImR5YWRfaWQiKQ0KDQpgYGANCg0KIyMgU3RlcCAyOiBjcmVhdGUgc3BlbGwgY291bnQgdmFyaWFibGUNCg0KTm93IHdlIGtub3cgdGhlIG51bWJlciBvZiBkeWFkIHNwZWxscyB3ZSBjYW4gc3RhcnQgd2l0aCBvdXIgY3VzdG9tIGZ1bmN0aW9uIGZvciBlYWNoIGR5YWQuIEZvciBlYWNoIGR5YWQgaXQgd2lsbCBjb3VudCB0aGUgbnVtYmVyIG9mIHNwZWxscyBhbmQgZm9yIGVhY2ggb2JzZXJ2YXRpb24gb2YgdGhlIGR5YWQgaXQgd2lsbCBhbHNvIG5vdGUgaW4gd2hpY2ggc3BlbGwgaXQgaXMgY3VycmVudGx5IGluLiANCg0KYGBge3IgcmVwZWF0ZWQgcmlzayBkYXRhIDEuMX0NCg0KI2NyZWF0ZSB0aGUgdmFyaWFibGUgZHJvcHBlZA0KI2Jhc2VkIG9uIHRyYW5zaXRpb24sIHdoZW4gdHJhbnNpdGlvbiBpcyAtMSwgYWx0ZXIgaXMgZHJvcHBlZC4NCmRhdGFfbGlzdCA8LSBldmVudF9kYXRhICU+JQ0KICB1bmdyb3VwKCkgJT4lIA0KICBtdXRhdGUoZHJvcHBlZCA9IGlmZWxzZSh0cmFuc2l0aW9uID09IC0xLCAxLCAwKSkgJT4lDQogIG11dGF0ZShkcm9wcGVkID0gaWZlbHNlKGlzLm5hKGRyb3BwZWQpLCAwLCBkcm9wcGVkKSkgJT4lDQogIGdyb3VwX3NwbGl0KGR5YWRfaWQpDQoNCnBsYW4obXVsdGlzZXNzaW9uLCB3b3JrZXJzID0gNikNCg0KZGF0YV9saXN0IDwtIGRhdGFfbGlzdCAlPiUNCiAgZnV0dXJlX21hcCguZiA9IH4gRnRpbWVzX2Ryb3BwZWQoLngpLA0KICAgICAgICAgICAgICAgICAucHJvZ3Jlc3MgPSBUKQ0KDQoNCiNzdG9wIHBhcmFsbGVsIHNlc3Npb24NCnBsYW4oc2VxdWVudGlhbCkNCg0KI3Jlc2V0IGRhdGEgdG8gZXZlbnRfZGF0YSBkZg0KcmVwZWF0ZWRfZXZlbnRfZGF0YSA8LSBkYXRhX2xpc3QgJT4lDQogIHJiaW5kbGlzdCgpDQoNCiNjcmVhdGUgYSBuZXcgcmVwZWF0ZWQgcmlzayBkYXRhc2V0DQpyZXBlYXRlZF9ldmVudF9kYXRhIDwtIHJlcGVhdGVkX2V2ZW50X2RhdGEgJT4lDQogIHNlbGVjdCghYyhyYW5nZSwgY2Vuc29yKSkgJT4lDQogIG11dGF0ZSgNCiAgICB0aW1lc19kcm9wcGVkX3JlYyA9IGlmZWxzZShzdXJ2ZXlfd2F2ZSA9PSAxLCAwLCB0aW1lc19kcm9wcGVkX3JlYyksDQogICAgZHJvcHBlZCA9IGlmZWxzZShpcy5uYShzZWxlY3RlZCksIE5BLCBkcm9wcGVkKSwNCiAgICBkcm9wcGVkID0gaWZlbHNlKHN1cnZleV93YXZlIDwgZW50ZXJlZF9uZXR3b3JrLCBOQSwgZHJvcHBlZCksDQogICAgdGltZXNfZHJvcHBlZF9yZWMgPSBpZmVsc2UoaXMubmEoc2VsZWN0ZWQpLCBOQSwgdGltZXNfZHJvcHBlZF9yZWMpLA0KICAgIHRpbWVzX2Ryb3BwZWRfcmVjID0gaWZlbHNlKHN1cnZleV93YXZlIDwgZW50ZXJlZF9uZXR3b3JrLCBOQSwgdGltZXNfZHJvcHBlZF9yZWMpLA0KICAgIHRpbWVzX2Ryb3BwZWRfcmVjID0gaWZlbHNlKHN1cnZleV93YXZlID09IGVudGVyZWRfbmV0d29yaywgMCwgdGltZXNfZHJvcHBlZF9yZWMpLA0KICAgIHByb2Nlc3NfaWQgPSBwYXN0ZTAoZHlhZF9pZCwgdGltZXNfZHJvcHBlZF9yZWMpDQogICkgJT4lDQogIGZpbHRlcighaXMubmEoZHJvcHBlZCkpDQoNCmBgYA0KDQoNCiMjIFN0ZXAgMzogRGVsZXRlIGVtcHR5IG9ic2VydmF0aW9ucw0KDQpXZSBoYXZlIGNyZWF0ZWQgYSBjb3VudGVyIGZvciBlYWNoIGR5YWQgc3BlbGwgYW5kIGFsc28gY3JlYXRlZCBhIHByb2Nlc3MgaWQsIHdoaWNoIGlkZW50aWZpZXMgdGhlIGR5YWQgc3BlbGwuIEhvd2V2ZXIsIHJpZ2h0IG5vdyB3ZSBhbHNvIGhhdmUgb2JzZXJ2YXRpb25zIGluIHRoZSBkYXRhIHdobyBhcmUgZHJvcHBlZCBhbmQgbm90IGluIHRoZSBkYXRhLiBUaGVzZSBjYW5ub3QgYmUgYXQgdGhlIHJpc2sgb2YgZGVzZWxlY3Rpb24uIEhlbmNlIHdlIG5lZWQgdG8gZHJvcCB0aGVtIGZyb20gdGhlIGRhdGEgYXMgcmVvY3VycmVuY2UgaXMgbm90IHBhcnQgb2Ygc3R1ZHkuDQoNCg0KYGBge3IgcmVwZWF0ZWQgcmlzayBkYXRhIDJ9DQoNCiMjIGZpbHRlciBvdXQgb2JzZXJ2YXRpb25zIGluIHdoaWNoIHRoZSBkeWFkX2lkIGlzIG5vdCBkcm9wcGVkIGZyb20gdGhlIG5ldHdvcmsgYW5kIGFsc28gbm90IHNlbGVjdGVkDQojIGluIHRoaXMgaW5zdGFuY2VzIHRoZSBkeWFkIGlzIG5vdCBhdCByaXNrIG9mIGJlaW5nIGRlc2VsZWN0ZWQuDQpyZXBlYXRlZF9ldmVudF9kYXRhIDwtIHJlcGVhdGVkX2V2ZW50X2RhdGEgJT4lDQogIG11dGF0ZShmaWx0ZXIgPSBkcm9wcGVkICsgc2VsZWN0ZWQpICU+JQ0KICBmaWx0ZXIoZmlsdGVyID4gMCkNCg0KYGBgDQoNCiMjIFN0ZXAgNDogIGNyZWF0ZSBhIG5ldyBjZW5zb3IgdmFyaWFibGUuIA0KDQpgYGB7ciByZXBlYXRlZCByaXNrIGRhdGEgM30NCiNjcmVhdGUgY2Vuc29yIHZhcmlhYmxlIGZvciBwcm9jZXNzX2lkDQpjZW5zb3JfcHJvY2Vzc19pZCA8LSByZXBlYXRlZF9ldmVudF9kYXRhICU+JQ0KICBzZWxlY3QoZHlhZF9pZCwgcHJvY2Vzc19pZCwgc3VydmV5X3dhdmUsIGRyb3BwZWQsIHNlbGVjdGVkKSAlPiUNCiAgZ3JvdXBfYnkocHJvY2Vzc19pZCkgJT4lDQogIG11dGF0ZShtYXhfd2F2ZSA9IG1heChzdXJ2ZXlfd2F2ZSkpICU+JQ0KICBtdXRhdGUoY2Vuc29yID0gaWZlbHNlKChtYXhfd2F2ZSA9PSBzdXJ2ZXlfd2F2ZSkgJiAoc2VsZWN0ZWQgPT0gMSksIDEsIDApKSAlPiUNCiAgc3VtbWFyaXplKGNlbnNvcl9wcm9jZXNzID0gbWF4KGNlbnNvcikpICU+JQ0KICB1bmdyb3VwKCkNCg0KI2FkZCBjZW5zb3IgdG8gdGhlIGRhdGENCnJlcGVhdGVkX2V2ZW50X2RhdGEgPC0gcmVwZWF0ZWRfZXZlbnRfZGF0YSAlPiUNCiAgbGVmdF9qb2luKGNlbnNvcl9wcm9jZXNzX2lkLCBieSA9ICJwcm9jZXNzX2lkIikNCg0KYGBgDQoNCiMjIFN0ZXAgNTogY3JlYXRlIGEgbmV3IHRpbWUgdmFyaWFibGUNCg0KV2UgbmVlZCBhIG5ldyB0aW1lIHZhcmlhYmxlIHRoYXQgY2FsY3VsYXRlcyBmb3IgZXZlcnkgcHJvY2Vzc19pZCBob3cgbG9uZyBpdCBpcyBhbmQgZm9yIGV2ZXJ5IG9ic2VydmF0aW9uIGluIHdoaWNoIHBlcmlvZCBpdCBpcyBvZiB0aGUgZnVsbCB0aW1lIHJhbmdlLiANCg0KYGBge3IgcmVwZWF0ZWQgcmlzayBkYXRhIDR9DQojY2FsY3VsYXRlIGZvciBldmVyeSBwcm9jZXNzIGlkIGhvdyBsb25nIHRoZSBwcm9jZXNzIGlzDQpwcm9jZXNzX2xlbmd0aCA8LSByZXBlYXRlZF9ldmVudF9kYXRhICU+JQ0KICBncm91cF9ieShwcm9jZXNzX2lkKSAlPiUNCiAgY291bnQoKSAlPiUNCiAgcmVuYW1lKHJhbmdlID0gbikgJT4lDQogIHVuZ3JvdXAoKQ0KDQojIyBhZGQgdGhlIHByb2Nlc3MgbGVuZ3RoIHRvIHRoZSByZXBlYXRlZF9kYXRhDQpyZXBlYXRlZF9ldmVudF9kYXRhIDwtIHJlcGVhdGVkX2V2ZW50X2RhdGEgJT4lDQogICNzZWxlY3QoIXJhbmdlKSAlPiUNCiAgbGVmdF9qb2luKHByb2Nlc3NfbGVuZ3RoLCBieSA9ICJwcm9jZXNzX2lkIikNCg0KI2NyZWF0ZSBuZXcgdGltZSB2YXJpYWJsZSANCnJlcGVhdGVkX2V2ZW50X2RhdGEgPC0gcmVwZWF0ZWRfZXZlbnRfZGF0YSAlPiUNCiAgZ3JvdXBfYnkocHJvY2Vzc19pZCkgJT4lDQogIG11dGF0ZSh0aW1lID0gc2VxKGZyb20gPSAxLCB0byA9IG1heChyYW5nZSkpKSAlPiUNCiAgdW5ncm91cCgpDQpgYGANCg0KDQojIyBTdGVwIDY6IGNyZWF0ZSByZWxhdGlvbnNoaXAgbGVuZ3RoIHZhcmlhYmxlDQoNCkkgYWxzbyB3YW50IGEgdmFyaWFibGUgd2hpY2ggZGVub3RlcyBob3cgbG9uZyBhbiBhbHRlciBhbmQgYW4gZWdvIGtub3cgZWFjaCBvdGhlci4gVHdvIHZhcmlhdGlvbnMgb24gdGhpcyB0aGVtZTogZmlyc3QsIGNhbGN1bGF0ZSB0aGUgdG90YWwgYW1vdW50IG9mIHRpbWUgYmV0d2VlbiBlbnRlcmluZyB0aGUgbmV0d29yayBhbmQgdGhlIGZpbmFsIGRyb3AuIFNlY29uZCwgY2FsY3VsYXRlIHRoZSB0b3RhbCBudW1iZXIgb2YgdGltZXMgYW4gYWx0ZXIgd2FzIHByZXNlbnQgaW4gdGhlIG5ldHdvcmsuDQoNCmBgYHtyIHJlcGVhdGVkIHJpc2sgNX0NCnJlbGF0aW9uc2hpcF9sZW5ndGggPC0gcmVwZWF0ZWRfZXZlbnRfZGF0YSAlPiUgDQogIHNlbGVjdChub21lbV9lbmNyLCBzdXJ2ZXlfd2F2ZSwgZHlhZF9pZCwgdGltZSwgZW50ZXJlZF9uZXR3b3JrLCBlbmRfeWVhciwgZHJvcHBlZCkgJT4lDQogIGZpbHRlcihkcm9wcGVkID09IDApICU+JSANCiAgZ3JvdXBfYnkoZHlhZF9pZCkgJT4lIA0KICBtdXRhdGUobGVuZ3RoX3JlbF9tZW1iZXIgPSAxOm4oKSwNCiAgICAgICAgIGxlbmd0aF9yZWxfdG90YWwgPSBzdXJ2ZXlfd2F2ZSAtIGVudGVyZWRfbmV0d29yayArIDEpICU+JSANCiAgdW5ncm91cCgpICU+JSANCiAgc2VsZWN0KG5vbWVtX2VuY3IsIHN1cnZleV93YXZlLCBkeWFkX2lkLCBsZW5ndGhfcmVsX21lbWJlciwgbGVuZ3RoX3JlbF90b3RhbCkNCg0KcmVwZWF0ZWRfZXZlbnRfZGF0YSA8LSByZXBlYXRlZF9ldmVudF9kYXRhICU+JSANCiAgbGVmdF9qb2luKHJlbGF0aW9uc2hpcF9sZW5ndGgsIGJ5ID0gYygibm9tZW1fZW5jciIsICJzdXJ2ZXlfd2F2ZSIsICJkeWFkX2lkIikpDQoNCg0KI2NyZWF0ZSBhIHNlbGVjdGlvbiBvZiB0aGUgZGF0YQ0KcmVwZWF0ZWRfcGVyc29uX2xldmVsIDwtIHJlcGVhdGVkX2V2ZW50X2RhdGEgJT4lDQogIHNlbGVjdChwcm9jZXNzX2lkLCBkeWFkX2lkLCBub21lbV9lbmNyLCB0aW1lc19kcm9wcGVkX3JlYywgY2Vuc29yX3Byb2Nlc3MsIHJhbmdlKSAlPiUNCiAgZGlzdGluY3QoKSAlPiUNCiAgcmVuYW1lKHRpbWVzX2Ryb3BwZWRfZWFybGllciA9IHRpbWVzX2Ryb3BwZWRfcmVjKQ0KDQpgYGANCg0KIyBEYXRhIGV4cG9ydA0KDQpFeHBvcnQgdGhlIHJlcGVhdGVkIHJpc2sgZGF0YS4NCg0KYGBge3IgZXhwb3J0IGRhdGF9DQojc2F2ZSBldmVudCBkYXRhIGFzIDIwMjItMDktMDJfcmlzay1kYXRhLnJkcw0Kc2F2ZShyZXBlYXRlZF9ldmVudF9kYXRhLCBmaWxlID0gImRhdGFmaWxlcy9kYXRhLXByb2Nlc3NlZC9kaXNhZ2dyZWdhdGVkX2RhdGEvMjAyMy0wNi0xMl9saXNzLXJlcGVhdGVkLXJpc2stZGF0YS5yZGEiKQ0KDQojc2F2ZSBwZXJzb24gcGVyaW9kIGRhdGENCnNhdmUocmVwZWF0ZWRfcGVyc29uX2xldmVsLCBmaWxlID0gImRhdGFmaWxlcy9kYXRhLXByb2Nlc3NlZC9kaXNhZ2dyZWdhdGVkX2RhdGEvMjAyMy0wNi0xMl9saXNzLXJlcGVhdGVkLXBlcnNvbi1sZXZlbC5yZGEiKQ0KDQpgYGANCg0KDQo=


Copyright © 2023 Jeroense Thijmen