rm(list = ls())

#install.packages("sna")
library(openalexR)
library(tidyverse)
require(igraph)

g <- make_graph("Zachary")
plot(g)

gmat <- as_adjacency_matrix(g, type = "both", sparse = FALSE)
gmat
##       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17]
##  [1,]    0    1    1    1    1    1    1    1    1     0     1     1     1     1     0     0     0
##  [2,]    1    0    1    1    0    0    0    1    0     0     0     0     0     1     0     0     0
##  [3,]    1    1    0    1    0    0    0    1    1     1     0     0     0     1     0     0     0
##  [4,]    1    1    1    0    0    0    0    1    0     0     0     0     1     1     0     0     0
##  [5,]    1    0    0    0    0    0    1    0    0     0     1     0     0     0     0     0     0
##  [6,]    1    0    0    0    0    0    1    0    0     0     1     0     0     0     0     0     1
##  [7,]    1    0    0    0    1    1    0    0    0     0     0     0     0     0     0     0     1
##  [8,]    1    1    1    1    0    0    0    0    0     0     0     0     0     0     0     0     0
##  [9,]    1    0    1    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [10,]    0    0    1    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [11,]    1    0    0    0    1    1    0    0    0     0     0     0     0     0     0     0     0
## [12,]    1    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [13,]    1    0    0    1    0    0    0    0    0     0     0     0     0     0     0     0     0
## [14,]    1    1    1    1    0    0    0    0    0     0     0     0     0     0     0     0     0
## [15,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [16,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [17,]    0    0    0    0    0    1    1    0    0     0     0     0     0     0     0     0     0
## [18,]    1    1    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [19,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [20,]    1    1    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [21,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [22,]    1    1    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [23,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [24,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [25,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [26,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [27,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [28,]    0    0    1    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [29,]    0    0    1    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [30,]    0    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [31,]    0    1    0    0    0    0    0    0    1     0     0     0     0     0     0     0     0
## [32,]    1    0    0    0    0    0    0    0    0     0     0     0     0     0     0     0     0
## [33,]    0    0    1    0    0    0    0    0    1     0     0     0     0     0     1     1     0
## [34,]    0    0    0    0    0    0    0    0    1     1     0     0     0     1     1     1     0
##       [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26] [,27] [,28] [,29] [,30] [,31] [,32]
##  [1,]     1     0     1     0     1     0     0     0     0     0     0     0     0     0     1
##  [2,]     1     0     1     0     1     0     0     0     0     0     0     0     0     1     0
##  [3,]     0     0     0     0     0     0     0     0     0     0     1     1     0     0     0
##  [4,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
##  [5,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
##  [6,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
##  [7,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
##  [8,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
##  [9,]     0     0     0     0     0     0     0     0     0     0     0     0     0     1     0
## [10,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [11,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [12,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [13,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [14,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [15,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [16,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [17,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [18,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [19,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [20,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [21,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [22,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [23,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [24,]     0     0     0     0     0     0     0     0     1     0     1     0     1     0     0
## [25,]     0     0     0     0     0     0     0     0     1     0     1     0     0     0     1
## [26,]     0     0     0     0     0     0     1     1     0     0     0     0     0     0     1
## [27,]     0     0     0     0     0     0     0     0     0     0     0     0     1     0     0
## [28,]     0     0     0     0     0     0     1     1     0     0     0     0     0     0     0
## [29,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     1
## [30,]     0     0     0     0     0     0     1     0     0     1     0     0     0     0     0
## [31,]     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
## [32,]     0     0     0     0     0     0     0     1     1     0     0     1     0     0     0
## [33,]     0     1     0     1     0     1     1     0     0     0     0     0     1     1     1
## [34,]     0     1     1     1     0     1     1     0     0     1     1     1     1     1     1
##       [,33] [,34]
##  [1,]     0     0
##  [2,]     0     0
##  [3,]     1     0
##  [4,]     0     0
##  [5,]     0     0
##  [6,]     0     0
##  [7,]     0     0
##  [8,]     0     0
##  [9,]     1     1
## [10,]     0     1
## [11,]     0     0
## [12,]     0     0
## [13,]     0     0
## [14,]     0     1
## [15,]     1     1
## [16,]     1     1
## [17,]     0     0
## [18,]     0     0
## [19,]     1     1
## [20,]     0     1
## [21,]     1     1
## [22,]     0     0
## [23,]     1     1
## [24,]     1     1
## [25,]     0     0
## [26,]     0     0
## [27,]     0     1
## [28,]     0     1
## [29,]     0     1
## [30,]     1     1
## [31,]     1     1
## [32,]     1     1
## [33,]     0     1
## [34,]     1     0
# changing V
V(g)$size = betweenness(g, normalized = T, directed = FALSE) * 60 + 15  #after some trial and error
plot(g, mode = "undirected")

set.seed(2345)
l <- layout_with_mds(g)  #https://igraph.org/r/doc/layout_with_mds.html
plot(g, layout = l)

l  #let us take a look at the coordinates
##               [,1]         [,2]
##  [1,]  1.070931935 -0.172458113
##  [2,]  0.732844464  0.754023309
##  [3,]  0.100582299  0.397693607
##  [4,]  0.708246655  0.570205545
##  [5,]  1.816293170 -0.120778206
##  [6,]  1.881329566 -0.135518854
##  [7,]  1.881329566 -0.135518854
##  [8,]  0.812606714  0.472619437
##  [9,] -0.003769996  0.615513628
## [10,] -0.685680315  0.621065149
## [11,]  1.816293170 -0.120778206
## [12,]  1.621247830 -0.065820692
## [13,]  1.637845123  0.001789972
## [14,]  0.067317230  0.681421148
## [15,] -1.796316404  0.351417630
## [16,] -1.796316404  0.351417630
## [17,]  2.775260452 -0.124317652
## [18,]  1.616210024  0.182510197
## [19,] -1.796316404  0.351417630
## [20,]  0.048362858  0.566654982
## [21,] -1.796316404  0.351417630
## [22,]  1.616210024  0.182510197
## [23,] -1.796316404  0.351417630
## [24,] -1.891240567 -0.799574907
## [25,] -0.258345165 -2.006346563
## [26,] -0.360530857 -2.131642875
## [27,] -1.865177401  0.128596564
## [28,] -0.760226022 -0.529392331
## [29,] -0.710979936 -0.299960128
## [30,] -1.898426916 -0.149398746
## [31,] -0.568691923  0.804189411
## [32,] -0.048136037 -0.870967614
## [33,] -1.023681000 -0.035802363
## [34,] -1.146442924 -0.037605192
l[1, 1] <- 4
l[34, 1] <- -3.5
plot(g, layout = l)

