1 Read data

# Read in data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
setwd("C:/Users/Mihai/Desktop/R Notebooks/notebooks/UG-met")
folder <- "C:/Users/Mihai/Desktop/R Notebooks/notebooks/UG-met"
pre <- readr::read_csv("PRE_answers_2022.csv")
Rows: 2057 Columns: 7
-- Column specification ------------------------------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (2): Username, Accepted
dbl  (4): Alocator, Decident, Feedback, Round
dttm (1): Timestamp

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
post <- readr::read_csv("POST_answers_2022.csv")
Rows: 1944 Columns: 7
-- Column specification ------------------------------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (2): Username, Accepted
dbl  (4): Alocator, Decident, Feedback, Round
dttm (1): Timestamp

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



## ID df
id_df <- rio::import(file.path(folder, "Scale complete triate Sofi pa4.xlsx"),
                     skip = 0, colNames = FALSE, which = "incadrari")   
New names:
* `` -> ...1
* `` -> ...2
* `` -> ...3
* `` -> ...4
* `` -> ...5
* ...
id_df <- id_df[, 1:4]
colnames(id_df) <- c("Grup", "Cond", "id", "email")

id_df <- 
  id_df %>%
  janitor::remove_empty("rows") %>% 
  dplyr::mutate(id = stringr::str_remove(id, "^0+"),              # remove leading zeros
                id = stringr::str_remove_all(id, "[[:blank:]]"),  # remove any white space
                id =  toupper(id)) %>%
  dplyr::mutate(Cond = stringr::str_replace(Cond, "12CONTROL", "CONTROL"),   # fix typo
                Grup = stringr::str_replace(Grup, "burnout", "Burnout"),
                Grup = stringr::str_replace(Grup, "pop generala", "pop gen"),
                Grup = stringr::str_replace(Grup, "old", "pop gen")) %>%
  dplyr::mutate(Grup = dplyr::if_else(is.na(Grup), "pop gen", Grup))

id_df <- 
  id_df %>%
  tidyr::separate(id, 
           into = c("id_num", "Exp_type"), 
           sep = "(?<=[0-9])(?=[A-Za-z])",     # ?<= is "look behind"
           remove = FALSE
           ) %>%
  dplyr::select(-id_num) %>%
  dplyr::mutate(Exp_type = dplyr::if_else(Exp_type %in% c("A", "B", "C", "D", "E", "R", "X"), "online", Exp_type)) %>% 
  dplyr::mutate(email = tolower(email),
                email = stringr::str_remove_all(email, "[[:blank:]]"))
# Read in data ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
setwd("C:/Users/Mihai/Desktop/R Notebooks/notebooks/UG-met")
email_df <- rio::import("mail-grup.xlsx", skip = 3)


gsr_df <- email_df[1:42, 1:4]
names(gsr_df)[1:4] <- c("Group", "Cond", "ID", "email")

rmn_df <- email_df[181:197, 2:4]
names(rmn_df)[1:3] <- c("Nr_Crt", "ID", "email")
rmn_df$Cond <- rep("EXPERIMENTAL", nrow(rmn_df))
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

–>

1.1 Exclude known test-IDs

# Exclude known test-IDs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
excluded_id <- c("bica.andreea21@gmail.com", "ioana.r.podina@gmail.com", "test@ro", "rozetadraghici@gmail.com", "ioana.podina@fpse.unibuc.ro",
                 "cociaioana@gmail.com")
varstnici_pattern <- "PA1"

pre <-
  pre %>%
  dplyr::filter(!Username %in% excluded_id) %>%
  dplyr::filter(!str_detect(Username, varstnici_pattern))

post <-
  post %>%
  dplyr::filter(!Username %in% excluded_id) %>%
  dplyr::filter(!str_detect(Username, varstnici_pattern))


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# Check & Exclude IDs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pre %>%
  count(Username) %>%
  print(n = Inf)   # "luciana.haloiu@invingemautismul.ro" has 24 trials instead of 12

post %>%
  count(Username) %>%
  print(n = Inf)  

pre <- 
  pre %>%
  dplyr::group_by(Username) %>%             # exclude last 12 trials of "luciana.haloiu@invingemautismul.ro"
  dplyr::filter(!(Username == "luciana.haloiu@invingemautismul.ro" & dplyr::row_number() %in% 13:24)) 
pre$Timestamp[pre$Username == "luciana.haloiu@invingemautismul.ro"]  # check: 12th trial is at "2020-11-23 16:40:59 UTC"
 [1] "2020-11-23 16:38:20 UTC" "2020-11-23 16:38:37 UTC" "2020-11-23 16:38:52 UTC" "2020-11-23 16:39:05 UTC" "2020-11-23 16:39:16 UTC"
 [6] "2020-11-23 16:39:30 UTC" "2020-11-23 16:39:40 UTC" "2020-11-23 16:39:58 UTC" "2020-11-23 16:40:13 UTC" "2020-11-23 16:40:26 UTC"
[11] "2020-11-23 16:40:39 UTC" "2020-11-23 16:40:59 UTC"
pre_ids <- data.frame(pre = unique(pre$Username))
post_ids <- data.frame(post = unique(post$Username))
list_ids <- dplyr::full_join(pre_ids, post_ids, by = c("pre" = "post"), keep = TRUE)
list_ids                   

complete_ids <-
  list_ids %>%
  tidyr::drop_na() %>%
  dplyr::mutate(pre = as.character(pre)) %>%
  dplyr::pull(pre)
  
# Keep only IDs that have both PRE and POST
pre <-
  pre %>%
  dplyr::filter(Username %in% complete_ids)

post <-
  post %>%
  dplyr::filter(Username %in% complete_ids)







### Radical exclusions (keep only the first 12 observations)
pre <-
  pre %>%
  group_by(Username) %>% 
  dplyr::filter(row_number() <= 12) 

post <-
  post %>%
  group_by(Username) %>% 
  dplyr::filter(row_number() <= 12)

2 Join with ID table

# some Usernames are emails, some are IDs in form of emails
pre <-
  pre %>%
  dplyr::mutate(id_user = Username) %>%
  dplyr::select(Username, id_user, everything()) %>%
  dplyr::mutate(id_user = stringr::str_remove(id_user, "@.*")) %>%
  dplyr::mutate(id_user = if_else(stringr::str_detect(id_user, "A10|GSR"), id_user, NA_character_)) %>%
  dplyr::mutate(id_user = stringr::str_remove(id_user, "^0+"),              # remove leading zeros
                id_user = stringr::str_remove_all(id_user, "[[:blank:]]"),  # remove any white space
                id_user =  toupper(id_user)) %>%
  dplyr::mutate(Username = tolower(Username),
                Username = stringr::str_remove_all(Username, "[[:blank:]]"))

post <-
  post %>%
  dplyr::mutate(id_user = Username) %>%
  dplyr::select(Username, id_user, everything()) %>%
  dplyr::mutate(id_user = stringr::str_remove(id_user, "@.*")) %>%
  dplyr::mutate(id_user = if_else(stringr::str_detect(id_user, "A10|GSR"), id_user, NA_character_)) %>%
  dplyr::mutate(id_user = stringr::str_remove(id_user, "^0+"),              # remove leading zeros
                id_user = stringr::str_remove_all(id_user, "[[:blank:]]"),  # remove any white space
                id_user =  toupper(id_user)) %>%
  dplyr::mutate(Username = tolower(Username),
                Username = stringr::str_remove_all(Username, "[[:blank:]]"))

# Exclude subjects from A10 (RMN sample)
pre <-
  pre %>%
  dplyr::filter(!str_detect(Username, "a10"))

post <-
  post %>%
  dplyr::filter(!str_detect(Username, "a10"))


# Merge
pre_united <- dplyr::left_join(pre, id_df, by = c("Username" = "email")) %>%
  dplyr::left_join(., id_df, by = c("id_user" = "id"), suffix = c("", ".x")) %>%
    dplyr::mutate(Grup = dplyr::coalesce(Grup, Grup.x),
                  Cond = dplyr::coalesce(Cond, Cond.x),
                  Exp_type = dplyr::coalesce(Exp_type, Exp_type.x),
                  email = dplyr::coalesce(email, email)) %>%
  dplyr::select(!contains(".x")) %>%
  dplyr::filter(!is.na(Grup), !is.na(Cond))
                