## making network collaberations data, from JT's tutorial


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

scholars <- fload("C:/Users/kalle/OneDrive/Documenten/REMA/Jaar 2/Social Networks/KS_labjournal/data/processed/scholars_20240924.rda")

#functie maken
fcolnet <- function(data = scholars, university = "RU", discipline = "sociology", waves = list(c(2015,
    2018), c(2019, 2023)), type = c("first")) {

    # step 1
    demographics <- do.call(rbind.data.frame, data$demographics)
    demographics <- demographics %>%
        mutate(Universiteit1.22 = replace(Universiteit1.22, is.na(Universiteit1.22), ""), Universiteit2.22 = replace(Universiteit2.22,
            is.na(Universiteit2.22), ""), Universiteit1.24 = replace(Universiteit1.24, is.na(Universiteit1.24),
            ""), Universiteit2.24 = replace(Universiteit2.24, is.na(Universiteit2.24), ""), discipline.22 = replace(discipline.22,
            is.na(discipline.22), ""), discipline.24 = replace(discipline.24, is.na(discipline.24), ""))

    sample <- which((demographics$Universiteit1.22 %in% university | demographics$Universiteit2.22 %in%
        university | demographics$Universiteit1.24 %in% university | demographics$Universiteit2.24 %in%
        university) & (demographics$discipline.22 %in% discipline | demographics$discipline.24 %in% discipline))

    demographics_soc <- demographics[sample, ]
    scholars_sel <- lapply(scholars, "[", sample)

    # step 2
    ids <- demographics_soc$au_id
    nwaves <- length(waves)
    nets <- array(0, dim = c(nwaves, length(ids), length(ids)), dimnames = list(wave = 1:nwaves, ids,
        ids))
    dimnames(nets)

    # step 3
    df_works <- tibble(works_id = unlist(lapply(scholars_sel$work, function(l) l$id)), works_author = unlist(lapply(scholars_sel$work,
        function(l) l$author), recursive = FALSE), works_year = unlist(lapply(scholars_sel$work, function(l) l$publication_year),
        recursive = FALSE))

    df_works <- df_works[!duplicated(df_works), ]

    # step 4
    if (type == "first") {
        for (j in 1:nwaves) {
            df_works_w <- df_works[df_works$works_year >= waves[[j]][1] & df_works$works_year <= waves[[j]][2],
                ]
            for (i in 1:nrow(df_works_w)) {
                ego <- df_works_w$works_author[i][[1]]$au_id[1]
                alters <- df_works_w$works_author[i][[1]]$au_id[-1]
                if (sum(ids %in% ego) > 0 & sum(ids %in% alters) > 0) {
                  nets[j, which(ids %in% ego), which(ids %in% alters)] <- 1
                }
            }
        }
    }

    if (type == "last") {
        for (j in 1:nwaves) {
            df_works_w <- df_works[df_works$works_year >= waves[[j]][1] & df_works$works_year <= waves[[j]][2],
                ]
            for (i in 1:nrow(df_works_w)) {
                ego <- rev(df_works_w$works_author[i][[1]]$au_id)[1]
                alters <- rev(df_works_w$works_author[i][[1]]$au_id)[-1]
                if (sum(ids %in% ego) > 0 & sum(ids %in% alters) > 0) {
                  nets[j, which(ids %in% ego), which(ids %in% alters)] <- 1
                }
            }
        }
    }

    if (type == "all") {
        for (j in 1:nwaves) {
            df_works_w <- df_works[df_works$works_year >= waves[[j]][1] & df_works$works_year <= waves[[j]][2],
                ]
            for (i in 1:nrow(df_works_w)) {
                egos <- df_works_w$works_author[i][[1]]$au_id
                if (sum(ids %in% egos) > 0) {
                  nets[j, which(ids %in% egos), which(ids %in% egos)] <- 1
                }
            }
        }
    }
    output <- list()
    output$data <- scholars_sel
    output$nets <- nets
    return(output)
}

1 Descriptive statistics for the network

#functie gebruiken

data <- fcolnet(data = scholars, 
                university = "RU", 
                discipline = "sociology", 
                waves = list(c(2015, 2018), c(2019, 2023)), 
                type = c("all"))

#first wave
net_w1 <- data$nets[1,,]
diag(net_w1) <- 0
g <- graph_from_adjacency_matrix(net_w1, mode = "undirected", diag = FALSE)

#density
density <- edge_density(g)
density
## [1] 0.04326531
#degree centrality
#ego level
degree(g)
## https://openalex.org/A5011326378 https://openalex.org/A5014129369 https://openalex.org/A5023395007 
##                                0                                3                                0 
## https://openalex.org/A5068642001 https://openalex.org/A5074062335 https://openalex.org/A5018242597 
##                                1                                0                                0 
## https://openalex.org/A5030977100 https://openalex.org/A5007673492 https://openalex.org/A5016107698 
##                                3                                7                                1 
## https://openalex.org/A5062608377 https://openalex.org/A5002388922 https://openalex.org/A5023494442 
##                                2                                2                                1 
## https://openalex.org/A5046746723 https://openalex.org/A5017382943 https://openalex.org/A5035350135 
##                                0                                0                               16 
## https://openalex.org/A5079372810 https://openalex.org/A5048988743 https://openalex.org/A5027461314 
##                                3                                5                               13 
## https://openalex.org/A5035502020 https://openalex.org/A5087380803 https://openalex.org/A5066699568 
##                                6                                4                                4 
## https://openalex.org/A5060015711 https://openalex.org/A5017017044 https://openalex.org/A5050987926 
##                                4                                8                                2 
## https://openalex.org/A5019030264 https://openalex.org/A5009655338 https://openalex.org/A5026217132 
##                                0                                0                                0 
## https://openalex.org/A5001803910 https://openalex.org/A5030092568 https://openalex.org/A5050683616 
##                                0                                0                                1 
## https://openalex.org/A5031371982 https://openalex.org/A5023362052 https://openalex.org/A5071959536 
##                                0                                0                                1 
## https://openalex.org/A5093927073 https://openalex.org/A5055096981 https://openalex.org/A5031002485 
##                                0                                0                                0 
## https://openalex.org/A5020765315 https://openalex.org/A5065130106 https://openalex.org/A5080235042 
##                                1                                0                                0 
## https://openalex.org/A5038009917 https://openalex.org/A5047687982 https://openalex.org/A5057934803 
##                                1                                2                                2 
## https://openalex.org/A5063338887 https://openalex.org/A5045572082 https://openalex.org/A5085493990 
##                                2                                2                                0 
## https://openalex.org/A5003892082 https://openalex.org/A5047911137 https://openalex.org/A5017637321 
##                                7                                0                                2 
## https://openalex.org/A5068000059 https://openalex.org/A5013258554 
##                                0                                0
#network level
mean(degree(g, mode = "all"))
## [1] 2.12
#transitivity
transitivity(g, type = "undirected")
## [1] 0.2743902
#plot
test_w1 <- igraph::graph_from_adjacency_matrix(
  data$nets[1,,], #for this example I take the first wave of data. (thus I select the array of networks and take the first matrix)
  mode = c("undirected"),
  weighted = NULL,
  diag = FALSE,
  add.colnames = NULL,
  add.rownames = NULL
)
## Warning: Same attribute for columns and rows, row names are ignored
plot(test_w1,
  vertex.label = NA,
  edge.width = 0.2,
  edge.arrow.size =0.2)

### second wave

#duidelijk meer density, centrality en minder isolates.

net_w2 <- data$nets[2,,]
diag(net_w2) <- 0
g2 <- graph_from_adjacency_matrix(net_w2, mode = "undirected", diag = FALSE)

#density
density2 <- edge_density(g2)
density2
## [1] 0.07428571
#degree centrality
#ego level
degree (g2)
## https://openalex.org/A5011326378 https://openalex.org/A5014129369 https://openalex.org/A5023395007 
##                                0                                2                                1 
## https://openalex.org/A5068642001 https://openalex.org/A5074062335 https://openalex.org/A5018242597 
##                                1                                1                                8 
## https://openalex.org/A5030977100 https://openalex.org/A5007673492 https://openalex.org/A5016107698 
##                                3                                9                                5 
## https://openalex.org/A5062608377 https://openalex.org/A5002388922 https://openalex.org/A5023494442 
##                                5                                2                                3 
## https://openalex.org/A5046746723 https://openalex.org/A5017382943 https://openalex.org/A5035350135 
##                                3                                0                               15 
## https://openalex.org/A5079372810 https://openalex.org/A5048988743 https://openalex.org/A5027461314 
##                                4                                7                               14 
## https://openalex.org/A5035502020 https://openalex.org/A5087380803 https://openalex.org/A5066699568 
##                               13                                8                                6 
## https://openalex.org/A5060015711 https://openalex.org/A5017017044 https://openalex.org/A5050987926 
##                                7                                3                                2 
## https://openalex.org/A5019030264 https://openalex.org/A5009655338 https://openalex.org/A5026217132 
##                                0                                2                                2 
## https://openalex.org/A5001803910 https://openalex.org/A5030092568 https://openalex.org/A5050683616 
##                                3                                2                                1 
## https://openalex.org/A5031371982 https://openalex.org/A5023362052 https://openalex.org/A5071959536 
##                                2                                2                                2 
## https://openalex.org/A5093927073 https://openalex.org/A5055096981 https://openalex.org/A5031002485 
##                                0                                4                                3 
## https://openalex.org/A5020765315 https://openalex.org/A5065130106 https://openalex.org/A5080235042 
##                                4                                3                                3 
## https://openalex.org/A5038009917 https://openalex.org/A5047687982 https://openalex.org/A5057934803 
##                                1                                1                                1 
## https://openalex.org/A5063338887 https://openalex.org/A5045572082 https://openalex.org/A5085493990 
##                                2                                4                                3 
## https://openalex.org/A5003892082 https://openalex.org/A5047911137 https://openalex.org/A5017637321 
##                               14                                0                                0 
## https://openalex.org/A5068000059 https://openalex.org/A5013258554 
##                                1                                0
#network level
mean(degree(g2, mode = "all"))
## [1] 3.64
#transitivity
transitivity(g2, type = "undirected")
## [1] 0.3226891
test_w2 <- igraph::graph_from_adjacency_matrix(
  data$nets[2,,],
  mode = c("undirected"),
  weighted = NULL,
  diag = FALSE,
  add.colnames = NULL,
  add.rownames = NULL
)
## Warning: Same attribute for columns and rows, row names are ignored
plot(test_w2,
  vertex.label = NA,
  edge.width = 0.2,
  edge.arrow.size =0.2)

2 Ego characteristics

# Scraping the # of citations of all papers published during per wave 


df_scholars <- do.call(rbind, scholars$demographics)

mail = "kalle.stoffers@ru.nl"


#empty list
citations_per_wave <- list()