post_united <- dplyr::left_join(post, id_df, by = c("Username" = "email")) %>%
  dplyr::left_join(., id_df, by = c("id_user" = "id"), suffix = c("", ".x")) %>%
    dplyr::mutate(Grup = dplyr::coalesce(Grup, Grup.x),
                  Cond = dplyr::coalesce(Cond, Cond.x),
                  Exp_type = dplyr::coalesce(Exp_type, Exp_type.x),
                  email = dplyr::coalesce(email, email)) %>%
  dplyr::select(!contains(".x")) %>%
  dplyr::filter(!is.na(Grup), !is.na(Cond))

# To keep rest of code working
pre <- pre_united
post <- post_united

merged_united <- rbind(pre_united, post_united) %>%
  dplyr::select(Username, Grup, Cond)

3 Compute scores

# Compute scores ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# utilizam doar Decident: unfair = 17-24 (6 oferte diferite); fair = 49-54 (6 oferte diferite)

# Define Fair/Unfair
pre <-
  pre %>%
  dplyr::mutate(Type = cut(Decident, breaks = c(-Inf, 30, Inf), labels = c("Unfair", "Fair")))

post <-
  post %>%
  dplyr::mutate(Type = cut(Decident, breaks = c(-Inf, 30, Inf), labels = c("Unfair", "Fair")))

# Compute Percent scores
pre_scores <-
  pre %>%
  dplyr::add_count(Username, Type, name = "n_Type") %>%
  dplyr::count(Username, Type, Accepted, n_Type, name = "n_Accepted_Type", .drop = FALSE) %>%   # need .drop = FALSE for missing factor levels leading to 0% Percentages
  dplyr::mutate(Percent = 100 * n_Accepted_Type / n_Type) %>%  
  dplyr::ungroup() %>%
  tidyr::complete(Username, Type, Accepted, fill = list(n_Type = 0, n_Accepted_Type = 0, Percent = 0)) %>%  # for missing factor levels leading to 0% Percentages
  dplyr::filter(Accepted == "Y") %>%
  dplyr::mutate(PrePost = rep("Pre", n())) %>%
  dplyr::mutate(PrePost= factor(PrePost, levels = c("Pre", "Post"))) 

post_scores <-
  post %>%
  dplyr::add_count(Username, Type, name = "n_Type") %>%
  dplyr::count(Username, Type, Accepted, n_Type, name = "n_Accepted_Type", .drop = FALSE) %>%   # need .drop = FALSE for missing factor levels leading to 0% Percentages
  dplyr::mutate(Percent = 100 * n_Accepted_Type / n_Type) %>%  
  dplyr::ungroup() %>%
  tidyr::complete(Username, Type, Accepted, fill = list(n_Type = 0, n_Accepted_Type = 0, Percent = 0)) %>%  # for missing factor levels leading to 0% Percentages
  dplyr::filter(Accepted == "Y") %>%
  dplyr::mutate(PrePost = rep("Post", n())) %>%
  dplyr::mutate(PrePost = factor(PrePost, levels = c("Pre", "Post")))
  

merged_scores <- rbind(pre_scores, post_scores) %>%
  dplyr::left_join(., merged_united, by = "Username")

# # Merge  - OLD
# merged_scores <- rbind(pre_scores, post_scores)
# 
# merged_scores$Username <- tolower(merged_scores$Username)   # emails to lower letters to match on
# gsr_df$email <- tolower(gsr_df$email)
# rmn_df$email <- tolower(rmn_df$email)
# 
# merged_scores_gsr <- dplyr::left_join(merged_scores, gsr_df, by = c("Username" = "email"))     # Merge with emails/cond
# merged_scores_rmn <- dplyr::left_join(merged_scores, rmn_df, by = c("Username" = "email"))     # Merge with emails/cond
# 
# merged_scores_gsr_rmn <-
#   dplyr::left_join(merged_scores_gsr, merged_scores_rmn, by = c("Username", "Type", "Accepted", "n_Type", "n_Accepted_Type", "Percent", "PrePost")) %>%
#   dplyr::mutate(Cond = dplyr::coalesce(Cond.x, Cond.y)) %>%
#   dplyr::mutate(ID = dplyr::coalesce(ID.x, ID.y))

4 General pop

merged_scores %>%
  dplyr::filter(Grup == "pop gen", Cond == "EXPERIMENTAL") %>%
    ggstatsplot::grouped_ggwithinstats(
      data = .,
      x = PrePost,
      y = Percent,
      grouping.var = Type,
      type = "parametric",
      pairwise.comparisons = TRUE,
      pairwise.display = "all",
      annotation.args = list(title = "Populatie Genearala - TR"))


merged_scores %>%
  dplyr::filter(Grup == "pop gen", Cond == "CONTROL") %>%
    ggstatsplot::grouped_ggwithinstats(
      data = .,
      x = PrePost,
      y = Percent,
      grouping.var = Type,
      type = "parametric",
      pairwise.comparisons = TRUE,
      pairwise.display = "all",
      annotation.args = list(title = "Populatie Genearala - CTRL"))

5 PTSD

merged_scores %>%
  dplyr::filter(Grup == "PTSD", Cond == "EXPERIMENTAL") %>%
    ggstatsplot::grouped_ggwithinstats(
      data = .,
      x = PrePost,
      y = Percent,
      grouping.var = Type,
      type = "np",
      pairwise.comparisons = TRUE,
      pairwise.display = "all",
      annotation.args = list(title = "PTSD - TR"))


merged_scores %>%
  dplyr::filter(Grup == "PTSD", Cond == "CONTROL") %>%
    ggstatsplot::grouped_ggwithinstats(
      data = .,
      x = PrePost,
      y = Percent,
      grouping.var = Type,
      type = "np",
      pairwise.comparisons = TRUE,
      pairwise.display = "all",
      annotation.args = list(title = "PTSD - CTRL"))

6 Burnout

merged_scores %>%
  dplyr::filter(Grup == "Burnout", Cond == "EXPERIMENTAL") %>%
    ggstatsplot::grouped_ggwithinstats(
      data = .,
      x = PrePost,
      y = Percent,
      grouping.var = Type,
      type = "np",
      pairwise.comparisons = TRUE,
      pairwise.display = "all",
      annotation.args = list(title = "Burnout - TR"))


merged_scores %>%
  dplyr::filter(Grup == "Burnout", Cond == "CONTROL") %>%
    ggstatsplot::grouped_ggwithinstats(
      data = .,
      x = PrePost,
      y = Percent,
      grouping.var = Type,
      type = "np",
      pairwise.comparisons = TRUE,
      pairwise.display = "all",
      annotation.args = list(title = "Burnout - CTRL"))


7 Session Info

R version 4.1.0 (2021-05-18)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8.1 x64 (build 9600)

Matrix products: default

locale:
[1] LC_COLLATE=Romanian_Romania.1250  LC_CTYPE=Romanian_Romania.1250    LC_MONETARY=Romanian_Romania.1250 LC_NUMERIC=C                     
[5] LC_TIME=Romanian_Romania.1250    
system code page: 1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] statsExpressions_1.1.0 ggstatsplot_0.8.0      rlang_0.4.11           broom_0.7.9            rstatix_0.7.0          rio_0.5.27            
 [7] scales_1.1.1           ggpubr_0.4.0           forcats_0.5.1          stringr_1.4.0          dplyr_1.0.7            purrr_0.3.4           
[13] readr_2.0.1            tidyr_1.1.3            tibble_3.1.4           ggplot2_3.3.5          tidyverse_1.3.1        papaja_0.1.0.9997     
[19] pacman_0.5.1          