for (author in df_scholars$au_id[1:675]) {

#fetch papers per authors
papers <- oa_fetch(
  entity = "works",
  author.id = author,
  mailto = mail)

# check if papers is NULL or has 0 rows
  if (is.null(papers) || nrow(papers) == 0) {
    # fill with 0 citations for both waves
    citations <- tibble(
      au_id = author,
      citations_w1 = 0,
      citations_w2 = 0
    )
  } else {
    # wave 1 citations
    citations_w1 <- papers |>
      filter(publication_year >= 2015 & publication_year <= 2018) |>
      summarise(citations_w1 = sum(cited_by_count, na.rm = TRUE))

    # wave 2 citations
    citations_w2 <- papers |>
      filter(publication_year >= 2019 & publication_year <= 2023) |>
      summarise(citations_w2 = sum(cited_by_count, na.rm = TRUE))

    # handle case where one of the summaries might return 0 rows
    if (nrow(citations_w1) == 0) citations_w1 <- tibble(citations_w1 = 0)
    if (nrow(citations_w2) == 0) citations_w2 <- tibble(citations_w2 = 0)

#join the two
citations <- merge(citations_w1, citations_w2)

citations <- citations|>
  mutate(au_id = author) |>
  relocate(au_id)
}
  
citations_per_wave[[author]] <- citations

}
  

#merge met originele dataset
citations_df <- bind_rows(citations_per_wave)

df <- left_join(df_scholars, citations_df, by = "au_id")


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

fsave(df)
#descriptives citations

df<- fload("~/REMA/Jaar 2/Social Networks/KS_labjournal/data/processed/df_20250929.rda")


summary(df$citations_w1)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0     0.0    45.0   256.8   264.0 17808.0
summary (df$citations_w2)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0    12.0    64.0   174.5   181.0  5030.0
#remove outlier
df<- df |> filter(citations_w1 <= 6000)
summary (df$citations_w2)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0    12.0    64.0   167.3   180.8  4836.0
df_long <- df|>
  pivot_longer(cols = c(citations_w1, citations_w2),
               names_to = "wave",
               names_prefix = "citations_w",
               values_to = "citations") |>
  mutate(wave = as.factor(wave))

ggplot(df_long, aes(x = citations, color = wave)) + geom_density()