loaded via a namespace (and not attached):
  [1] estimability_1.3          ggprism_1.0.3             GGally_2.1.2              lavaan_0.6-9              coda_0.19-4              
  [6] bit64_4.0.5               knitr_1.33                multcomp_1.4-17           data.table_1.14.0         rpart_4.1-15             
 [11] hardhat_0.1.6             generics_0.1.0            GPfit_1.0-8               TH.data_1.0-10            future_1.22.1            
 [16] correlation_0.7.0         bit_4.0.4                 tzdb_0.1.2                xml2_1.3.2                lubridate_1.7.10         
 [21] assertthat_0.2.1          gower_0.2.2               WRS2_1.1-3                xfun_0.25                 jquerylib_0.1.4          
 [26] hms_1.1.0                 evaluate_0.14             fansi_0.5.0               dbplyr_2.1.1              readxl_1.3.1             
 [31] igraph_1.2.6              DBI_1.1.1                 tmvnsim_1.0-2             Rsolnp_1.16               htmlwidgets_1.5.3        
 [36] reshape_0.8.8             kSamples_1.2-9            stats4_4.1.0              Rmpfr_0.8-4               paletteer_1.4.0          
 [41] ellipsis_0.3.2            backports_1.2.1           pbivnorm_0.6.0            insight_0.14.4            prismatic_1.0.0          
 [46] RcppParallel_5.1.4        vctrs_0.3.8               abind_1.4-5               cachem_1.0.6              withr_2.4.2              
 [51] vroom_1.5.4               checkmate_2.0.0           emmeans_1.6.3             archive_1.1.0             fdrtool_1.2.16           
 [56] parsnip_0.1.7             mnormt_2.0.2              cluster_2.1.2             mi_1.0                    crayon_1.4.1             
 [61] labeling_0.4.2            recipes_0.1.16            pkgconfig_2.0.3           SuppDists_1.1-9.5         nlme_3.1-152             
 [66] nnet_7.3-16               globals_0.14.0            lifecycle_1.0.1           MatrixModels_0.5-0        sandwich_3.0-1           
 [71] kutils_1.70               modelr_0.1.8              cellranger_1.1.0          datawizard_0.2.0.1        Matrix_1.3-4             
 [76] yardstick_0.0.8           regsem_1.8.0              mc2d_0.1-21               carData_3.0-4             boot_1.3-28              
 [81] zoo_1.8-9                 reprex_2.0.1              base64enc_0.1-3           png_0.1-7                 PMCMRplus_1.9.0          
 [86] parameters_0.14.0         pROC_1.18.0               tune_0.1.6                workflows_0.2.3           multcompView_0.1-8       
 [91] arm_1.11-2                parallelly_1.27.0         jpeg_0.1-9                rockchalk_1.8.144         ggsignif_0.6.2           
 [96] memoise_2.0.0             magrittr_2.0.1            plyr_1.8.6                compiler_4.1.0            RColorBrewer_1.1-2       
[101] lme4_1.1-27.1             snakecase_0.11.0          cli_3.0.1                 DiceDesign_1.9            listenv_0.8.0            
[106] patchwork_1.1.1           pbapply_1.4-3             htmlTable_2.2.1           Formula_1.2-4             MASS_7.3-54              
[111] tidyselect_1.1.1          stringi_1.7.4             lisrelToR_0.1.4           sem_3.1-11                yaml_2.2.1               
[116] OpenMx_2.19.6             latticeExtra_0.6-29       ggrepel_0.9.1             semTools_0.5-5            grid_4.1.0               
[121] sass_0.4.0                tools_4.1.0               future.apply_1.8.1        parallel_4.1.0            matrixcalc_1.0-5         
[126] rstudioapi_0.13           foreach_1.5.1             foreign_0.8-81            janitor_2.1.0             gridExtra_2.3            
[131] ipmisc_6.0.2              prodlim_2019.11.13        pairwiseComparisons_3.1.6 farver_2.1.0              digest_0.6.28            
[136] lava_1.6.10               BWStest_0.2.2             Rcpp_1.0.7                car_3.0-11                BayesFactor_0.9.12-4.2   
[141] performance_0.7.3         httr_1.4.2                psych_2.1.6               effectsize_0.4.5          poLCA_1.4.1              
[146] colorspace_2.0-2          rvest_1.0.1               XML_3.99-0.7              fs_1.5.0                  truncnorm_1.0-8          
[151] splines_4.1.0             rematch2_2.1.2            xtable_1.8-4              gmp_0.6-2                 jsonlite_1.7.2           
[156] nloptr_1.2.2.2            corpcor_1.6.9             timeDate_3043.102         glasso_1.11               zeallot_0.1.0            
[161] ipred_0.9-11              R6_2.5.1                  Hmisc_4.5-0               lhs_1.1.1                 pillar_1.6.3             
[166] htmltools_0.5.2           glue_1.4.2                fastmap_1.1.0             minqa_1.2.4               class_7.3-19             
[171] codetools_0.2-18          mvtnorm_1.1-2             furrr_0.2.3               utf8_1.2.2                bslib_0.3.0              
[176] lattice_0.20-44           dials_0.0.9               curl_4.3.2                gtools_3.9.2              zip_2.2.0                
[181] openxlsx_4.2.4            survival_3.2-13           rmarkdown_2.10            qgraph_1.6.9              munsell_0.5.0            
[186] semPlot_1.1.2             rsample_0.1.0             iterators_1.0.13          haven_2.4.3               reshape2_1.4.4           
[191] gtable_0.3.0              bayestestR_0.11.0        
 

A work by Claudiu Papasteri

 