LS0tDQp0aXRsZTogIldlZWsgNCINCmF1dGhvcjogIkthbGxlIFN0b2ZmZXJzIg0KZGF0ZTogIjIwMjUtMDktMjYiDQpvdXRwdXQ6IGh0bWxfZG9jdW1lbnQNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQpgYGB7cn0NCnJtKGxpc3QgPSBscygpKQ0KDQojaW5zdGFsbC5wYWNrYWdlcygic25hIikNCmxpYnJhcnkob3BlbmFsZXhSKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpyZXF1aXJlKGlncmFwaCkNCg0KZyA8LSBtYWtlX2dyYXBoKCJaYWNoYXJ5IikNCnBsb3QoZykNCg0KZ21hdCA8LSBhc19hZGphY2VuY3lfbWF0cml4KGcsIHR5cGUgPSAiYm90aCIsIHNwYXJzZSA9IEZBTFNFKQ0KZ21hdA0KDQojIGNoYW5naW5nIFYNClYoZykkc2l6ZSA9IGJldHdlZW5uZXNzKGcsIG5vcm1hbGl6ZWQgPSBULCBkaXJlY3RlZCA9IEZBTFNFKSAqIDYwICsgMTUgICNhZnRlciBzb21lIHRyaWFsIGFuZCBlcnJvcg0KcGxvdChnLCBtb2RlID0gInVuZGlyZWN0ZWQiKQ0KDQpzZXQuc2VlZCgyMzQ1KQ0KbCA8LSBsYXlvdXRfd2l0aF9tZHMoZykgICNodHRwczovL2lncmFwaC5vcmcvci9kb2MvbGF5b3V0X3dpdGhfbWRzLmh0bWwNCnBsb3QoZywgbGF5b3V0ID0gbCkNCg0KbCAgI2xldCB1cyB0YWtlIGEgbG9vayBhdCB0aGUgY29vcmRpbmF0ZXMNCmxbMSwgMV0gPC0gNA0KbFszNCwgMV0gPC0gLTMuNQ0KcGxvdChnLCBsYXlvdXQgPSBsKQ0KDQoNCmBgYA0KDQpgYGB7cn0NCiMjIG1ha2luZyBuZXR3b3JrIGNvbGxhYmVyYXRpb25zIGRhdGEsIGZyb20gSlQncyB0dXRvcmlhbA0KDQoNCmZsb2FkIDwtIGZ1bmN0aW9uKGZpbGVuYW1lKSB7DQogICAgbG9hZChmaWxlbmFtZSkNCiAgICBnZXQobHMoKVtscygpICE9ICJmaWxlbmFtZSJdKQ0KfQ0KDQpzY2hvbGFycyA8LSBmbG9hZCgiQzovVXNlcnMva2FsbGUvT25lRHJpdmUvRG9jdW1lbnRlbi9SRU1BL0phYXIgMi9Tb2NpYWwgTmV0d29ya3MvS1NfbGFiam91cm5hbC9kYXRhL3Byb2Nlc3NlZC9zY2hvbGFyc18yMDI0MDkyNC5yZGEiKQ0KDQojZnVuY3RpZSBtYWtlbg0KZmNvbG5ldCA8LSBmdW5jdGlvbihkYXRhID0gc2Nob2xhcnMsIHVuaXZlcnNpdHkgPSAiUlUiLCBkaXNjaXBsaW5lID0gInNvY2lvbG9neSIsIHdhdmVzID0gbGlzdChjKDIwMTUsDQogICAgMjAxOCksIGMoMjAxOSwgMjAyMykpLCB0eXBlID0gYygiZmlyc3QiKSkgew0KDQogICAgIyBzdGVwIDENCiAgICBkZW1vZ3JhcGhpY3MgPC0gZG8uY2FsbChyYmluZC5kYXRhLmZyYW1lLCBkYXRhJGRlbW9ncmFwaGljcykNCiAgICBkZW1vZ3JhcGhpY3MgPC0gZGVtb2dyYXBoaWNzICU+JQ0KICAgICAgICBtdXRhdGUoVW5pdmVyc2l0ZWl0MS4yMiA9IHJlcGxhY2UoVW5pdmVyc2l0ZWl0MS4yMiwgaXMubmEoVW5pdmVyc2l0ZWl0MS4yMiksICIiKSwgVW5pdmVyc2l0ZWl0Mi4yMiA9IHJlcGxhY2UoVW5pdmVyc2l0ZWl0Mi4yMiwNCiAgICAgICAgICAgIGlzLm5hKFVuaXZlcnNpdGVpdDIuMjIpLCAiIiksIFVuaXZlcnNpdGVpdDEuMjQgPSByZXBsYWNlKFVuaXZlcnNpdGVpdDEuMjQsIGlzLm5hKFVuaXZlcnNpdGVpdDEuMjQpLA0KICAgICAgICAgICAgIiIpLCBVbml2ZXJzaXRlaXQyLjI0ID0gcmVwbGFjZShVbml2ZXJzaXRlaXQyLjI0LCBpcy5uYShVbml2ZXJzaXRlaXQyLjI0KSwgIiIpLCBkaXNjaXBsaW5lLjIyID0gcmVwbGFjZShkaXNjaXBsaW5lLjIyLA0KICAgICAgICAgICAgaXMubmEoZGlzY2lwbGluZS4yMiksICIiKSwgZGlzY2lwbGluZS4yNCA9IHJlcGxhY2UoZGlzY2lwbGluZS4yNCwgaXMubmEoZGlzY2lwbGluZS4yNCksICIiKSkNCg0KICAgIHNhbXBsZSA8LSB3aGljaCgoZGVtb2dyYXBoaWNzJFVuaXZlcnNpdGVpdDEuMjIgJWluJSB1bml2ZXJzaXR5IHwgZGVtb2dyYXBoaWNzJFVuaXZlcnNpdGVpdDIuMjIgJWluJQ0KICAgICAgICB1bml2ZXJzaXR5IHwgZGVtb2dyYXBoaWNzJFVuaXZlcnNpdGVpdDEuMjQgJWluJSB1bml2ZXJzaXR5IHwgZGVtb2dyYXBoaWNzJFVuaXZlcnNpdGVpdDIuMjQgJWluJQ0KICAgICAgICB1bml2ZXJzaXR5KSAmIChkZW1vZ3JhcGhpY3MkZGlzY2lwbGluZS4yMiAlaW4lIGRpc2NpcGxpbmUgfCBkZW1vZ3JhcGhpY3MkZGlzY2lwbGluZS4yNCAlaW4lIGRpc2NpcGxpbmUpKQ0KDQogICAgZGVtb2dyYXBoaWNzX3NvYyA8LSBkZW1vZ3JhcGhpY3Nbc2FtcGxlLCBdDQogICAgc2Nob2xhcnNfc2VsIDwtIGxhcHBseShzY2hvbGFycywgIlsiLCBzYW1wbGUpDQoNCiAgICAjIHN0ZXAgMg0KICAgIGlkcyA8LSBkZW1vZ3JhcGhpY3Nfc29jJGF1X2lkDQogICAgbndhdmVzIDwtIGxlbmd0aCh3YXZlcykNCiAgICBuZXRzIDwtIGFycmF5KDAsIGRpbSA9IGMobndhdmVzLCBsZW5ndGgoaWRzKSwgbGVuZ3RoKGlkcykpLCBkaW1uYW1lcyA9IGxpc3Qod2F2ZSA9IDE6bndhdmVzLCBpZHMsDQogICAgICAgIGlkcykpDQogICAgZGltbmFtZXMobmV0cykNCg0KICAgICMgc3RlcCAzDQogICAgZGZfd29ya3MgPC0gdGliYmxlKHdvcmtzX2lkID0gdW5saXN0KGxhcHBseShzY2hvbGFyc19zZWwkd29yaywgZnVuY3Rpb24obCkgbCRpZCkpLCB3b3Jrc19hdXRob3IgPSB1bmxpc3QobGFwcGx5KHNjaG9sYXJzX3NlbCR3b3JrLA0KICAgICAgICBmdW5jdGlvbihsKSBsJGF1dGhvciksIHJlY3Vyc2l2ZSA9IEZBTFNFKSwgd29ya3NfeWVhciA9IHVubGlzdChsYXBwbHkoc2Nob2xhcnNfc2VsJHdvcmssIGZ1bmN0aW9uKGwpIGwkcHVibGljYXRpb25feWVhciksDQogICAgICAgIHJlY3Vyc2l2ZSA9IEZBTFNFKSkNCg0KICAgIGRmX3dvcmtzIDwtIGRmX3dvcmtzWyFkdXBsaWNhdGVkKGRmX3dvcmtzKSwgXQ0KDQogICAgIyBzdGVwIDQNCiAgICBpZiAodHlwZSA9PSAiZmlyc3QiKSB7DQogICAgICAgIGZvciAoaiBpbiAxOm53YXZlcykgew0KICAgICAgICAgICAgZGZfd29ya3NfdyA8LSBkZl93b3Jrc1tkZl93b3JrcyR3b3Jrc195ZWFyID49IHdhdmVzW1tqXV1bMV0gJiBkZl93b3JrcyR3b3Jrc195ZWFyIDw9IHdhdmVzW1tqXV1bMl0sDQogICAgICAgICAgICAgICAgXQ0KICAgICAgICAgICAgZm9yIChpIGluIDE6bnJvdyhkZl93b3Jrc193KSkgew0KICAgICAgICAgICAgICAgIGVnbyA8LSBkZl93b3Jrc193JHdvcmtzX2F1dGhvcltpXVtbMV1dJGF1X2lkWzFdDQogICAgICAgICAgICAgICAgYWx0ZXJzIDwtIGRmX3dvcmtzX3ckd29ya3NfYXV0aG9yW2ldW1sxXV0kYXVfaWRbLTFdDQogICAgICAgICAgICAgICAgaWYgKHN1bShpZHMgJWluJSBlZ28pID4gMCAmIHN1bShpZHMgJWluJSBhbHRlcnMpID4gMCkgew0KICAgICAgICAgICAgICAgICAgbmV0c1tqLCB3aGljaChpZHMgJWluJSBlZ28pLCB3aGljaChpZHMgJWluJSBhbHRlcnMpXSA8LSAxDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgfQ0KDQogICAgaWYgKHR5cGUgPT0gImxhc3QiKSB7DQogICAgICAgIGZvciAoaiBpbiAxOm53YXZlcykgew0KICAgICAgICAgICAgZGZfd29ya3NfdyA8LSBkZl93b3Jrc1tkZl93b3JrcyR3b3Jrc195ZWFyID49IHdhdmVzW1tqXV1bMV0gJiBkZl93b3JrcyR3b3Jrc195ZWFyIDw9IHdhdmVzW1tqXV1bMl0sDQogICAgICAgICAgICAgICAgXQ0KICAgICAgICAgICAgZm9yIChpIGluIDE6bnJvdyhkZl93b3Jrc193KSkgew0KICAgICAgICAgICAgICAgIGVnbyA8LSByZXYoZGZfd29ya3NfdyR3b3Jrc19hdXRob3JbaV1bWzFdXSRhdV9pZClbMV0NCiAgICAgICAgICAgICAgICBhbHRlcnMgPC0gcmV2KGRmX3dvcmtzX3ckd29ya3NfYXV0aG9yW2ldW1sxXV0kYXVfaWQpWy0xXQ0KICAgICAgICAgICAgICAgIGlmIChzdW0oaWRzICVpbiUgZWdvKSA+IDAgJiBzdW0oaWRzICVpbiUgYWx0ZXJzKSA+IDApIHsNCiAgICAgICAgICAgICAgICAgIG5ldHNbaiwgd2hpY2goaWRzICVpbiUgZWdvKSwgd2hpY2goaWRzICVpbiUgYWx0ZXJzKV0gPC0gMQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIGlmICh0eXBlID09ICJhbGwiKSB7DQogICAgICAgIGZvciAoaiBpbiAxOm53YXZlcykgew0KICAgICAgICAgICAgZGZfd29ya3NfdyA8LSBkZl93b3Jrc1tkZl93b3JrcyR3b3Jrc195ZWFyID49IHdhdmVzW1tqXV1bMV0gJiBkZl93b3JrcyR3b3Jrc195ZWFyIDw9IHdhdmVzW1tqXV1bMl0sDQogICAgICAgICAgICAgICAgXQ0KICAgICAgICAgICAgZm9yIChpIGluIDE6bnJvdyhkZl93b3Jrc193KSkgew0KICAgICAgICAgICAgICAgIGVnb3MgPC0gZGZfd29ya3NfdyR3b3Jrc19hdXRob3JbaV1bWzFdXSRhdV9pZA0KICAgICAgICAgICAgICAgIGlmIChzdW0oaWRzICVpbiUgZWdvcykgPiAwKSB7DQogICAgICAgICAgICAgICAgICBuZXRzW2osIHdoaWNoKGlkcyAlaW4lIGVnb3MpLCB3aGljaChpZHMgJWluJSBlZ29zKV0gPC0gMQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICBvdXRwdXQgPC0gbGlzdCgpDQogICAgb3V0cHV0JGRhdGEgPC0gc2Nob2xhcnNfc2VsDQogICAgb3V0cHV0JG5ldHMgPC0gbmV0cw0KICAgIHJldHVybihvdXRwdXQpDQp9DQoNCmBgYA0KDQojIERlc2NyaXB0aXZlIHN0YXRpc3RpY3MgZm9yIHRoZSBuZXR3b3JrDQoNCmBgYHtyfQ0KI2Z1bmN0aWUgZ2VicnVpa2VuDQoNCmRhdGEgPC0gZmNvbG5ldChkYXRhID0gc2Nob2xhcnMsIA0KICAgICAgICAgICAgICAgIHVuaXZlcnNpdHkgPSAiUlUiLCANCiAgICAgICAgICAgICAgICBkaXNjaXBsaW5lID0gInNvY2lvbG9neSIsIA0KICAgICAgICAgICAgICAgIHdhdmVzID0gbGlzdChjKDIwMTUsIDIwMTgpLCBjKDIwMTksIDIwMjMpKSwgDQogICAgICAgICAgICAgICAgdHlwZSA9IGMoImFsbCIpKQ0KDQojZmlyc3Qgd2F2ZQ0KbmV0X3cxIDwtIGRhdGEkbmV0c1sxLCxdDQpkaWFnKG5ldF93MSkgPC0gMA0KZyA8LSBncmFwaF9mcm9tX2FkamFjZW5jeV9tYXRyaXgobmV0X3cxLCBtb2RlID0gInVuZGlyZWN0ZWQiLCBkaWFnID0gRkFMU0UpDQoNCiNkZW5zaXR5DQpkZW5zaXR5IDwtIGVkZ2VfZGVuc2l0eShnKQ0KZGVuc2l0eQ0KDQoNCiNkZWdyZWUgY2VudHJhbGl0eQ0KI2VnbyBsZXZlbA0KZGVncmVlKGcpDQoNCiNuZXR3b3JrIGxldmVsDQptZWFuKGRlZ3JlZShnLCBtb2RlID0gImFsbCIpKQ0KDQoNCiN0cmFuc2l0aXZpdHkNCnRyYW5zaXRpdml0eShnLCB0eXBlID0gInVuZGlyZWN0ZWQiKQ0KDQoNCiNwbG90DQp0ZXN0X3cxIDwtIGlncmFwaDo6Z3JhcGhfZnJvbV9hZGphY2VuY3lfbWF0cml4KA0KICBkYXRhJG5ldHNbMSwsXSwgI2ZvciB0aGlzIGV4YW1wbGUgSSB0YWtlIHRoZSBmaXJzdCB3YXZlIG9mIGRhdGEuICh0aHVzIEkgc2VsZWN0IHRoZSBhcnJheSBvZiBuZXR3b3JrcyBhbmQgdGFrZSB0aGUgZmlyc3QgbWF0cml4KQ0KICBtb2RlID0gYygidW5kaXJlY3RlZCIpLA0KICB3ZWlnaHRlZCA9IE5VTEwsDQogIGRpYWcgPSBGQUxTRSwNCiAgYWRkLmNvbG5hbWVzID0gTlVMTCwNCiAgYWRkLnJvd25hbWVzID0gTlVMTA0KKQ0KDQpwbG90KHRlc3RfdzEsDQogIHZlcnRleC5sYWJlbCA9IE5BLA0KICBlZGdlLndpZHRoID0gMC4yLA0KICBlZGdlLmFycm93LnNpemUgPTAuMikNCg0KDQojIyMgc2Vjb25kIHdhdmUNCg0KI2R1aWRlbGlqayBtZWVyIGRlbnNpdHksIGNlbnRyYWxpdHkgZW4gbWluZGVyIGlzb2xhdGVzLg0KDQpuZXRfdzIgPC0gZGF0YSRuZXRzWzIsLF0NCmRpYWcobmV0X3cyKSA8LSAwDQpnMiA8LSBncmFwaF9mcm9tX2FkamFjZW5jeV9tYXRyaXgobmV0X3cyLCBtb2RlID0gInVuZGlyZWN0ZWQiLCBkaWFnID0gRkFMU0UpDQoNCiNkZW5zaXR5DQpkZW5zaXR5MiA8LSBlZGdlX2RlbnNpdHkoZzIpDQpkZW5zaXR5Mg0KDQoNCiNkZWdyZWUgY2VudHJhbGl0eQ0KI2VnbyBsZXZlbA0KZGVncmVlIChnMikNCg0KI25ldHdvcmsgbGV2ZWwNCm1lYW4oZGVncmVlKGcyLCBtb2RlID0gImFsbCIpKQ0KDQoNCiN0cmFuc2l0aXZpdHkNCnRyYW5zaXRpdml0eShnMiwgdHlwZSA9ICJ1bmRpcmVjdGVkIikNCg0KDQoNCg0KdGVzdF93MiA8LSBpZ3JhcGg6OmdyYXBoX2Zyb21fYWRqYWNlbmN5X21hdHJpeCgNCiAgZGF0YSRuZXRzWzIsLF0sDQogIG1vZGUgPSBjKCJ1bmRpcmVjdGVkIiksDQogIHdlaWdodGVkID0gTlVMTCwNCiAgZGlhZyA9IEZBTFNFLA0KICBhZGQuY29sbmFtZXMgPSBOVUxMLA0KICBhZGQucm93bmFtZXMgPSBOVUxMDQopDQoNCnBsb3QodGVzdF93MiwNCiAgdmVydGV4LmxhYmVsID0gTkEsDQogIGVkZ2Uud2lkdGggPSAwLjIsDQogIGVkZ2UuYXJyb3cuc2l6ZSA9MC4yKQ0KDQoNCmBgYA0KDQojIEVnbyBjaGFyYWN0ZXJpc3RpY3MNCg0KYGBge3IsIGV2YWw9RkFMU0UsIGVjaG89VFJVRX0NCiMgU2NyYXBpbmcgdGhlICMgb2YgY2l0YXRpb25zIG9mIGFsbCBwYXBlcnMgcHVibGlzaGVkIGR1cmluZyBwZXIgd2F2ZSANCg0KDQpkZl9zY2hvbGFycyA8LSBkby5jYWxsKHJiaW5kLCBzY2hvbGFycyRkZW1vZ3JhcGhpY3MpDQoNCm1haWwgPSAia2FsbGUuc3RvZmZlcnNAcnUubmwiDQoNCg0KI2VtcHR5IGxpc3QNCmNpdGF0aW9uc19wZXJfd2F2ZSA8LSBsaXN0KCkNCg0KDQpmb3IgKGF1dGhvciBpbiBkZl9zY2hvbGFycyRhdV9pZFsxOjY3NV0pIHsNCg0KI2ZldGNoIHBhcGVycyBwZXIgYXV0aG9ycw0KcGFwZXJzIDwtIG9hX2ZldGNoKA0KICBlbnRpdHkgPSAid29ya3MiLA0KICBhdXRob3IuaWQgPSBhdXRob3IsDQogIG1haWx0byA9IG1haWwpDQoNCiMgY2hlY2sgaWYgcGFwZXJzIGlzIE5VTEwgb3IgaGFzIDAgcm93cw0KICBpZiAoaXMubnVsbChwYXBlcnMpIHx8IG5yb3cocGFwZXJzKSA9PSAwKSB7DQogICAgIyBmaWxsIHdpdGggMCBjaXRhdGlvbnMgZm9yIGJvdGggd2F2ZXMNCiAgICBjaXRhdGlvbnMgPC0gdGliYmxlKA0KICAgICAgYXVfaWQgPSBhdXRob3IsDQogICAgICBjaXRhdGlvbnNfdzEgPSAwLA0KICAgICAgY2l0YXRpb25zX3cyID0gMA0KICAgICkNCiAgfSBlbHNlIHsNCiAgICAjIHdhdmUgMSBjaXRhdGlvbnMNCiAgICBjaXRhdGlvbnNfdzEgPC0gcGFwZXJzIHw+DQogICAgICBmaWx0ZXIocHVibGljYXRpb25feWVhciA+PSAyMDE1ICYgcHVibGljYXRpb25feWVhciA8PSAyMDE4KSB8Pg0KICAgICAgc3VtbWFyaXNlKGNpdGF0aW9uc193MSA9IHN1bShjaXRlZF9ieV9jb3VudCwgbmEucm0gPSBUUlVFKSkNCg0KICAgICMgd2F2ZSAyIGNpdGF0aW9ucw0KICAgIGNpdGF0aW9uc193MiA8LSBwYXBlcnMgfD4NCiAgICAgIGZpbHRlcihwdWJsaWNhdGlvbl95ZWFyID49IDIwMTkgJiBwdWJsaWNhdGlvbl95ZWFyIDw9IDIwMjMpIHw+DQogICAgICBzdW1tYXJpc2UoY2l0YXRpb25zX3cyID0gc3VtKGNpdGVkX2J5X2NvdW50LCBuYS5ybSA9IFRSVUUpKQ0KDQogICAgIyBoYW5kbGUgY2FzZSB3aGVyZSBvbmUgb2YgdGhlIHN1bW1hcmllcyBtaWdodCByZXR1cm4gMCByb3dzDQogICAgaWYgKG5yb3coY2l0YXRpb25zX3cxKSA9PSAwKSBjaXRhdGlvbnNfdzEgPC0gdGliYmxlKGNpdGF0aW9uc193MSA9IDApDQogICAgaWYgKG5yb3coY2l0YXRpb25zX3cyKSA9PSAwKSBjaXRhdGlvbnNfdzIgPC0gdGliYmxlKGNpdGF0aW9uc193MiA9IDApDQoNCiNqb2luIHRoZSB0d28NCmNpdGF0aW9ucyA8LSBtZXJnZShjaXRhdGlvbnNfdzEsIGNpdGF0aW9uc193MikNCg0KY2l0YXRpb25zIDwtIGNpdGF0aW9uc3w+DQogIG11dGF0ZShhdV9pZCA9IGF1dGhvcikgfD4NCiAgcmVsb2NhdGUoYXVfaWQpDQp9DQogIA0KY2l0YXRpb25zX3Blcl93YXZlW1thdXRob3JdXSA8LSBjaXRhdGlvbnMNCg0KfQ0KICANCg0KI21lcmdlIG1ldCBvcmlnaW5lbGUgZGF0YXNldA0KY2l0YXRpb25zX2RmIDwtIGJpbmRfcm93cyhjaXRhdGlvbnNfcGVyX3dhdmUpDQoNCmRmIDwtIGxlZnRfam9pbihkZl9zY2hvbGFycywgY2l0YXRpb25zX2RmLCBieSA9ICJhdV9pZCIpDQoNCg0KZnNhdmUgPC0gZnVuY3Rpb24oeCwgZmlsZSA9IE5VTEwsIGxvY2F0aW9uID0gIi4vZGF0YS9wcm9jZXNzZWQvIikgew0KICAgIGlmZWxzZSghZGlyLmV4aXN0cygiZGF0YSIpLCBkaXIuY3JlYXRlKCJkYXRhIiksIEZBTFNFKQ0KICAgIGlmZWxzZSghZGlyLmV4aXN0cygiZGF0YS9wcm9jZXNzZWQiKSwgZGlyLmNyZWF0ZSgiZGF0YS9wcm9jZXNzZWQiKSwgRkFMU0UpDQogICAgaWYgKGlzLm51bGwoZmlsZSkpDQogICAgICAgIGZpbGUgPSBkZXBhcnNlKHN1YnN0aXR1dGUoeCkpDQogICAgZGF0ZW5hbWUgPC0gc3Vic3RyKGdzdWIoIls6LV0iLCAiIiwgU3lzLnRpbWUoKSksIDEsIDgpDQogICAgdG90YWxuYW1lIDwtIHBhc3RlKGxvY2F0aW9uLCBmaWxlLCAiXyIsIGRhdGVuYW1lLCAiLnJkYSIsIHNlcCA9ICIiKQ0KICAgIHNhdmUoeCwgZmlsZSA9IHRvdGFsbmFtZSkgICNuZWVkIHRvIGZpeCBpZiBmaWxlIGlzIHJlbG9hZGVkIGFzIGlucHV0IG5hbWUsIG5vdCBhcyB4LiANCn0NCg0KZnNhdmUoZGYpDQoNCmBgYA0KDQpgYGB7cn0NCiNkZXNjcmlwdGl2ZXMgY2l0YXRpb25zDQoNCmRmPC0gZmxvYWQoIn4vUkVNQS9KYWFyIDIvU29jaWFsIE5ldHdvcmtzL0tTX2xhYmpvdXJuYWwvZGF0YS9wcm9jZXNzZWQvZGZfMjAyNTA5MjkucmRhIikNCg0KDQpzdW1tYXJ5KGRmJGNpdGF0aW9uc193MSkNCnN1bW1hcnkgKGRmJGNpdGF0aW9uc193MikNCg0KI3JlbW92ZSBvdXRsaWVyDQpkZjwtIGRmIHw+IGZpbHRlcihjaXRhdGlvbnNfdzEgPD0gNjAwMCkNCnN1bW1hcnkgKGRmJGNpdGF0aW9uc193MikNCg0KZGZfbG9uZyA8LSBkZnw+DQogIHBpdm90X2xvbmdlcihjb2xzID0gYyhjaXRhdGlvbnNfdzEsIGNpdGF0aW9uc193MiksDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJ3YXZlIiwNCiAgICAgICAgICAgICAgIG5hbWVzX3ByZWZpeCA9ICJjaXRhdGlvbnNfdyIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiY2l0YXRpb25zIikgfD4NCiAgbXV0YXRlKHdhdmUgPSBhcy5mYWN0b3Iod2F2ZSkpDQoNCmdncGxvdChkZl9sb25nLCBhZXMoeCA9IGNpdGF0aW9ucywgY29sb3IgPSB3YXZlKSkgKyBnZW9tX2RlbnNpdHkoKQ0KDQpgYGANCg==