LS0tDQp0aXRsZTogIjxicj4gVWx0aW1hdHVtIEdhbWUiIA0Kc3VidGl0bGU6ICJSZXBvcnQiDQphdXRob3I6ICI8YnI+IENsYXVkaXUgUGFwYXN0ZXJpIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJW0gJVknKWAiDQpvdXRwdXQ6IA0KICAgIGh0bWxfbm90ZWJvb2s6DQogICAgICAgICAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICAgICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICAgICAgICAgIHRoZW1lOiBzcGFjZWxhYg0KICAgICAgICAgICAgaGlnaGxpZ2h0OiB0YW5nbw0KICAgICAgICAgICAgZm9udC1mYW1pbHk6IEFyaWFsDQogICAgICAgICAgICBmaWdfd2lkdGg6IDEwDQogICAgICAgICAgICBmaWdfaGVpZ2h0OiA5DQogICAgIyBwZGZfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgIHRvY19kZXB0aDogMg0KICAgICAgICAgICAgIyAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgICAgICAgICAjIGZvbnRzaXplOiAxMXB0DQogICAgICAgICAgICAjIGdlb21ldHJ5OiBtYXJnaW49MWluDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNw0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA2DQogICAgICAgICAgICAjIGZpZ19jYXB0aW9uOiB0cnVlDQogICAgIyBnaXRodWJfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjIGh0bWxfcHJldmlldzogZmFsc2UNCiAgICAgICAgICAgICMgZmlnX3dpZHRoOiA1DQogICAgICAgICAgICAjIGZpZ19oZWlnaHQ6IDUNCiAgICAgICAgICAgICMgZGV2OiBqcGVnDQotLS0NCg0KDQo8IS0tIFNldHVwIC0tPg0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBraW50ciBvcHRpb25zDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGNvbW1lbnQgPSAiIyIsDQogIGNvbGxhcHNlID0gVFJVRSwNCiAgZXJyb3IgPSBUUlVFLA0KICBlY2hvID0gVFJVRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIGNhY2hlID0gVFJVRSAgICAgICAjIGVjaG8gPSBGYWxzZSBmb3IgZ2l0aHViX2RvY3VtZW50LCBidXQgd2lsbCBiZSBmb2xkZWQgaW4gaHRtbF9ub3RlYm9vaw0KKQ0KDQojIEdlbmVyYWwgUiBvcHRpb25zIGFuZCBpbmZvDQpzZXQuc2VlZCgxMTEpICAgICAgICAgICAgICAgIyBpbiBjYXNlIHdlIHVzZSByYW5kb21pemVkIHByb2NlZHVyZXMgICAgICAgDQpvcHRpb25zKHNjaXBlbiA9IDk5OSkgICAgICAgIyBwb3NpdGl2ZSB2YWx1ZXMgYmlhcyB0b3dhcmRzIGZpeGVkIGFuZCBuZWdhdGl2ZSB0b3dhcmRzIHNjaWVudGlmaWMgbm90YXRpb24NCg0KIyBMb2FkIHBhY2thZ2VzDQpwYWNrYWdlcyA8LSBjKA0KICAicGFwYWphIiwNCiAgInRpZHl2ZXJzZSIsICAgICAgIA0KICAiZ2dwbG90MiIsICJnZ3B1YnIiLCAic2NhbGVzIiwgICAgICAgIA0KICAicmlvIiwNCiAgInJzdGF0aXgiLCAiYnJvb20iLCANCiAgInJsYW5nIiwNCiAgImdnc3RhdHNwbG90IiwgInN0YXRzRXhwcmVzc2lvbnMiDQogICMgLCAuLi4NCikNCg0KaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCnBhY21hbjo6cF9sb2FkKGNoYXIgPSBwYWNrYWdlcywgdXBkYXRlID0gRkFMU0UpDQoNCiMgVGhlbWVzIGZvciBnZ3Bsb3QyIHBsb3RpbmcgKGhlcmUgdXNlZCBBUEEgc3R5bGUpDQpnZ3Bsb3QyOjp0aGVtZV9zZXQocGFwYWphOjp0aGVtZV9hcGEoKSkNCmBgYA0KDQoNCg0KPCEtLSBSZXBvcnQgLS0+DQoNCmBgYHtyIGluZm8sIGVjaG89RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQojIElORk8gfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KIyBVRyAxOg0KIyAgIGh0dHBzOi8vYWdpbGUtcml2ZXItNTI2MjkuaGVyb2t1YXBwLmNvbS8NCiMgICBEb3dubG9hZCBodHRwczovL2FnaWxlLXJpdmVyLTUyNjI5Lmhlcm9rdWFwcC5jb20vZG93bmxvYWQvNHR3eXQ1MzZ3cQ0KIyBVRyAyOg0KIyAgIGh0dHBzOi8vdHJhbnF1aWwtbG93bGFuZHMtNjM1MjYuaGVyb2t1YXBwLmNvbS8NCiMgICBEb3dubG9hZDogaHR0cHM6Ly90cmFucXVpbC1sb3dsYW5kcy02MzUyNi5oZXJva3VhcHAuY29tL2Rvd25sb2FkLzR0d3l0NTM2d3ENCiMgDQojIA0KIyBBbmFsaXphIEFOT1ZBIDJYMiAoUHJlLVBvc3QgWCBGYWlyUmF0ZS1VbmZhaXJSYXRlKQ0KIyBGb2xvc2ltIGRvYXIgYW5zd2VyLmNzdiAoZmllY2FyZSBvbSB0cmVjZSBwcmluIDYgZmFpciBzaSA2IHVuZmFpcikNCiMgLSBOdSBmb2xvc2ltIGFsb2NhdG9yDQojIC0gRGVjaWRlbnQ6IHVuZmFpciA9IDE3LTI0ICg2IG9mZXJ0ZSBkaWZlcml0ZSk7IGZhaXIgPSA0OS01NCAoNiBvZmVydGUgZGlmZXJpdGUpIA0KIyAtIGRlY2kgYXZlbSBjYXRlZyBmYWlyL3VuZmFpcg0KIyAtIENhbGMgYWNjZXB0YW5jZSByYXRlIC4uLiBjYXRlIGF1IGZvc3QgYWNjZXB0YXRlIHBlIGZhaXIsIHNpIGNhdGUgcGUgdW5mYWlyIHB0IGZpZWNhcmUgb20gaW4gcGFydGUgKGRlY2kgMTAwJSA9IDYgY2EgNiB0cmFpZWx1cmkgc3VudCkNCiMgLSBkZWNpIG8gc2EgYXZlbSB1biBwcm9jZW50YWogZGUgYWNjZXB0YW5jZSBwdCBmaWVjYXJlIG9tIC0gdW5hIHBlIGZhaXIsIHVuYSBwZSB1bmZhaXINCiMgLSBDYWxjIG1lZGlhIGZlZWRiYWNrIC4uLiBjYXQgZSBtZWRpYSBmYWlyIHBlIGZhaXIsIHNpIHBlIHVuZmFpciBwdCBmaWVjYXJlIG9tIGluIHBhcnRlIA0KIyAtIDAgPSBEZWxvYyBjb3JlY3QsIDEwMCA9IEV4dHJlbSBkZSBjb3JlY3QNCiMgLSBkZWNpIG8gbWVkaWUgZmVlZGJhY2sgcHQgZmllY2FyZSBvbSAtIHVuYSBwZSBmYWlyLCB1bmEgcGUgdW5mYWlyDQojDQojIHZlcmlmOiANCiMgICAtIGZpZWNhcmUgYXJlIDYsIGV4Y2x1cyB0ZXN0IHJ1biAoYmljYS5hbmRyZWVhMjFAZ21haWwuY29tLCBpb2FuYS5yLnBvZGluYUBnbWFpbC5jb20sIHRlc3RAcm8sIHJvemV0YWRyYWdoaWNpQGdtYWlsLmNvbSksIA0KIyAtIG91dGxpZXIgbWlzc21hdGNoIGFjY2VwdGFuY2UgcmF0ZQ0KI35+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KYGBgDQoNCg0KDQoNCiMgUmVhZCBkYXRhDQoNCmBgYHtyIHJlYWRfZGF0YX0NCiMgUmVhZCBpbiBkYXRhIH5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4NCnNldHdkKCJDOi9Vc2Vycy9NaWhhaS9EZXNrdG9wL1IgTm90ZWJvb2tzL25vdGVib29rcy9VRy1tZXQiKQ0KZm9sZGVyIDwtICJDOi9Vc2Vycy9NaWhhaS9EZXNrdG9wL1IgTm90ZWJvb2tzL25vdGVib29rcy9VRy1tZXQiDQpwcmUgPC0gcmVhZHI6OnJlYWRfY3N2KCJQUkVfYW5zd2Vyc18yMDIyLmNzdiIpDQpwb3N0IDwtIHJlYWRyOjpyZWFkX2NzdigiUE9TVF9hbnN3ZXJzXzIwMjIuY3N2IikNCiMgfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4NCg0KDQoNCiMjIElEIGRmDQppZF9kZiA8LSByaW86OmltcG9ydChmaWxlLnBhdGgoZm9sZGVyLCAiU2NhbGUgY29tcGxldGUgdHJpYXRlIFNvZmkgcGE0Lnhsc3giKSwNCiAgICAgICAgICAgICAgICAgICAgIHNraXAgPSAwLCBjb2xOYW1lcyA9IEZBTFNFLCB3aGljaCA9ICJpbmNhZHJhcmkiKSAgIA0KDQppZF9kZiA8LSBpZF9kZlssIDE6NF0NCmNvbG5hbWVzKGlkX2RmKSA8LSBjKCJHcnVwIiwgIkNvbmQiLCAiaWQiLCAiZW1haWwiKQ0KDQppZF9kZiA8LSANCiAgaWRfZGYgJT4lDQogIGphbml0b3I6OnJlbW92ZV9lbXB0eSgicm93cyIpICU+JSANCiAgZHBseXI6Om11dGF0ZShpZCA9IHN0cmluZ3I6OnN0cl9yZW1vdmUoaWQsICJeMCsiKSwgICAgICAgICAgICAgICMgcmVtb3ZlIGxlYWRpbmcgemVyb3MNCiAgICAgICAgICAgICAgICBpZCA9IHN0cmluZ3I6OnN0cl9yZW1vdmVfYWxsKGlkLCAiW1s6Ymxhbms6XV0iKSwgICMgcmVtb3ZlIGFueSB3aGl0ZSBzcGFjZQ0KICAgICAgICAgICAgICAgIGlkID0gIHRvdXBwZXIoaWQpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShDb25kID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoQ29uZCwgIjEyQ09OVFJPTCIsICJDT05UUk9MIiksICAgIyBmaXggdHlwbw0KICAgICAgICAgICAgICAgIEdydXAgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZShHcnVwLCAiYnVybm91dCIsICJCdXJub3V0IiksDQogICAgICAgICAgICAgICAgR3J1cCA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlKEdydXAsICJwb3AgZ2VuZXJhbGEiLCAicG9wIGdlbiIpLA0KICAgICAgICAgICAgICAgIEdydXAgPSBzdHJpbmdyOjpzdHJfcmVwbGFjZShHcnVwLCAib2xkIiwgInBvcCBnZW4iKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoR3J1cCA9IGRwbHlyOjppZl9lbHNlKGlzLm5hKEdydXApLCAicG9wIGdlbiIsIEdydXApKQ0KDQppZF9kZiA8LSANCiAgaWRfZGYgJT4lDQogIHRpZHlyOjpzZXBhcmF0ZShpZCwgDQogICAgICAgICAgIGludG8gPSBjKCJpZF9udW0iLCAiRXhwX3R5cGUiKSwgDQogICAgICAgICAgIHNlcCA9ICIoPzw9WzAtOV0pKD89W0EtWmEtel0pIiwgICAgICMgPzw9IGlzICJsb29rIGJlaGluZCINCiAgICAgICAgICAgcmVtb3ZlID0gRkFMU0UNCiAgICAgICAgICAgKSAlPiUNCiAgZHBseXI6OnNlbGVjdCgtaWRfbnVtKSAlPiUNCiAgZHBseXI6Om11dGF0ZShFeHBfdHlwZSA9IGRwbHlyOjppZl9lbHNlKEV4cF90eXBlICVpbiUgYygiQSIsICJCIiwgIkMiLCAiRCIsICJFIiwgIlIiLCAiWCIpLCAib25saW5lIiwgRXhwX3R5cGUpKSAlPiUgDQogIGRwbHlyOjptdXRhdGUoZW1haWwgPSB0b2xvd2VyKGVtYWlsKSwNCiAgICAgICAgICAgICAgICBlbWFpbCA9IHN0cmluZ3I6OnN0cl9yZW1vdmVfYWxsKGVtYWlsLCAiW1s6Ymxhbms6XV0iKSkNCg0KYGBgDQoNCg0KPCEtLSAgT0xEDQojIEVtYWlscyBhbmQgZ3JvdXBzDQoNCmBgYHtyIGVtYWlsX2RmfQ0KIyBSZWFkIGluIGRhdGEgfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0Kc2V0d2QoIkM6L1VzZXJzL01paGFpL0Rlc2t0b3AvUiBOb3RlYm9va3Mvbm90ZWJvb2tzL1VHLW1ldCIpDQplbWFpbF9kZiA8LSByaW86OmltcG9ydCgibWFpbC1ncnVwLnhsc3giLCBza2lwID0gMykNCg0KDQpnc3JfZGYgPC0gZW1haWxfZGZbMTo0MiwgMTo0XQ0KbmFtZXMoZ3NyX2RmKVsxOjRdIDwtIGMoIkdyb3VwIiwgIkNvbmQiLCAiSUQiLCAiZW1haWwiKQ0KDQpybW5fZGYgPC0gZW1haWxfZGZbMTgxOjE5NywgMjo0XQ0KbmFtZXMocm1uX2RmKVsxOjNdIDwtIGMoIk5yX0NydCIsICJJRCIsICJlbWFpbCIpDQpybW5fZGYkQ29uZCA8LSByZXAoIkVYUEVSSU1FTlRBTCIsIG5yb3cocm1uX2RmKSkNCiMgfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4NCg0KYGBgDQotLT4NCg0KIyMgRXhjbHVkZSBrbm93biB0ZXN0LUlEcw0KDQpgYGB7ciBmaWx0ZXJ9DQojIEV4Y2x1ZGUga25vd24gdGVzdC1JRHMgfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQpleGNsdWRlZF9pZCA8LSBjKCJiaWNhLmFuZHJlZWEyMUBnbWFpbC5jb20iLCAiaW9hbmEuci5wb2RpbmFAZ21haWwuY29tIiwgInRlc3RAcm8iLCAicm96ZXRhZHJhZ2hpY2lAZ21haWwuY29tIiwgImlvYW5hLnBvZGluYUBmcHNlLnVuaWJ1Yy5ybyIsDQogICAgICAgICAgICAgICAgICJjb2NpYWlvYW5hQGdtYWlsLmNvbSIpDQp2YXJzdG5pY2lfcGF0dGVybiA8LSAiUEExIg0KDQpwcmUgPC0NCiAgcHJlICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFVc2VybmFtZSAlaW4lIGV4Y2x1ZGVkX2lkKSAlPiUNCiAgZHBseXI6OmZpbHRlcighc3RyX2RldGVjdChVc2VybmFtZSwgdmFyc3RuaWNpX3BhdHRlcm4pKQ0KDQpwb3N0IDwtDQogIHBvc3QgJT4lDQogIGRwbHlyOjpmaWx0ZXIoIVVzZXJuYW1lICVpbiUgZXhjbHVkZWRfaWQpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFzdHJfZGV0ZWN0KFVzZXJuYW1lLCB2YXJzdG5pY2lfcGF0dGVybikpDQoNCg0KIyB+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KDQojIENoZWNrICYgRXhjbHVkZSBJRHMgfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+DQpwcmUgJT4lDQogIGNvdW50KFVzZXJuYW1lKSAlPiUNCiAgcHJpbnQobiA9IEluZikgICAjICJsdWNpYW5hLmhhbG9pdUBpbnZpbmdlbWF1dGlzbXVsLnJvIiBoYXMgMjQgdHJpYWxzIGluc3RlYWQgb2YgMTINCg0KcG9zdCAlPiUNCiAgY291bnQoVXNlcm5hbWUpICU+JQ0KICBwcmludChuID0gSW5mKSAgDQoNCnByZSA8LSANCiAgcHJlICU+JQ0KICBkcGx5cjo6Z3JvdXBfYnkoVXNlcm5hbWUpICU+JSAgICAgICAgICAgICAjIGV4Y2x1ZGUgbGFzdCAxMiB0cmlhbHMgb2YgImx1Y2lhbmEuaGFsb2l1QGludmluZ2VtYXV0aXNtdWwucm8iDQogIGRwbHlyOjpmaWx0ZXIoIShVc2VybmFtZSA9PSAibHVjaWFuYS5oYWxvaXVAaW52aW5nZW1hdXRpc211bC5ybyIgJiBkcGx5cjo6cm93X251bWJlcigpICVpbiUgMTM6MjQpKSANCnByZSRUaW1lc3RhbXBbcHJlJFVzZXJuYW1lID09ICJsdWNpYW5hLmhhbG9pdUBpbnZpbmdlbWF1dGlzbXVsLnJvIl0gICMgY2hlY2s6IDEydGggdHJpYWwgaXMgYXQgIjIwMjAtMTEtMjMgMTY6NDA6NTkgVVRDIg0KDQpwcmVfaWRzIDwtIGRhdGEuZnJhbWUocHJlID0gdW5pcXVlKHByZSRVc2VybmFtZSkpDQpwb3N0X2lkcyA8LSBkYXRhLmZyYW1lKHBvc3QgPSB1bmlxdWUocG9zdCRVc2VybmFtZSkpDQpsaXN0X2lkcyA8LSBkcGx5cjo6ZnVsbF9qb2luKHByZV9pZHMsIHBvc3RfaWRzLCBieSA9IGMoInByZSIgPSAicG9zdCIpLCBrZWVwID0gVFJVRSkNCmxpc3RfaWRzICAgICAgICAgICAgICAgICAgIA0KDQpjb21wbGV0ZV9pZHMgPC0NCiAgbGlzdF9pZHMgJT4lDQogIHRpZHlyOjpkcm9wX25hKCkgJT4lDQogIGRwbHlyOjptdXRhdGUocHJlID0gYXMuY2hhcmFjdGVyKHByZSkpICU+JQ0KICBkcGx5cjo6cHVsbChwcmUpDQogIA0KIyBLZWVwIG9ubHkgSURzIHRoYXQgaGF2ZSBib3RoIFBSRSBhbmQgUE9TVA0KcHJlIDwtDQogIHByZSAlPiUNCiAgZHBseXI6OmZpbHRlcihVc2VybmFtZSAlaW4lIGNvbXBsZXRlX2lkcykNCg0KcG9zdCA8LQ0KICBwb3N0ICU+JQ0KICBkcGx5cjo6ZmlsdGVyKFVzZXJuYW1lICVpbiUgY29tcGxldGVfaWRzKQ0KDQoNCg0KDQoNCg0KDQojIyMgUmFkaWNhbCBleGNsdXNpb25zIChrZWVwIG9ubHkgdGhlIGZpcnN0IDEyIG9ic2VydmF0aW9ucykNCnByZSA8LQ0KICBwcmUgJT4lDQogIGdyb3VwX2J5KFVzZXJuYW1lKSAlPiUgDQogIGRwbHlyOjpmaWx0ZXIocm93X251bWJlcigpIDw9IDEyKSANCg0KcG9zdCA8LQ0KICBwb3N0ICU+JQ0KICBncm91cF9ieShVc2VybmFtZSkgJT4lIA0KICBkcGx5cjo6ZmlsdGVyKHJvd19udW1iZXIoKSA8PSAxMikNCg0KYGBgDQoNCg0KDQojIEpvaW4gd2l0aCBJRCB0YWJsZQ0KDQpgYGB7cn0NCiMgc29tZSBVc2VybmFtZXMgYXJlIGVtYWlscywgc29tZSBhcmUgSURzIGluIGZvcm0gb2YgZW1haWxzDQpwcmUgPC0NCiAgcHJlICU+JQ0KICBkcGx5cjo6bXV0YXRlKGlkX3VzZXIgPSBVc2VybmFtZSkgJT4lDQogIGRwbHlyOjpzZWxlY3QoVXNlcm5hbWUsIGlkX3VzZXIsIGV2ZXJ5dGhpbmcoKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoaWRfdXNlciA9IHN0cmluZ3I6OnN0cl9yZW1vdmUoaWRfdXNlciwgIkAuKiIpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShpZF91c2VyID0gaWZfZWxzZShzdHJpbmdyOjpzdHJfZGV0ZWN0KGlkX3VzZXIsICJBMTB8R1NSIiksIGlkX3VzZXIsIE5BX2NoYXJhY3Rlcl8pKSAlPiUNCiAgZHBseXI6Om11dGF0ZShpZF91c2VyID0gc3RyaW5ncjo6c3RyX3JlbW92ZShpZF91c2VyLCAiXjArIiksICAgICAgICAgICAgICAjIHJlbW92ZSBsZWFkaW5nIHplcm9zDQogICAgICAgICAgICAgICAgaWRfdXNlciA9IHN0cmluZ3I6OnN0cl9yZW1vdmVfYWxsKGlkX3VzZXIsICJbWzpibGFuazpdXSIpLCAgIyByZW1vdmUgYW55IHdoaXRlIHNwYWNlDQogICAgICAgICAgICAgICAgaWRfdXNlciA9ICB0b3VwcGVyKGlkX3VzZXIpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShVc2VybmFtZSA9IHRvbG93ZXIoVXNlcm5hbWUpLA0KICAgICAgICAgICAgICAgIFVzZXJuYW1lID0gc3RyaW5ncjo6c3RyX3JlbW92ZV9hbGwoVXNlcm5hbWUsICJbWzpibGFuazpdXSIpKQ0KDQpwb3N0IDwtDQogIHBvc3QgJT4lDQogIGRwbHlyOjptdXRhdGUoaWRfdXNlciA9IFVzZXJuYW1lKSAlPiUNCiAgZHBseXI6OnNlbGVjdChVc2VybmFtZSwgaWRfdXNlciwgZXZlcnl0aGluZygpKSAlPiUNCiAgZHBseXI6Om11dGF0ZShpZF91c2VyID0gc3RyaW5ncjo6c3RyX3JlbW92ZShpZF91c2VyLCAiQC4qIikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKGlkX3VzZXIgPSBpZl9lbHNlKHN0cmluZ3I6OnN0cl9kZXRlY3QoaWRfdXNlciwgIkExMHxHU1IiKSwgaWRfdXNlciwgTkFfY2hhcmFjdGVyXykpICU+JQ0KICBkcGx5cjo6bXV0YXRlKGlkX3VzZXIgPSBzdHJpbmdyOjpzdHJfcmVtb3ZlKGlkX3VzZXIsICJeMCsiKSwgICAgICAgICAgICAgICMgcmVtb3ZlIGxlYWRpbmcgemVyb3MNCiAgICAgICAgICAgICAgICBpZF91c2VyID0gc3RyaW5ncjo6c3RyX3JlbW92ZV9hbGwoaWRfdXNlciwgIltbOmJsYW5rOl1dIiksICAjIHJlbW92ZSBhbnkgd2hpdGUgc3BhY2UNCiAgICAgICAgICAgICAgICBpZF91c2VyID0gIHRvdXBwZXIoaWRfdXNlcikpICU+JQ0KICBkcGx5cjo6bXV0YXRlKFVzZXJuYW1lID0gdG9sb3dlcihVc2VybmFtZSksDQogICAgICAgICAgICAgICAgVXNlcm5hbWUgPSBzdHJpbmdyOjpzdHJfcmVtb3ZlX2FsbChVc2VybmFtZSwgIltbOmJsYW5rOl1dIikpDQoNCiMgRXhjbHVkZSBzdWJqZWN0cyBmcm9tIEExMCAoUk1OIHNhbXBsZSkNCnByZSA8LQ0KICBwcmUgJT4lDQogIGRwbHlyOjpmaWx0ZXIoIXN0cl9kZXRlY3QoVXNlcm5hbWUsICJhMTAiKSkNCg0KcG9zdCA8LQ0KICBwb3N0ICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFzdHJfZGV0ZWN0KFVzZXJuYW1lLCAiYTEwIikpDQoNCg0KIyBNZXJnZQ0KcHJlX3VuaXRlZCA8LSBkcGx5cjo6bGVmdF9qb2luKHByZSwgaWRfZGYsIGJ5ID0gYygiVXNlcm5hbWUiID0gImVtYWlsIikpICU+JQ0KICBkcGx5cjo6bGVmdF9qb2luKC4sIGlkX2RmLCBieSA9IGMoImlkX3VzZXIiID0gImlkIiksIHN1ZmZpeCA9IGMoIiIsICIueCIpKSAlPiUNCiAgICBkcGx5cjo6bXV0YXRlKEdydXAgPSBkcGx5cjo6Y29hbGVzY2UoR3J1cCwgR3J1cC54KSwNCiAgICAgICAgICAgICAgICAgIENvbmQgPSBkcGx5cjo6Y29hbGVzY2UoQ29uZCwgQ29uZC54KSwNCiAgICAgICAgICAgICAgICAgIEV4cF90eXBlID0gZHBseXI6OmNvYWxlc2NlKEV4cF90eXBlLCBFeHBfdHlwZS54KSwNCiAgICAgICAgICAgICAgICAgIGVtYWlsID0gZHBseXI6OmNvYWxlc2NlKGVtYWlsLCBlbWFpbCkpICU+JQ0KICBkcGx5cjo6c2VsZWN0KCFjb250YWlucygiLngiKSkgJT4lDQogIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKEdydXApLCAhaXMubmEoQ29uZCkpDQogICAgICAgICAgICAgICAgDQpwb3N0X3VuaXRlZCA8LSBkcGx5cjo6bGVmdF9qb2luKHBvc3QsIGlkX2RmLCBieSA9IGMoIlVzZXJuYW1lIiA9ICJlbWFpbCIpKSAlPiUNCiAgZHBseXI6OmxlZnRfam9pbiguLCBpZF9kZiwgYnkgPSBjKCJpZF91c2VyIiA9ICJpZCIpLCBzdWZmaXggPSBjKCIiLCAiLngiKSkgJT4lDQogICAgZHBseXI6Om11dGF0ZShHcnVwID0gZHBseXI6OmNvYWxlc2NlKEdydXAsIEdydXAueCksDQogICAgICAgICAgICAgICAgICBDb25kID0gZHBseXI6OmNvYWxlc2NlKENvbmQsIENvbmQueCksDQogICAgICAgICAgICAgICAgICBFeHBfdHlwZSA9IGRwbHlyOjpjb2FsZXNjZShFeHBfdHlwZSwgRXhwX3R5cGUueCksDQogICAgICAgICAgICAgICAgICBlbWFpbCA9IGRwbHlyOjpjb2FsZXNjZShlbWFpbCwgZW1haWwpKSAlPiUNCiAgZHBseXI6OnNlbGVjdCghY29udGFpbnMoIi54IikpICU+JQ0KICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShHcnVwKSwgIWlzLm5hKENvbmQpKQ0KDQojIFRvIGtlZXAgcmVzdCBvZiBjb2RlIHdvcmtpbmcNCnByZSA8LSBwcmVfdW5pdGVkDQpwb3N0IDwtIHBvc3RfdW5pdGVkDQoNCm1lcmdlZF91bml0ZWQgPC0gcmJpbmQocHJlX3VuaXRlZCwgcG9zdF91bml0ZWQpICU+JQ0KICBkcGx5cjo6c2VsZWN0KFVzZXJuYW1lLCBHcnVwLCBDb25kKSAlPiUNCiAgZHBseXI6OmRpc3RpbmN0KFVzZXJuYW1lLCBHcnVwLCBDb25kLCAua2VlcF9hbGwgPSBUUlVFKQ0KDQpgYGANCg0KDQoNCiMgQ29tcHV0ZSBzY29yZXMNCg0KYGBge3Igc2NvcmluZ30NCiMgQ29tcHV0ZSBzY29yZXMgfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn4NCiMgdXRpbGl6YW0gZG9hciBEZWNpZGVudDogdW5mYWlyID0gMTctMjQgKDYgb2ZlcnRlIGRpZmVyaXRlKTsgZmFpciA9IDQ5LTU0ICg2IG9mZXJ0ZSBkaWZlcml0ZSkNCg0KIyBEZWZpbmUgRmFpci9VbmZhaXINCnByZSA8LQ0KICBwcmUgJT4lDQogIGRwbHlyOjptdXRhdGUoVHlwZSA9IGN1dChEZWNpZGVudCwgYnJlYWtzID0gYygtSW5mLCAzMCwgSW5mKSwgbGFiZWxzID0gYygiVW5mYWlyIiwgIkZhaXIiKSkpDQoNCnBvc3QgPC0NCiAgcG9zdCAlPiUNCiAgZHBseXI6Om11dGF0ZShUeXBlID0gY3V0KERlY2lkZW50LCBicmVha3MgPSBjKC1JbmYsIDMwLCBJbmYpLCBsYWJlbHMgPSBjKCJVbmZhaXIiLCAiRmFpciIpKSkNCg0KIyBDb21wdXRlIFBlcmNlbnQgc2NvcmVzDQpwcmVfc2NvcmVzIDwtDQogIHByZSAlPiUNCiAgZHBseXI6OmFkZF9jb3VudChVc2VybmFtZSwgVHlwZSwgbmFtZSA9ICJuX1R5cGUiKSAlPiUNCiAgZHBseXI6OmNvdW50KFVzZXJuYW1lLCBUeXBlLCBBY2NlcHRlZCwgbl9UeXBlLCBuYW1lID0gIm5fQWNjZXB0ZWRfVHlwZSIsIC5kcm9wID0gRkFMU0UpICU+JSAgICMgbmVlZCAuZHJvcCA9IEZBTFNFIGZvciBtaXNzaW5nIGZhY3RvciBsZXZlbHMgbGVhZGluZyB0byAwJSBQZXJjZW50YWdlcw0KICBkcGx5cjo6bXV0YXRlKFBlcmNlbnQgPSAxMDAgKiBuX0FjY2VwdGVkX1R5cGUgLyBuX1R5cGUpICU+JSAgDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lDQogIHRpZHlyOjpjb21wbGV0ZShVc2VybmFtZSwgVHlwZSwgQWNjZXB0ZWQsIGZpbGwgPSBsaXN0KG5fVHlwZSA9IDAsIG5fQWNjZXB0ZWRfVHlwZSA9IDAsIFBlcmNlbnQgPSAwKSkgJT4lICAjIGZvciBtaXNzaW5nIGZhY3RvciBsZXZlbHMgbGVhZGluZyB0byAwJSBQZXJjZW50YWdlcw0KICBkcGx5cjo6ZmlsdGVyKEFjY2VwdGVkID09ICJZIikgJT4lDQogIGRwbHlyOjptdXRhdGUoUHJlUG9zdCA9IHJlcCgiUHJlIiwgbigpKSkgJT4lDQogIGRwbHlyOjptdXRhdGUoUHJlUG9zdD0gZmFjdG9yKFByZVBvc3QsIGxldmVscyA9IGMoIlByZSIsICJQb3N0IikpKSANCg0KcG9zdF9zY29yZXMgPC0NCiAgcG9zdCAlPiUNCiAgZHBseXI6OmFkZF9jb3VudChVc2VybmFtZSwgVHlwZSwgbmFtZSA9ICJuX1R5cGUiKSAlPiUNCiAgZHBseXI6OmNvdW50KFVzZXJuYW1lLCBUeXBlLCBBY2NlcHRlZCwgbl9UeXBlLCBuYW1lID0gIm5fQWNjZXB0ZWRfVHlwZSIsIC5kcm9wID0gRkFMU0UpICU+JSAgICMgbmVlZCAuZHJvcCA9IEZBTFNFIGZvciBtaXNzaW5nIGZhY3RvciBsZXZlbHMgbGVhZGluZyB0byAwJSBQZXJjZW50YWdlcw0KICBkcGx5cjo6bXV0YXRlKFBlcmNlbnQgPSAxMDAgKiBuX0FjY2VwdGVkX1R5cGUgLyBuX1R5cGUpICU+JSAgDQogIGRwbHlyOjp1bmdyb3VwKCkgJT4lDQogIHRpZHlyOjpjb21wbGV0ZShVc2VybmFtZSwgVHlwZSwgQWNjZXB0ZWQsIGZpbGwgPSBsaXN0KG5fVHlwZSA9IDAsIG5fQWNjZXB0ZWRfVHlwZSA9IDAsIFBlcmNlbnQgPSAwKSkgJT4lICAjIGZvciBtaXNzaW5nIGZhY3RvciBsZXZlbHMgbGVhZGluZyB0byAwJSBQZXJjZW50YWdlcw0KICBkcGx5cjo6ZmlsdGVyKEFjY2VwdGVkID09ICJZIikgJT4lDQogIGRwbHlyOjptdXRhdGUoUHJlUG9zdCA9IHJlcCgiUG9zdCIsIG4oKSkpICU+JQ0KICBkcGx5cjo6bXV0YXRlKFByZVBvc3QgPSBmYWN0b3IoUHJlUG9zdCwgbGV2ZWxzID0gYygiUHJlIiwgIlBvc3QiKSkpDQogIA0KDQptZXJnZWRfc2NvcmVzIDwtIHJiaW5kKHByZV9zY29yZXMsIHBvc3Rfc2NvcmVzKSAlPiUNCiAgZHBseXI6OmxlZnRfam9pbiguLCBtZXJnZWRfdW5pdGVkLCBieSA9ICJVc2VybmFtZSIpDQoNCiMgIyBNZXJnZSAgLSBPTEQNCiMgbWVyZ2VkX3Njb3JlcyA8LSByYmluZChwcmVfc2NvcmVzLCBwb3N0X3Njb3JlcykNCiMgDQojIG1lcmdlZF9zY29yZXMkVXNlcm5hbWUgPC0gdG9sb3dlcihtZXJnZWRfc2NvcmVzJFVzZXJuYW1lKSAgICMgZW1haWxzIHRvIGxvd2VyIGxldHRlcnMgdG8gbWF0Y2ggb24NCiMgZ3NyX2RmJGVtYWlsIDwtIHRvbG93ZXIoZ3NyX2RmJGVtYWlsKQ0KIyBybW5fZGYkZW1haWwgPC0gdG9sb3dlcihybW5fZGYkZW1haWwpDQojIA0KIyBtZXJnZWRfc2NvcmVzX2dzciA8LSBkcGx5cjo6bGVmdF9qb2luKG1lcmdlZF9zY29yZXMsIGdzcl9kZiwgYnkgPSBjKCJVc2VybmFtZSIgPSAiZW1haWwiKSkgICAgICMgTWVyZ2Ugd2l0aCBlbWFpbHMvY29uZA0KIyBtZXJnZWRfc2NvcmVzX3JtbiA8LSBkcGx5cjo6bGVmdF9qb2luKG1lcmdlZF9zY29yZXMsIHJtbl9kZiwgYnkgPSBjKCJVc2VybmFtZSIgPSAiZW1haWwiKSkgICAgICMgTWVyZ2Ugd2l0aCBlbWFpbHMvY29uZA0KIyANCiMgbWVyZ2VkX3Njb3Jlc19nc3Jfcm1uIDwtDQojICAgZHBseXI6OmxlZnRfam9pbihtZXJnZWRfc2NvcmVzX2dzciwgbWVyZ2VkX3Njb3Jlc19ybW4sIGJ5ID0gYygiVXNlcm5hbWUiLCAiVHlwZSIsICJBY2NlcHRlZCIsICJuX1R5cGUiLCAibl9BY2NlcHRlZF9UeXBlIiwgIlBlcmNlbnQiLCAiUHJlUG9zdCIpKSAlPiUNCiMgICBkcGx5cjo6bXV0YXRlKENvbmQgPSBkcGx5cjo6Y29hbGVzY2UoQ29uZC54LCBDb25kLnkpKSAlPiUNCiMgICBkcGx5cjo6bXV0YXRlKElEID0gZHBseXI6OmNvYWxlc2NlKElELngsIElELnkpKQ0KYGBgDQoNCg0KDQoNCiMgR2VuZXJhbCBwb3ANCg0KYGBge3IgcGxvdDEsIGZpZy5oZWlnaHQ9NywgZmlnLndpZHRoPTksIGZpZy5zZXA9YygnXFxuZXdsaW5lJywnXFxuZXdsaW5lJyksIHdhcm5pbmc9RkFMU0V9DQptZXJnZWRfc2NvcmVzICU+JQ0KICBkcGx5cjo6ZmlsdGVyKEdydXAgPT0gInBvcCBnZW4iLCBDb25kID09ICJFWFBFUklNRU5UQUwiKSAlPiUNCiAgICBnZ3N0YXRzcGxvdDo6Z3JvdXBlZF9nZ3dpdGhpbnN0YXRzKA0KICAgICAgZGF0YSA9IC4sDQogICAgICB4ID0gUHJlUG9zdCwNCiAgICAgIHkgPSBQZXJjZW50LA0KICAgICAgZ3JvdXBpbmcudmFyID0gVHlwZSwNCiAgICAgIHR5cGUgPSAicGFyYW1ldHJpYyIsDQogICAgICBwYWlyd2lzZS5jb21wYXJpc29ucyA9IFRSVUUsDQogICAgICBwYWlyd2lzZS5kaXNwbGF5ID0gImFsbCIsDQogICAgICBhbm5vdGF0aW9uLmFyZ3MgPSBsaXN0KHRpdGxlID0gIlBvcHVsYXRpZSBHZW5lYXJhbGEgLSBUUiIpKQ0KDQptZXJnZWRfc2NvcmVzICU+JQ0KICBkcGx5cjo6ZmlsdGVyKEdydXAgPT0gInBvcCBnZW4iLCBDb25kID09ICJDT05UUk9MIikgJT4lDQogICAgZ2dzdGF0c3Bsb3Q6Omdyb3VwZWRfZ2d3aXRoaW5zdGF0cygNCiAgICAgIGRhdGEgPSAuLA0KICAgICAgeCA9IFByZVBvc3QsDQogICAgICB5ID0gUGVyY2VudCwNCiAgICAgIGdyb3VwaW5nLnZhciA9IFR5cGUsDQogICAgICB0eXBlID0gInBhcmFtZXRyaWMiLA0KICAgICAgcGFpcndpc2UuY29tcGFyaXNvbnMgPSBUUlVFLA0KICAgICAgcGFpcndpc2UuZGlzcGxheSA9ICJhbGwiLA0KICAgICAgYW5ub3RhdGlvbi5hcmdzID0gbGlzdCh0aXRsZSA9ICJQb3B1bGF0aWUgR2VuZWFyYWxhIC0gQ1RSTCIpKQ0KYGBgDQoNCg0KIyBQVFNEDQoNCmBgYHtyIHBsb3QyLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD05LCBmaWcuc2VwPWMoJ1xcbmV3bGluZScsJ1xcbmV3bGluZScpLCB3YXJuaW5nPUZBTFNFfQ0KbWVyZ2VkX3Njb3JlcyAlPiUNCiAgZHBseXI6OmZpbHRlcihHcnVwID09ICJQVFNEIiwgQ29uZCA9PSAiRVhQRVJJTUVOVEFMIikgJT4lDQogICAgZ2dzdGF0c3Bsb3Q6Omdyb3VwZWRfZ2d3aXRoaW5zdGF0cygNCiAgICAgIGRhdGEgPSAuLA0KICAgICAgeCA9IFByZVBvc3QsDQogICAgICB5ID0gUGVyY2VudCwNCiAgICAgIGdyb3VwaW5nLnZhciA9IFR5cGUsDQogICAgICB0eXBlID0gIm5wIiwNCiAgICAgIHBhaXJ3aXNlLmNvbXBhcmlzb25zID0gVFJVRSwNCiAgICAgIHBhaXJ3aXNlLmRpc3BsYXkgPSAiYWxsIiwNCiAgICAgIGFubm90YXRpb24uYXJncyA9IGxpc3QodGl0bGUgPSAiUFRTRCAtIFRSIikpDQoNCm1lcmdlZF9zY29yZXMgJT4lDQogIGRwbHlyOjpmaWx0ZXIoR3J1cCA9PSAiUFRTRCIsIENvbmQgPT0gIkNPTlRST0wiKSAlPiUNCiAgICBnZ3N0YXRzcGxvdDo6Z3JvdXBlZF9nZ3dpdGhpbnN0YXRzKA0KICAgICAgZGF0YSA9IC4sDQogICAgICB4ID0gUHJlUG9zdCwNCiAgICAgIHkgPSBQZXJjZW50LA0KICAgICAgZ3JvdXBpbmcudmFyID0gVHlwZSwNCiAgICAgIHR5cGUgPSAibnAiLA0KICAgICAgcGFpcndpc2UuY29tcGFyaXNvbnMgPSBUUlVFLA0KICAgICAgcGFpcndpc2UuZGlzcGxheSA9ICJhbGwiLA0KICAgICAgYW5ub3RhdGlvbi5hcmdzID0gbGlzdCh0aXRsZSA9ICJQVFNEIC0gQ1RSTCIpKQ0KYGBgDQoNCg0KIyBCdXJub3V0DQoNCmBgYHtyIHBsb3QzLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD05LCBmaWcuc2VwPWMoJ1xcbmV3bGluZScsJ1xcbmV3bGluZScpLCB3YXJuaW5nPUZBTFNFfQ0KbWVyZ2VkX3Njb3JlcyAlPiUNCiAgZHBseXI6OmZpbHRlcihHcnVwID09ICJCdXJub3V0IiwgQ29uZCA9PSAiRVhQRVJJTUVOVEFMIikgJT4lDQogICAgZ2dzdGF0c3Bsb3Q6Omdyb3VwZWRfZ2d3aXRoaW5zdGF0cygNCiAgICAgIGRhdGEgPSAuLA0KICAgICAgeCA9IFByZVBvc3QsDQogICAgICB5ID0gUGVyY2VudCwNCiAgICAgIGdyb3VwaW5nLnZhciA9IFR5cGUsDQogICAgICB0eXBlID0gIm5wIiwNCiAgICAgIHBhaXJ3aXNlLmNvbXBhcmlzb25zID0gVFJVRSwNCiAgICAgIHBhaXJ3aXNlLmRpc3BsYXkgPSAiYWxsIiwNCiAgICAgIGFubm90YXRpb24uYXJncyA9IGxpc3QodGl0bGUgPSAiQnVybm91dCAtIFRSIikpDQoNCm1lcmdlZF9zY29yZXMgJT4lDQogIGRwbHlyOjpmaWx0ZXIoR3J1cCA9PSAiQnVybm91dCIsIENvbmQgPT0gIkNPTlRST0wiKSAlPiUNCiAgICBnZ3N0YXRzcGxvdDo6Z3JvdXBlZF9nZ3dpdGhpbnN0YXRzKA0KICAgICAgZGF0YSA9IC4sDQogICAgICB4ID0gUHJlUG9zdCwNCiAgICAgIHkgPSBQZXJjZW50LA0KICAgICAgZ3JvdXBpbmcudmFyID0gVHlwZSwNCiAgICAgIHR5cGUgPSAibnAiLA0KICAgICAgcGFpcndpc2UuY29tcGFyaXNvbnMgPSBUUlVFLA0KICAgICAgcGFpcndpc2UuZGlzcGxheSA9ICJhbGwiLA0KICAgICAgYW5ub3RhdGlvbi5hcmdzID0gbGlzdCh0aXRsZSA9ICJCdXJub3V0IC0gQ1RSTCIpKQ0KYGBgDQoNCg0KDQoNCjwhLS0gU2Vzc2lvbiBJbmZvIGFuZCBMaWNlbnNlIC0tPg0KDQo8YnI+DQoNCiMgU2Vzc2lvbiBJbmZvDQpgYGB7ciBzZXNzaW9uX2luZm8sIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9ICdtYXJrdXAnfQ0Kc2Vzc2lvbkluZm8oKSAgICANCmBgYA0KDQo8IS0tIEZvb3RlciAtLT4NCiZuYnNwOw0KPGhyIC8+DQo8cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyOyI+QSB3b3JrIGJ5IDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9DbGF1ZGl1UGFwYXN0ZXJpLyI+Q2xhdWRpdSBQYXBhc3Rlcmk8L2E+PC9wPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPjxzcGFuIHN0eWxlPSJjb2xvcjogIzgwODA4MDsiPjxlbT5jbGF1ZGl1LnBhcGFzdGVyaUBnbWFpbC5jb208L2VtPjwvc3Bhbj48L3A+DQombmJzcDsNCg==