knitr::opts_chunk$set(warning = FALSE)

General Data Preparation

Loading Libraries

suppressMessages(library(sna))
suppressMessages(library(dplyr))
suppressMessages(library(ggsci))
suppressMessages(library(plotly))
suppressMessages(library(igraph))
suppressMessages(library(network))
suppressMessages(library(kableExtra))
suppressMessages(library(igraphdata))
suppressMessages(library(intergraph))
suppressMessages(library(RColorBrewer))

Loading Dataset

load("res_sem.RData")
#sub stringing the IPC3 from IPC
IPC4 <- substr(joined_IPC_Inv$IPC, start = 1, stop = 4) #extracting the IPC3 from the original sorted dataset
IPC4 <- as.data.frame(IPC4) # defining it as a dataframe
data_final <- cbind(joined_IPC_Inv, IPC4) # combining the newly created IPC3 containing dataframe with the main dataframe
rm(joined_IPC_Inv) & rm(IPC4) # removing the dataset to free memory
## logical(0)
data_final <- subset(data_final, select = -c(IPC,ctry_code)) # dropping columns

Data Cleaning

data <- (data_final %>% 
                 filter(IPC4=="F03D")) # creating subset of Wind Energy Industry (F03D)
rm(data_final)
data <- (data %>% 
           filter(app_year>= 1996 & app_year <= 2016)) # limiting years from 1996 to 2016

# now getting rid of empty city values
data <- (data %>%
           mutate(city = replace(city, city == "", NA)))#making the empty values NA
data <- na.omit(data) #getting rid of NA values

# getting rid of duplicate values
data_main <- data[!duplicated(data),]

# ranking cities according to patents
data_main_city_rank <- (data_main %>% 
                          group_by(city) %>%
                          count(city, sort = TRUE,  name = "patents")) #ranking the cities according to the number of patent applications

data_main_15 <- head(data_main_city_rank,15) # keeping first 15 patent owning cities in ranked format
data_main_15_attr <- (data_main %>%
                     filter(city %in% c("Aurich","Hamburg","Berlin","Salzbergen","Rendsburg","Rheine","Kiel","Aachen","Munchen","Norderstedt","Osnabruck","Bremen","Erlangen","Dresden","Munster"))) # keeping the most 15 patent owning cities with all attributes

General Insights from the Data

Top 15 most patent owning cities

Network Data Preparation (Using igraph and sna packages)

N1. Inventor networks for all cities

inv_aff_all <- (data_main %>% 
              select(appln_id,person_id))
inv_aff_all_2mode <- table(inv_aff_all)
inv_aff_all_adj <- inv_aff_all_2mode %*% t(inv_aff_all_2mode)
diag(inv_aff_all_adj) <-0 # deleting the diagonals
inv_aff_all_ig <- graph.adjacency(inv_aff_all_adj, mode = "undirected", weight = TRUE)
print(inv_aff_all_ig) # Basic information about the network
## IGRAPH 1bd6ec3 UNW- 2129 15915 -- 
## + attr: name (v/c), weight (e/n)
## + edges from 1bd6ec3 (vertex names):
##  [1] 146 --16300136  146 --16301200  146 --16389117  146 --313583480
##  [5] 1040--57537     1042--124159    1042--165074    1042--184222   
##  [9] 1042--220266    1042--241948    1042--269684    1042--271952   
## [13] 1042--342495    1042--374699    1042--397355    1042--412779   
## [17] 1042--414426    1042--15756743  1042--15757619  1042--15764242 
## [21] 1042--15765093  1042--15766246  1042--15777559  1042--15777598 
## [25] 1042--15780371  1042--15780379  1042--15790852  1042--15796437 
## [29] 1042--15796509  1042--15799148  1042--15800073  1042--15820220 
## + ... omitted several edges

N2. City networks (for 15 most innovative cities)

inv_city <- (data_main_15_attr %>% 
               select(city, appln_id))
inv_city_2mode <-  table(inv_city)   # cross tabulate -> 2-mode sociomatrix
inv_city_adj <- inv_city_2mode %*% t(inv_city_2mode)
diag(inv_city_adj) <-0 # deleting the diagonals
inv_city_ig <- graph.adjacency(inv_city_adj, mode = "undirected", weight = TRUE)
print(inv_city_ig) # basic information about the network
## IGRAPH 1beb531 UNW- 15 34 -- 
## + attr: name (v/c), weight (e/n)
## + edges from 1beb531 (vertex names):
##  [1] Aachen --Bremen      Aachen --Rheine      Aurich --Berlin     
##  [4] Aurich --Bremen      Aurich --Hamburg     Berlin --Erlangen   
##  [7] Berlin --Hamburg     Berlin --Kiel        Berlin --Norderstedt
## [10] Berlin --Rendsburg   Berlin --Rheine      Berlin --Salzbergen 
## [13] Bremen --Hamburg     Bremen --Rheine      Dresden--Norderstedt
## [16] Hamburg--Kiel        Hamburg--Munchen     Hamburg--Norderstedt
## [19] Hamburg--Rendsburg   Hamburg--Rheine      Kiel   --Norderstedt
## [22] Kiel   --Osnabruck   Kiel   --Rendsburg   Kiel   --Rheine     
## + ... omitted several edges

N3. Inventor’s network of top 15 cities

# inventor's data cleaning
inv_person <- (data_main_15_attr %>% 
                 select(inv_name,appln_id)) # sub-setting the data for inventors with patents
inv_per_attr <- (data_main_15_attr %>% 
                   select(appln_id, city))

# parsing the person's network data to have clean and non-duplicated values
inv_person_parsed <- inv_person
length(unique(inv_person_parsed$inv_name))
## [1] 630
inv_person_parsed$inv_name_small <- tolower(inv_person_parsed$inv_name)
inv_person_parsed$inv_name_small <- sub(", prof. dr.-ing.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 591
inv_person_parsed$inv_name_small <- sub(", dr.-ing.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 590
inv_person_parsed$inv_name_small <- sub(", dipl.-ing.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 588
inv_person_parsed$inv_name_small <- sub(", -ing.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 588
inv_person_parsed$inv_name_small <- sub(", dr.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 578
inv_person_parsed$inv_name_small <- sub(" dr.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 577
# new network changed size
length(unique(inv_person_parsed$inv_name_small))/length(unique(inv_person_parsed$inv_name))
## [1] 0.915873
# getting rid of original inventor names
inv_person_parsed$inv_name <- inv_person_parsed$inv_name_small

# removing third column
inv_person_parsed <- subset(inv_person_parsed, select = -c(inv_name_small))

# creating network with the cleaned data
inv_person_2mode <- table(inv_person_parsed) # making 2 mode sociomatrix
inv_person_adj <- inv_person_2mode %*% t(inv_person_2mode)
diag(inv_person_adj) <-0
inv_aff_ig <- graph.adjacency(inv_person_adj, mode = "undirected", weight = TRUE)

Creating Networks and Plotting Graphs

Detaching packages to avoid conflicts between package operations.

detach(package:sna)
detach(package:network)
suppressMessages(library(igraph))

N1. Creating the network for all the inventors

# matching the dataset with city and application ids
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]

N1. Plotting

set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_all_ig,
     vertex.label=NA,
     vertex.size = 3,
     vertex.color = V(inv_aff_all_ig),
     main="Network of all the inventors")

N2. Creating network for 15 cities

inv_city_ig <- (inv_city_ig %>% 
                  set_vertex_attr(
                    name = "vertex.names",
                    value = c("Aurich","Hamburg","Berlin","Salzbergen","Rendsburg","Rheine","Kiel","Aachen","Munchen","Norderstedt","Osnabruck","Bremen","Erlangen","Dresden","Munster") # modifying vertex names on the igraph object (as city names)
                  ))
V(inv_city_ig)$label <- c("Aurich","Hamburg","Berlin","Salzbergen","Rendsburg","Rheine","Kiel","Aachen","Munchen","Norderstedt","Osnabruck","Bremen","Erlangen","Dresden","Munster") # changing the igraph object's labels also into the city names

N2. Centrality Measurement

centr_degree(
  inv_city_ig,
  mode = c("all", "out", "in", "total"),
  loops = F,
  normalized = TRUE)
## $res
##  [1] 2 3 8 4 1 1 8 7 4 2 6 3 5 9 5
## 
## $centralization
## [1] 0.3681319
## 
## $theoretical_max
## [1] 182

N2. Plotting

par(mar=c(0,0,2,0))
set.seed(100)
plot(inv_city_ig,
     vertex.label=V(inv_city_ig)$city,
     vertex.color=V(inv_city_ig),
     vertex.size= 10,
     vertex.frame.color=NA,
     vertex.label.family= "Cambria",
     vertex.label.font=2,
     main="Network of top 15 cities")

N3. Plotting and centrality measurement of inventor’s network (top 15 cities)

N3. Centrality Measurement

centr_degree(
  inv_aff_ig,
  mode = c("all", "out", "in", "total"),
  loops = F,
  normalized = TRUE)
## $res
##   [1] 3 0 0 7 1 5 2 3 0 1 1 1 1 1 0 0 1 4 1 2 1 0 0 0 1 1 0 1 1 1 3 1 1 2 3 0 0
##  [38] 0 0 1 0 0 0 0 1 0 3 4 1 2 0 1 0 3 4 1 0 0 2 1 3 1 0 2 0 1 1 1 1 2 6 0 1 1
##  [75] 0 3 3 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 1 0 0 3 2 1 4 0 0 3 1 2
## [112] 1 0 1 0 0 1 0 1 1 1 1 0 2 2 0 0 0 2 0 3 1 0 2 0 1 0 0 4 1 0 5 0 0 1 1 2 0
## [149] 1 1 1 0 1 0 0 1 4 5 0 3 1 0 2 0 0 0 0 1 0 0 2 0 0 1 1 7 5 0 1 2 1 4 0 1 1
## [186] 1 1 3 3 0 5 1 0 0 0 1 1 0 0 0 2 3 3 1 1 0 0 0 1 0 0 1 4 0 1 0 0 0 0 1 1 1
## [223] 2 2 0 0 1 3 0 7 0 1 2 1 2 0 1 2 2 3 0 0 1 1 0 3 4 3 0 0 1 2 0 1 3 3 0 0 0
## [260] 1 0 1 1 2 1 0 1 1 2 0 0 0 0 0 0 3 0 0 1 2 0 1 0 1 1 2 2 3 0 1 1 4 0 2 0 1
## [297] 0 2 2 0 0 3 2 0 3 0 3 3 0 2 3 1 3 0 0 1 0 1 1 1 0 0 0 0 1 1 1 2 1 4 0 0 1
## [334] 1 0 1 1 0 0 4 4 4 1 1 3 2 0 4 1 0 2 3 2 1 3 0 2 3 5 2 0 3 0 0 2 2 2 4 1 0
## [371] 3 1 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 3 1 0 2 0 2 1 0 0 1 2 5 1 1 2 2 3 0 0 0
## [408] 1 0 2 2 3 1 1 0 1 2 1 0 0 0 1 1 0 1 2 2 0 0 3 0 1 0 1 0 0 3 1 3 1 1 2 2 2
## [445] 3 0 2 1 1 0 0 0 1 0 0 0 4 2 0 1 2 4 0 2 1 1 0 0 0 0 0 0 0 1 2 0 2 3 1 4 0
## [482] 4 0 2 0 1 1 0 2 0 0 5 0 1 2 1 4 2 2 0 0 0 1 0 2 1 0 0 2 3 3 1 0 0 0 1 0 0
## [519] 2 2 2 1 1 0 2 0 0 0 1 1 2 0 1 2 1 1 0 0 1 0 0 0 4 3 1 0 1 1 0 0 0 4 0 0 0
## [556] 1 3 1 1 3 0 0 1 0 0 0 1 1 0 1 0 3 0 1 0 3 2
## 
## $centralization
## [1] 0.01025664
## 
## $theoretical_max
## [1] 331200

N3. Plotting

General network graph

set.seed(100)
par(mar=c(0,0,2,0))
plot(inv_aff_ig,
     vertex.label=NA,
     vertex.size=1.5,
     vertex.frame.color="black",
     vertex.color = V(inv_aff_ig),
     main="Inventor network of top 15 cities\nfor 1996-2016")

Plotting with density

set.seed(100)
par(mar=c(0,0,4,0))
plot(inv_aff_ig,
     vertex.label=NA,
     vertex.size=degree(inv_aff_ig)*1.5,
     vertex.frame.color="black",
     vertex.color = V(inv_aff_ig),
     main="Inventor network of top 15 cities\nfor 1996-2016\nwith degree measurement")

Plotting with density and edge betweenness

set.seed(100)
par(mar=c(0,0,4,0))
plot(inv_aff_ig,
     vertex.label=NA,
     vertex.frame.color="black",
     vertex.color=V(inv_aff_ig),
     vertex.size=degree(inv_aff_ig)*1.5,
     edge.curved=.1,
     main="Inventor network of top 15 cities\nfor 1996-2016\nwith degree measurement and edge betweenness",
     edge.width = edge_betweenness(inv_aff_ig)*.8)

Top 5 City’s Innovation Scenario over the Time

Detaching packages to avoid conflicts between package operations

detach(package:igraph)
suppressMessages(library(network))

Aurich

## Aurich 1996:2006 network
aurich_data_06 <- (data_main_15_attr %>%
                          filter(city=="Aurich", app_year>=1996 & app_year<=2006) %>%
                          select(inv_name, appln_id))

aurich_data_06 <- table(aurich_data_06)
dim(aurich_data_06)
## [1]   4 170
aurich_adj_06 <- aurich_data_06 %*% t(aurich_data_06)
dim(aurich_adj_06)
## [1] 4 4
class(aurich_adj_06)
## [1] "matrix" "array"
aurich_nw_06 <-  network(aurich_adj_06,
                      matrix.type="adjacency",
                      directed=F)  # convert into 'network' format


## Aurich 2007:2016 network
aurich_data_16 <- (data_main_15_attr %>%
                        filter(city=="Aurich", app_year>=2007 & app_year<=2016) %>%
                        select(inv_name, appln_id))

aurich_data_16 <- table(aurich_data_16)
dim(aurich_data_16)
## [1]  50 101
aurich_adj_16 <- aurich_data_16 %*% t(aurich_data_16)
dim(aurich_adj_16)
## [1] 50 50
class(aurich_adj_16)
## [1] "matrix" "array"
aurich_nw_16 <-  network(aurich_adj_16,
                           matrix.type="adjacency",
                           directed=F)  # convert into 'network' format

Plotting

par(mfrow = c(1,2))
par(mar=c(3,0,1,0))

#plot for 1996:2006
plot.network(aurich_nw_06,
             vertex.col="#7570B3",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Aurich 1996:2006",
             pad=4,
             frame = T,
             sub=network.size(aurich_nw_06),
             cex.main=.8)

# plot for 2007:2016
plot.network(aurich_nw_16,
             vertex.col="#7570B3",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Aurich 2007:2016",
             frame = T,
             cex.main=.8)

cat("Total nodes 1996-2006:", network.size(aurich_nw_06),"\nTotal nodes 2007-2016:", network.size(aurich_nw_16))
## Total nodes 1996-2006: 4 
## Total nodes 2007-2016: 50

Hamburg

## Hamburg 1996:2006 network
hamburg_data_06 <- (data_main_15_attr %>%
                          filter(city=="Hamburg", app_year>=1996 & app_year<=2006) %>%
                          select(inv_name, appln_id))

hamburg_data_06 <- table(hamburg_data_06)
dim(hamburg_data_06)
## [1] 12 14
hamburg_adj_06 <- hamburg_data_06 %*% t(hamburg_data_06)
dim(hamburg_adj_06)
## [1] 12 12
class(hamburg_adj_06)
## [1] "matrix" "array"
hamburg_nw_06 <-  network(hamburg_adj_06,
                         matrix.type="adjacency",
                         directed=F)  # convert into 'network' format


## Hamburg 2007:2006 network
hamburg_data_16 <- (data_main_15_attr %>%
                          filter(city=="Hamburg", app_year>=2007 & app_year<=2016) %>%
                          select(inv_name, appln_id))

hamburg_data_16 <- table(hamburg_data_16)
dim(hamburg_data_16)
## [1] 113 152
hamburg_adj_16 <- hamburg_data_16 %*% t(hamburg_data_16)
dim(hamburg_adj_16)
## [1] 113 113
class(hamburg_adj_16)
## [1] "matrix" "array"
hamburg_nw_16 <-  network(hamburg_adj_16,
                      matrix.type="adjacency",
                      directed=F)  # convert into 'network' format

Plotting

par(mfrow = c(1,2))
par(mar=c(0,0,1,0))

#plot for 1996:2006
plot.network(hamburg_nw_06,
             vertex.col="#99B898",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Hamburg 1996:2006",
             frame = T,
             pad=4,
             cex.main=.8)
# plot for 2007:2016
plot.network(hamburg_nw_16,
             vertex.col="#99B898",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Hamburg 2007:2016",
             frame = T,
             cex.main=.8)

cat("Total nodes 1996-2006:", network.size(hamburg_nw_06),"\nTotal nodes 2007-2016:", network.size(hamburg_nw_16))
## Total nodes 1996-2006: 12 
## Total nodes 2007-2016: 113

Berlin

## Berlin 1996:2006 network
berlin_data_06 <- (data_main_15_attr %>%
                      filter(city=="Berlin", app_year>=1996 & app_year<=2006) %>%
                      select(inv_name, appln_id))

berlin_data_06 <- table(berlin_data_06)
dim(berlin_data_06)
## [1] 25 21
berlin_adj_06 <- berlin_data_06 %*% t(berlin_data_06)
dim(berlin_adj_06)
## [1] 25 25
class(berlin_adj_06)
## [1] "matrix" "array"
berlin_nw_06 <-  network(berlin_adj_06,
                          matrix.type="adjacency",
                          directed=F)  # convert into 'network' format


## Berlin 2007:2016 network
berlin_data_16 <- (data_main_15_attr %>%
                      filter(city=="Berlin", app_year>=2007 & app_year<=2016) %>%
                      select(inv_name, appln_id))

berlin_data_16 <- table(berlin_data_16)
dim(berlin_data_16)
## [1] 75 89
berlin_adj_16 <- berlin_data_16 %*% t(berlin_data_16)
dim(berlin_adj_16)
## [1] 75 75
class(berlin_adj_16)
## [1] "matrix" "array"
berlin_nw_16 <-  network(berlin_adj_16,
                          matrix.type="adjacency",
                          directed=F)  # convert into 'network' format

Plotting

par(mfrow = c(1,2))
par(mar=c(0,0,1,0))

#plot for 1996:2006
plot.network(berlin_nw_06,
             vertex.col="#F26B38",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Berlin 1996:2006",
             frame = T,
             pad=4,
             cex.main=.8)
# plot for 2007:2016
plot.network(berlin_nw_16,
             vertex.col="#F26B38",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Berlin 2007:2016",
             frame = T,
             cex.main=.8)

cat("Total nodes 1996-2006:", network.size(berlin_nw_06),"\nTotal nodes 2007-2016:", network.size(berlin_nw_16))
## Total nodes 1996-2006: 25 
## Total nodes 2007-2016: 75

Salzbergen

## Salzbergen 1996:2006 network
salzbergen_data_06 <- (data_main_15_attr %>%
                         filter(city=="Salzbergen", app_year>=1996 & app_year<=2006) %>%
                         select(inv_name, appln_id))

salzbergen_data_06 <- table(salzbergen_data_06)
dim(salzbergen_data_06)
## [1] 2 4
salzbergen_adj_06 <- salzbergen_data_06 %*% t(salzbergen_data_06)
dim(salzbergen_adj_06)
## [1] 2 2
class(salzbergen_adj_06)
## [1] "matrix" "array"
salzbergen_nw_06 <-  network(salzbergen_adj_06,
                         matrix.type="adjacency",
                         directed=F)  # convert into 'network' format


## Salzbergen 2007:2017 network
salzbergen_data_16 <- (data_main_15_attr %>%
                         filter(city=="Salzbergen", app_year>=2007 & app_year<=2016) %>%
                         select(inv_name, appln_id))

salzbergen_data_16 <- table(salzbergen_data_16)
dim(salzbergen_data_16)
## [1] 86 97
salzbergen_adj_16 <- salzbergen_data_16 %*% t(salzbergen_data_16)
dim(salzbergen_adj_16)
## [1] 86 86
class(salzbergen_adj_16)
## [1] "matrix" "array"
salzbergen_nw_16 <-  network(salzbergen_adj_16,
                             matrix.type="adjacency",
                             directed=F)  # convert into 'network' format

Plotting

par(mfrow = c(1,2))
par(mar=c(0,0,1,0))

#plot for 1996:2006
plot.network(salzbergen_nw_06,
             vertex.col="#594F4F",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Salzbergen 1996:2006",
             frame = T,
             pad=4,
             cex.main=.8)
# plot for 2007:2016
plot.network(salzbergen_nw_16,
             vertex.col="#594F4F",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Salzbergen 2007:2016",
             frame = T,
             cex.main=.8)

cat("Total nodes 1996-2006:", network.size(salzbergen_nw_06),"\nTotal nodes 2007-2016:", network.size(salzbergen_nw_16))
## Total nodes 1996-2006: 2 
## Total nodes 2007-2016: 86

Rendsburg

## Rendsburg 1996:2006 network
rendsburg_data_06 <- (data_main_15_attr %>%
                         filter(city=="Rendsburg", app_year>=1996 & app_year<=2006) %>%
                         select(inv_name, appln_id))

rendsburg_data_06 <- table(rendsburg_data_06)
dim(rendsburg_data_06)
## [1] 10 25
rendsburg_adj_06 <- rendsburg_data_06 %*% t(rendsburg_data_06)
dim(rendsburg_adj_06)
## [1] 10 10
class(rendsburg_adj_06)
## [1] "matrix" "array"
rendsburg_nw_06 <-  network(rendsburg_adj_06,
                             matrix.type="adjacency",
                             directed=F)  # convert into 'network' format


## Rendsburg 200:2016 network
rendsburg_data_16 <- (data_main_15_attr %>%
                         filter(city=="Rendsburg", app_year>=2007 & app_year<=2016) %>%
                         select(inv_name, appln_id))

rendsburg_data_16 <- table(rendsburg_data_16)
dim(rendsburg_data_16)
## [1] 13 51
rendsburg_adj_16 <- rendsburg_data_16 %*% t(rendsburg_data_16)
dim(rendsburg_adj_16)
## [1] 13 13
class(rendsburg_adj_16)
## [1] "matrix" "array"
rendsburg_nw_16 <-  network(rendsburg_adj_16,
                             matrix.type="adjacency",
                             directed=F)  # convert into 'network' format

Plotting

par(mfrow = c(1,2))
par(mar=c(0,0,1,0))

#plot for 1996:2006
plot.network(rendsburg_nw_06,
             vertex.col="#355C7D",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Rendsburg 1996:2006",
             frame = T,
             pad=4,
             cex.main=.8)
# plot for 2007:2016
plot.network(rendsburg_nw_16,
             vertex.col="#355C7D",
             vertex.cex=1,
             vertex.border="black",
             main="Inventors Network for Rendsburg 2007:2016",
             frame = T,
             cex.main=.8)

cat("Total nodes 1996-2006:", network.size(rendsburg_nw_06),"\nTotal nodes 2007-2016:", network.size(rendsburg_nw_16))
## Total nodes 1996-2006: 10 
## Total nodes 2007-2016: 13

Position of the Top 5 Cities in 15 City’s Network

Detaching packages to avoid conflicts between package operations.

detach(package:network)
suppressMessages(library(igraph))

Aurich

## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)

V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Aurich", "red","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)

set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
     layout = layout.auto(inv_aff_ig),
     vertex.size = 3,
     vertex.frame.color="black",
     vertex.color = V(inv_aff_ig)$city_name_color,
     vertex.label = NA,
     edge.color= "black",
     main="Inventors from Aurich in top 15 city's network")

Hamburg

## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)

V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Hamburg", "blue","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)

set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
     layout = layout.auto(inv_aff_ig),
     vertex.size = 3,
     vertex.frame.color="black",
     vertex.color = V(inv_aff_ig)$city_name_color,
     vertex.label = NA,
     edge.color= "black",
     main="Inventors from Hamburg in top 15 city's network")

Berlin

## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)

V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Berlin", "darkslategray4","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)

set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
     layout = layout.auto(inv_aff_ig),
     vertex.size = 3,
     vertex.frame.color="black",
     vertex.color = V(inv_aff_ig)$city_name_color,
     vertex.label = NA,
     edge.color= "black",
     main="Inventors from Berlin in top 15 city's network")

Salzbergen

## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)

V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Salzbergen", "darkorange1","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)

set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
     layout = layout.auto(inv_aff_ig),
     vertex.size = 3,
     vertex.frame.color="black",
     vertex.color = V(inv_aff_ig)$city_name_color,
     vertex.label = NA,
     edge.color= "black",
     main="Inventors from Salzbergen in top 15 city's network")

Rendsburg

## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)

V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Rendsburg", "darkmagenta","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)

set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
     layout = layout.auto(inv_aff_ig),
     vertex.size = 3,
     vertex.frame.color="black",
     vertex.color = V(inv_aff_ig)$city_name_color,
     vertex.label = NA,
     edge.color= "black",
     main="Inventors from Rendsburg in top 15 city's network")

Inventors by Highest Degree (>6)

inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Aurich", "yellow", "gray")

Position in the network

set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
     layout = layout.auto(inv_aff_ig),
     vertex.size = degree(inv_aff_ig),
     vertex.color = NA,
     vertex.label = ifelse(degree(inv_aff_ig)> 6, V(inv_aff_ig)$id, NA),
     main="Higehst Degree Inventors")

City affiliation of the inventors

high_degree_inv <- as.data.frame(unique(high_degree_inv <- (inv_person_parsed %>%
                                                              filter(inv_name %in% c("altemark, jens","harms, ulrich","jurkat, mark")) %>% 
                                                              select(inv_name, city))))
high_degree_inv %>% 
  knitr::kable(caption = "Inventors with Highest Degree and Their City Affilitions") %>% 
  kable_styling(bootstrap_options = c("striped","responsive", "hover"), full_width = F)
Inventors with Highest Degree and Their City Affilitions
inv_name city
jurkat, mark Norderstedt
harms, ulrich Norderstedt
altemark, jens Rendsburg
altemark, jens Berlin
harms, ulrich Hamburg
altemark, jens Kiel
LS0tDQp0aXRsZTogIklubm92YXRpb24gU2NlbmFyaW8gaW4gR2VybWFuIFdpbmQgTW90b3IgSW5kdXN0cnkgKDE5OTYtMjAxNikiDQpzdWJ0aXRsZTogIkEgU29jaWFsIE5ldHdvcmsgQW5hbHlzaXMgQXBwcm9hY2giDQphdXRob3I6ICJKaGFsYWsgR29wZSINCmRhdGU6ICcyMDIyLTA3LTEzJw0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjc3M6IGNzc19iYWNrLmNzcw0KICAgIHRoZW1lOiB5ZXRpDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9VFJVRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nID0gRkFMU0UpDQpgYGANCg0KIyBHZW5lcmFsIERhdGEgUHJlcGFyYXRpb24NCg0KIyMgTG9hZGluZyBMaWJyYXJpZXMNCg0KYGBge3IgbG9hZGluZyBsaWJyYXJpZXMsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9ImhpZGUifQ0Kc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KHNuYSkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZHBseXIpKQ0Kc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KGdnc2NpKSkNCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShwbG90bHkpKQ0Kc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KGlncmFwaCkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkobmV0d29yaykpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoa2FibGVFeHRyYSkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoaWdyYXBoZGF0YSkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoaW50ZXJncmFwaCkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoUkNvbG9yQnJld2VyKSkNCmBgYA0KDQojIyBMb2FkaW5nIERhdGFzZXQNCg0KYGBge3IgbG9hZGluZyBkYXRhc2V0fQ0KbG9hZCgicmVzX3NlbS5SRGF0YSIpDQojc3ViIHN0cmluZ2luZyB0aGUgSVBDMyBmcm9tIElQQw0KSVBDNCA8LSBzdWJzdHIoam9pbmVkX0lQQ19JbnYkSVBDLCBzdGFydCA9IDEsIHN0b3AgPSA0KSAjZXh0cmFjdGluZyB0aGUgSVBDMyBmcm9tIHRoZSBvcmlnaW5hbCBzb3J0ZWQgZGF0YXNldA0KSVBDNCA8LSBhcy5kYXRhLmZyYW1lKElQQzQpICMgZGVmaW5pbmcgaXQgYXMgYSBkYXRhZnJhbWUNCmRhdGFfZmluYWwgPC0gY2JpbmQoam9pbmVkX0lQQ19JbnYsIElQQzQpICMgY29tYmluaW5nIHRoZSBuZXdseSBjcmVhdGVkIElQQzMgY29udGFpbmluZyBkYXRhZnJhbWUgd2l0aCB0aGUgbWFpbiBkYXRhZnJhbWUNCnJtKGpvaW5lZF9JUENfSW52KSAmIHJtKElQQzQpICMgcmVtb3ZpbmcgdGhlIGRhdGFzZXQgdG8gZnJlZSBtZW1vcnkNCmRhdGFfZmluYWwgPC0gc3Vic2V0KGRhdGFfZmluYWwsIHNlbGVjdCA9IC1jKElQQyxjdHJ5X2NvZGUpKSAjIGRyb3BwaW5nIGNvbHVtbnMNCmBgYA0KDQojIyBEYXRhIENsZWFuaW5nDQoNCmBgYHtyIGRhdGEgY2xlYW5pbmd9DQpkYXRhIDwtIChkYXRhX2ZpbmFsICU+JSANCiAgICAgICAgICAgICAgICAgZmlsdGVyKElQQzQ9PSJGMDNEIikpICMgY3JlYXRpbmcgc3Vic2V0IG9mIFdpbmQgRW5lcmd5IEluZHVzdHJ5IChGMDNEKQ0Kcm0oZGF0YV9maW5hbCkNCmRhdGEgPC0gKGRhdGEgJT4lIA0KICAgICAgICAgICBmaWx0ZXIoYXBwX3llYXI+PSAxOTk2ICYgYXBwX3llYXIgPD0gMjAxNikpICMgbGltaXRpbmcgeWVhcnMgZnJvbSAxOTk2IHRvIDIwMTYNCg0KIyBub3cgZ2V0dGluZyByaWQgb2YgZW1wdHkgY2l0eSB2YWx1ZXMNCmRhdGEgPC0gKGRhdGEgJT4lDQogICAgICAgICAgIG11dGF0ZShjaXR5ID0gcmVwbGFjZShjaXR5LCBjaXR5ID09ICIiLCBOQSkpKSNtYWtpbmcgdGhlIGVtcHR5IHZhbHVlcyBOQQ0KZGF0YSA8LSBuYS5vbWl0KGRhdGEpICNnZXR0aW5nIHJpZCBvZiBOQSB2YWx1ZXMNCg0KIyBnZXR0aW5nIHJpZCBvZiBkdXBsaWNhdGUgdmFsdWVzDQpkYXRhX21haW4gPC0gZGF0YVshZHVwbGljYXRlZChkYXRhKSxdDQoNCiMgcmFua2luZyBjaXRpZXMgYWNjb3JkaW5nIHRvIHBhdGVudHMNCmRhdGFfbWFpbl9jaXR5X3JhbmsgPC0gKGRhdGFfbWFpbiAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KGNpdHkpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudChjaXR5LCBzb3J0ID0gVFJVRSwgIG5hbWUgPSAicGF0ZW50cyIpKSAjcmFua2luZyB0aGUgY2l0aWVzIGFjY29yZGluZyB0byB0aGUgbnVtYmVyIG9mIHBhdGVudCBhcHBsaWNhdGlvbnMNCg0KZGF0YV9tYWluXzE1IDwtIGhlYWQoZGF0YV9tYWluX2NpdHlfcmFuaywxNSkgIyBrZWVwaW5nIGZpcnN0IDE1IHBhdGVudCBvd25pbmcgY2l0aWVzIGluIHJhbmtlZCBmb3JtYXQNCmRhdGFfbWFpbl8xNV9hdHRyIDwtIChkYXRhX21haW4gJT4lDQogICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoY2l0eSAlaW4lIGMoIkF1cmljaCIsIkhhbWJ1cmciLCJCZXJsaW4iLCJTYWx6YmVyZ2VuIiwiUmVuZHNidXJnIiwiUmhlaW5lIiwiS2llbCIsIkFhY2hlbiIsIk11bmNoZW4iLCJOb3JkZXJzdGVkdCIsIk9zbmFicnVjayIsIkJyZW1lbiIsIkVybGFuZ2VuIiwiRHJlc2RlbiIsIk11bnN0ZXIiKSkpICMga2VlcGluZyB0aGUgbW9zdCAxNSBwYXRlbnQgb3duaW5nIGNpdGllcyB3aXRoIGFsbCBhdHRyaWJ1dGVzDQpgYGANCg0KIyBHZW5lcmFsIEluc2lnaHRzIGZyb20gdGhlIERhdGENCg0KIyMgVG9wIDE1IG1vc3QgcGF0ZW50IG93bmluZyBjaXRpZXMNCg0KYGBge3IgdG9wIG1vc3QgaW5ub3ZhdGl2ZSBjaXRpZXMsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NywgZmlnLndpZHRoPTgsIHJlc3VsdHM9ImFzaXMifQ0KcGxvdF9seShkYXRhX21haW5fMTUsDQogICAgICAgIHggPSBkYXRhX21haW5fMTUkY2l0eSwNCiAgICAgICAgeSA9IGRhdGFfbWFpbl8xNSRwYXRlbnRzLA0KICAgICAgICB0eXBlID0gImJhciIsDQogICAgICAgIGNvbG9yID0gZGF0YV9tYWluXzE1JGNpdHksDQogICAgICAgIHNob3dsZWdlbmQgPSBGQUxTRSwNCiAgICAgICAgY29sb3JzPXBhbF9qY28oKSgxMCkpICU+JSANCiAgbGF5b3V0KHRpdGxlID0gIlRvcCAxNSBHZXJtYW4gQ2l0aWVzIGluIFdpbmQgTW90b3IgSW5ub3ZhdGlvbiIsDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeW9yZGVyID0gImFycmF5IiwNCiAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeWFycmF5ID0gfmNpdHkpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIk51bWJlciBvZiBwYXRlbnRzIikNCiAgICAgICAgICkNCmBgYA0KDQojIE5ldHdvcmsgRGF0YSBQcmVwYXJhdGlvbiAoVXNpbmcgaWdyYXBoIGFuZCBzbmEgcGFja2FnZXMpDQoNCiMjIE4xLiBJbnZlbnRvciBuZXR3b3JrcyBmb3IgYWxsIGNpdGllcw0KDQpgYGB7ciBpbnYgbmV0IGFsbCBjaXRpZXN9DQppbnZfYWZmX2FsbCA8LSAoZGF0YV9tYWluICU+JSANCiAgICAgICAgICAgICAgc2VsZWN0KGFwcGxuX2lkLHBlcnNvbl9pZCkpDQppbnZfYWZmX2FsbF8ybW9kZSA8LSB0YWJsZShpbnZfYWZmX2FsbCkNCmludl9hZmZfYWxsX2FkaiA8LSBpbnZfYWZmX2FsbF8ybW9kZSAlKiUgdChpbnZfYWZmX2FsbF8ybW9kZSkNCmRpYWcoaW52X2FmZl9hbGxfYWRqKSA8LTAgIyBkZWxldGluZyB0aGUgZGlhZ29uYWxzDQppbnZfYWZmX2FsbF9pZyA8LSBncmFwaC5hZGphY2VuY3koaW52X2FmZl9hbGxfYWRqLCBtb2RlID0gInVuZGlyZWN0ZWQiLCB3ZWlnaHQgPSBUUlVFKQ0KcHJpbnQoaW52X2FmZl9hbGxfaWcpICMgQmFzaWMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG5ldHdvcmsNCmBgYA0KDQojIyBOMi4gQ2l0eSBuZXR3b3JrcyAoZm9yIDE1IG1vc3QgaW5ub3ZhdGl2ZSBjaXRpZXMpDQoNCmBgYHtyIGNpdHkgbmV0IDE1IGNpdGllc30NCmludl9jaXR5IDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUgDQogICAgICAgICAgICAgICBzZWxlY3QoY2l0eSwgYXBwbG5faWQpKQ0KaW52X2NpdHlfMm1vZGUgPC0gIHRhYmxlKGludl9jaXR5KSAgICMgY3Jvc3MgdGFidWxhdGUgLT4gMi1tb2RlIHNvY2lvbWF0cml4DQppbnZfY2l0eV9hZGogPC0gaW52X2NpdHlfMm1vZGUgJSolIHQoaW52X2NpdHlfMm1vZGUpDQpkaWFnKGludl9jaXR5X2FkaikgPC0wICMgZGVsZXRpbmcgdGhlIGRpYWdvbmFscw0KaW52X2NpdHlfaWcgPC0gZ3JhcGguYWRqYWNlbmN5KGludl9jaXR5X2FkaiwgbW9kZSA9ICJ1bmRpcmVjdGVkIiwgd2VpZ2h0ID0gVFJVRSkNCnByaW50KGludl9jaXR5X2lnKSAjIGJhc2ljIGluZm9ybWF0aW9uIGFib3V0IHRoZSBuZXR3b3JrDQoNCmBgYA0KDQojIyBOMy4gSW52ZW50b3IncyBuZXR3b3JrIG9mIHRvcCAxNSBjaXRpZXMNCg0KYGBge3IgaW52IG5ldH0NCiMgaW52ZW50b3IncyBkYXRhIGNsZWFuaW5nDQppbnZfcGVyc29uIDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUgDQogICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSxhcHBsbl9pZCkpICMgc3ViLXNldHRpbmcgdGhlIGRhdGEgZm9yIGludmVudG9ycyB3aXRoIHBhdGVudHMNCmludl9wZXJfYXR0ciA8LSAoZGF0YV9tYWluXzE1X2F0dHIgJT4lIA0KICAgICAgICAgICAgICAgICAgIHNlbGVjdChhcHBsbl9pZCwgY2l0eSkpDQoNCiMgcGFyc2luZyB0aGUgcGVyc29uJ3MgbmV0d29yayBkYXRhIHRvIGhhdmUgY2xlYW4gYW5kIG5vbi1kdXBsaWNhdGVkIHZhbHVlcw0KaW52X3BlcnNvbl9wYXJzZWQgPC0gaW52X3BlcnNvbg0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSkpDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCA8LSB0b2xvd2VyKGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lKQ0KaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwgPC0gc3ViKCIsIHByb2YuIGRyLi1pbmcuIiwiIiwgaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwpDQpsZW5ndGgodW5pcXVlKGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsKSkNCmludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsIDwtIHN1YigiLCBkci4taW5nLiIsIiIsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsKQ0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkpDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCA8LSBzdWIoIiwgZGlwbC4taW5nLiIsIiIsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsKQ0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkpDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCA8LSBzdWIoIiwgLWluZy4iLCIiLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkNCmxlbmd0aCh1bmlxdWUoaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwpKQ0KaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwgPC0gc3ViKCIsIGRyLiIsIiIsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsKQ0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkpDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCA8LSBzdWIoIiBkci4iLCIiLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkNCmxlbmd0aCh1bmlxdWUoaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwpKQ0KDQojIG5ldyBuZXR3b3JrIGNoYW5nZWQgc2l6ZQ0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkpL2xlbmd0aCh1bmlxdWUoaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWUpKQ0KDQojIGdldHRpbmcgcmlkIG9mIG9yaWdpbmFsIGludmVudG9yIG5hbWVzDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSA8LSBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbA0KDQojIHJlbW92aW5nIHRoaXJkIGNvbHVtbg0KaW52X3BlcnNvbl9wYXJzZWQgPC0gc3Vic2V0KGludl9wZXJzb25fcGFyc2VkLCBzZWxlY3QgPSAtYyhpbnZfbmFtZV9zbWFsbCkpDQoNCiMgY3JlYXRpbmcgbmV0d29yayB3aXRoIHRoZSBjbGVhbmVkIGRhdGENCmludl9wZXJzb25fMm1vZGUgPC0gdGFibGUoaW52X3BlcnNvbl9wYXJzZWQpICMgbWFraW5nIDIgbW9kZSBzb2Npb21hdHJpeA0KaW52X3BlcnNvbl9hZGogPC0gaW52X3BlcnNvbl8ybW9kZSAlKiUgdChpbnZfcGVyc29uXzJtb2RlKQ0KZGlhZyhpbnZfcGVyc29uX2FkaikgPC0wDQppbnZfYWZmX2lnIDwtIGdyYXBoLmFkamFjZW5jeShpbnZfcGVyc29uX2FkaiwgbW9kZSA9ICJ1bmRpcmVjdGVkIiwgd2VpZ2h0ID0gVFJVRSkNCg0KDQpgYGANCg0KIyBDcmVhdGluZyBOZXR3b3JrcyBhbmQgUGxvdHRpbmcgR3JhcGhzDQoNCkRldGFjaGluZyBwYWNrYWdlcyB0byBhdm9pZCBjb25mbGljdHMgYmV0d2VlbiBwYWNrYWdlIG9wZXJhdGlvbnMuDQoNCmBgYHtyIGxpYnJhcnkgZGV0YWNoaW5nLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGV0YWNoKHBhY2thZ2U6c25hKQ0KZGV0YWNoKHBhY2thZ2U6bmV0d29yaykNCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShpZ3JhcGgpKQ0KYGBgDQoNCiMjIE4xLiBDcmVhdGluZyB0aGUgbmV0d29yayBmb3IgYWxsIHRoZSBpbnZlbnRvcnMNCg0KYGBge3IgY29udi4gbjF9DQojIG1hdGNoaW5nIHRoZSBkYXRhc2V0IHdpdGggY2l0eSBhbmQgYXBwbGljYXRpb24gaWRzDQppbnZfcGVyc29uX3BhcnNlZCRjaXR5IDwtIGludl9wZXJfYXR0ciRjaXR5W21hdGNoKGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkLCBpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCldDQpgYGANCg0KIyMjIE4xLiBQbG90dGluZw0KDQpgYGB7ciBuMSBwbG90LCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD03fQ0Kc2V0LnNlZWQoMTAwKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KcGxvdChpbnZfYWZmX2FsbF9pZywNCiAgICAgdmVydGV4LmxhYmVsPU5BLA0KICAgICB2ZXJ0ZXguc2l6ZSA9IDMsDQogICAgIHZlcnRleC5jb2xvciA9IFYoaW52X2FmZl9hbGxfaWcpLA0KICAgICBtYWluPSJOZXR3b3JrIG9mIGFsbCB0aGUgaW52ZW50b3JzIikNCmBgYA0KDQojIyBOMi4gQ3JlYXRpbmcgbmV0d29yayBmb3IgMTUgY2l0aWVzDQoNCmBgYHtyIGNvbnYuIG4yfQ0KaW52X2NpdHlfaWcgPC0gKGludl9jaXR5X2lnICU+JSANCiAgICAgICAgICAgICAgICAgIHNldF92ZXJ0ZXhfYXR0cigNCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJ2ZXJ0ZXgubmFtZXMiLA0KICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGMoIkF1cmljaCIsIkhhbWJ1cmciLCJCZXJsaW4iLCJTYWx6YmVyZ2VuIiwiUmVuZHNidXJnIiwiUmhlaW5lIiwiS2llbCIsIkFhY2hlbiIsIk11bmNoZW4iLCJOb3JkZXJzdGVkdCIsIk9zbmFicnVjayIsIkJyZW1lbiIsIkVybGFuZ2VuIiwiRHJlc2RlbiIsIk11bnN0ZXIiKSAjIG1vZGlmeWluZyB2ZXJ0ZXggbmFtZXMgb24gdGhlIGlncmFwaCBvYmplY3QgKGFzIGNpdHkgbmFtZXMpDQogICAgICAgICAgICAgICAgICApKQ0KVihpbnZfY2l0eV9pZykkbGFiZWwgPC0gYygiQXVyaWNoIiwiSGFtYnVyZyIsIkJlcmxpbiIsIlNhbHpiZXJnZW4iLCJSZW5kc2J1cmciLCJSaGVpbmUiLCJLaWVsIiwiQWFjaGVuIiwiTXVuY2hlbiIsIk5vcmRlcnN0ZWR0IiwiT3NuYWJydWNrIiwiQnJlbWVuIiwiRXJsYW5nZW4iLCJEcmVzZGVuIiwiTXVuc3RlciIpICMgY2hhbmdpbmcgdGhlIGlncmFwaCBvYmplY3QncyBsYWJlbHMgYWxzbyBpbnRvIHRoZSBjaXR5IG5hbWVzDQpgYGANCg0KIyMjIE4yLiBDZW50cmFsaXR5IE1lYXN1cmVtZW50DQoNCmBgYHtyIG4yIGNlbnRyYWxpdHl9DQpjZW50cl9kZWdyZWUoDQogIGludl9jaXR5X2lnLA0KICBtb2RlID0gYygiYWxsIiwgIm91dCIsICJpbiIsICJ0b3RhbCIpLA0KICBsb29wcyA9IEYsDQogIG5vcm1hbGl6ZWQgPSBUUlVFKQ0KYGBgDQoNCiMjIyBOMi4gUGxvdHRpbmcNCg0KYGBge3IgbjIgcGxvdCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Nn0NCnBhcihtYXI9YygwLDAsMiwwKSkNCnNldC5zZWVkKDEwMCkNCnBsb3QoaW52X2NpdHlfaWcsDQogICAgIHZlcnRleC5sYWJlbD1WKGludl9jaXR5X2lnKSRjaXR5LA0KICAgICB2ZXJ0ZXguY29sb3I9VihpbnZfY2l0eV9pZyksDQogICAgIHZlcnRleC5zaXplPSAxMCwNCiAgICAgdmVydGV4LmZyYW1lLmNvbG9yPU5BLA0KICAgICB2ZXJ0ZXgubGFiZWwuZmFtaWx5PSAiQ2FtYnJpYSIsDQogICAgIHZlcnRleC5sYWJlbC5mb250PTIsDQogICAgIG1haW49Ik5ldHdvcmsgb2YgdG9wIDE1IGNpdGllcyIpDQpgYGANCg0KIyMgTjMuIFBsb3R0aW5nIGFuZCBjZW50cmFsaXR5IG1lYXN1cmVtZW50IG9mIGludmVudG9yJ3MgbmV0d29yayAodG9wIDE1IGNpdGllcykgDQojIyMgTjMuIENlbnRyYWxpdHkgTWVhc3VyZW1lbnQNCg0KYGBge3IgbjMgY2VudHJhbGl0eX0NCmNlbnRyX2RlZ3JlZSgNCiAgaW52X2FmZl9pZywNCiAgbW9kZSA9IGMoImFsbCIsICJvdXQiLCAiaW4iLCAidG90YWwiKSwNCiAgbG9vcHMgPSBGLA0KICBub3JtYWxpemVkID0gVFJVRSkNCmBgYA0KDQojIyMgTjMuIFBsb3R0aW5nDQoNCiMjIyMgR2VuZXJhbCBuZXR3b3JrIGdyYXBoDQoNCmBgYHtyIGdlbmVyYWwgbmV0IHBsb3QsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTZ9DQpzZXQuc2VlZCgxMDApDQpwYXIobWFyPWMoMCwwLDIsMCkpDQpwbG90KGludl9hZmZfaWcsDQogICAgIHZlcnRleC5sYWJlbD1OQSwNCiAgICAgdmVydGV4LnNpemU9MS41LA0KICAgICB2ZXJ0ZXguZnJhbWUuY29sb3I9ImJsYWNrIiwNCiAgICAgdmVydGV4LmNvbG9yID0gVihpbnZfYWZmX2lnKSwNCiAgICAgbWFpbj0iSW52ZW50b3IgbmV0d29yayBvZiB0b3AgMTUgY2l0aWVzXG5mb3IgMTk5Ni0yMDE2IikNCmBgYA0KDQojIyMjIFBsb3R0aW5nIHdpdGggZGVuc2l0eQ0KDQpgYGB7ciAgZGVuc2l0eSBwbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02fQ0Kc2V0LnNlZWQoMTAwKQ0KcGFyKG1hcj1jKDAsMCw0LDApKQ0KcGxvdChpbnZfYWZmX2lnLA0KICAgICB2ZXJ0ZXgubGFiZWw9TkEsDQogICAgIHZlcnRleC5zaXplPWRlZ3JlZShpbnZfYWZmX2lnKSoxLjUsDQogICAgIHZlcnRleC5mcmFtZS5jb2xvcj0iYmxhY2siLA0KICAgICB2ZXJ0ZXguY29sb3IgPSBWKGludl9hZmZfaWcpLA0KICAgICBtYWluPSJJbnZlbnRvciBuZXR3b3JrIG9mIHRvcCAxNSBjaXRpZXNcbmZvciAxOTk2LTIwMTZcbndpdGggZGVncmVlIG1lYXN1cmVtZW50IikNCmBgYA0KDQojIyMjIFBsb3R0aW5nIHdpdGggZGVuc2l0eSBhbmQgZWRnZSBiZXR3ZWVubmVzcw0KDQpgYGB7ciAgZGVuc2l0eSwgZWIgcGxvdCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Nn0NCnNldC5zZWVkKDEwMCkNCnBhcihtYXI9YygwLDAsNCwwKSkNCnBsb3QoaW52X2FmZl9pZywNCiAgICAgdmVydGV4LmxhYmVsPU5BLA0KICAgICB2ZXJ0ZXguZnJhbWUuY29sb3I9ImJsYWNrIiwNCiAgICAgdmVydGV4LmNvbG9yPVYoaW52X2FmZl9pZyksDQogICAgIHZlcnRleC5zaXplPWRlZ3JlZShpbnZfYWZmX2lnKSoxLjUsDQogICAgIGVkZ2UuY3VydmVkPS4xLA0KICAgICBtYWluPSJJbnZlbnRvciBuZXR3b3JrIG9mIHRvcCAxNSBjaXRpZXNcbmZvciAxOTk2LTIwMTZcbndpdGggZGVncmVlIG1lYXN1cmVtZW50IGFuZCBlZGdlIGJldHdlZW5uZXNzIiwNCiAgICAgZWRnZS53aWR0aCA9IGVkZ2VfYmV0d2Vlbm5lc3MoaW52X2FmZl9pZykqLjgpDQpgYGANCg0KIyBUb3AgNSBDaXR5J3MgSW5ub3ZhdGlvbiBTY2VuYXJpbyBvdmVyIHRoZSBUaW1lDQoNCkRldGFjaGluZyBwYWNrYWdlcyB0byBhdm9pZCBjb25mbGljdHMgYmV0d2VlbiBwYWNrYWdlIG9wZXJhdGlvbnMNCg0KYGBge3IgcGNrZyBkZXRhY2h9DQpkZXRhY2gocGFja2FnZTppZ3JhcGgpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkobmV0d29yaykpDQpgYGANCg0KIyMgQXVyaWNoDQoNCmBgYHtyIGF1cmljaCBuZXR9DQojIyBBdXJpY2ggMTk5NjoyMDA2IG5ldHdvcmsNCmF1cmljaF9kYXRhXzA2IDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKGNpdHk9PSJBdXJpY2giLCBhcHBfeWVhcj49MTk5NiAmIGFwcF95ZWFyPD0yMDA2KSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCmF1cmljaF9kYXRhXzA2IDwtIHRhYmxlKGF1cmljaF9kYXRhXzA2KQ0KZGltKGF1cmljaF9kYXRhXzA2KQ0KYXVyaWNoX2Fkal8wNiA8LSBhdXJpY2hfZGF0YV8wNiAlKiUgdChhdXJpY2hfZGF0YV8wNikNCmRpbShhdXJpY2hfYWRqXzA2KQ0KY2xhc3MoYXVyaWNoX2Fkal8wNikNCmF1cmljaF9ud18wNiA8LSAgbmV0d29yayhhdXJpY2hfYWRqXzA2LA0KICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeC50eXBlPSJhZGphY2VuY3kiLA0KICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGVkPUYpICAjIGNvbnZlcnQgaW50byAnbmV0d29yaycgZm9ybWF0DQoNCg0KIyMgQXVyaWNoIDIwMDc6MjAxNiBuZXR3b3JrDQphdXJpY2hfZGF0YV8xNiA8LSAoZGF0YV9tYWluXzE1X2F0dHIgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoY2l0eT09IkF1cmljaCIsIGFwcF95ZWFyPj0yMDA3ICYgYXBwX3llYXI8PTIwMTYpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCmF1cmljaF9kYXRhXzE2IDwtIHRhYmxlKGF1cmljaF9kYXRhXzE2KQ0KZGltKGF1cmljaF9kYXRhXzE2KQ0KYXVyaWNoX2Fkal8xNiA8LSBhdXJpY2hfZGF0YV8xNiAlKiUgdChhdXJpY2hfZGF0YV8xNikNCmRpbShhdXJpY2hfYWRqXzE2KQ0KY2xhc3MoYXVyaWNoX2Fkal8xNikNCmF1cmljaF9ud18xNiA8LSAgbmV0d29yayhhdXJpY2hfYWRqXzE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4LnR5cGU9ImFkamFjZW5jeSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RlZD1GKSAgIyBjb252ZXJ0IGludG8gJ25ldHdvcmsnIGZvcm1hdA0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIGF1cmljaCBwbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93ID0gYygxLDIpKQ0KcGFyKG1hcj1jKDMsMCwxLDApKQ0KDQojcGxvdCBmb3IgMTk5NjoyMDA2DQpwbG90Lm5ldHdvcmsoYXVyaWNoX253XzA2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiM3NTcwQjMiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIEF1cmljaCAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIHBhZD00LA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBzdWI9bmV0d29yay5zaXplKGF1cmljaF9ud18wNiksDQogICAgICAgICAgICAgY2V4Lm1haW49LjgpDQoNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsoYXVyaWNoX253XzE2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiM3NTcwQjMiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIEF1cmljaCAyMDA3OjIwMTYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCmNhdCgiVG90YWwgbm9kZXMgMTk5Ni0yMDA2OiIsIG5ldHdvcmsuc2l6ZShhdXJpY2hfbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUoYXVyaWNoX253XzE2KSkNCmBgYA0KDQojIyBIYW1idXJnDQoNCmBgYHtyIGhhbWJ1cmcgbmV0fQ0KIyMgSGFtYnVyZyAxOTk2OjIwMDYgbmV0d29yaw0KaGFtYnVyZ19kYXRhXzA2IDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKGNpdHk9PSJIYW1idXJnIiwgYXBwX3llYXI+PTE5OTYgJiBhcHBfeWVhcjw9MjAwNikgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgYXBwbG5faWQpKQ0KDQpoYW1idXJnX2RhdGFfMDYgPC0gdGFibGUoaGFtYnVyZ19kYXRhXzA2KQ0KZGltKGhhbWJ1cmdfZGF0YV8wNikNCmhhbWJ1cmdfYWRqXzA2IDwtIGhhbWJ1cmdfZGF0YV8wNiAlKiUgdChoYW1idXJnX2RhdGFfMDYpDQpkaW0oaGFtYnVyZ19hZGpfMDYpDQpjbGFzcyhoYW1idXJnX2Fkal8wNikNCmhhbWJ1cmdfbndfMDYgPC0gIG5ldHdvcmsoaGFtYnVyZ19hZGpfMDYsDQogICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4LnR5cGU9ImFkamFjZW5jeSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0ZWQ9RikgICMgY29udmVydCBpbnRvICduZXR3b3JrJyBmb3JtYXQNCg0KDQojIyBIYW1idXJnIDIwMDc6MjAwNiBuZXR3b3JrDQpoYW1idXJnX2RhdGFfMTYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoY2l0eT09IkhhbWJ1cmciLCBhcHBfeWVhcj49MjAwNyAmIGFwcF95ZWFyPD0yMDE2KSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCmhhbWJ1cmdfZGF0YV8xNiA8LSB0YWJsZShoYW1idXJnX2RhdGFfMTYpDQpkaW0oaGFtYnVyZ19kYXRhXzE2KQ0KaGFtYnVyZ19hZGpfMTYgPC0gaGFtYnVyZ19kYXRhXzE2ICUqJSB0KGhhbWJ1cmdfZGF0YV8xNikNCmRpbShoYW1idXJnX2Fkal8xNikNCmNsYXNzKGhhbWJ1cmdfYWRqXzE2KQ0KaGFtYnVyZ19ud18xNiA8LSAgbmV0d29yayhoYW1idXJnX2Fkal8xNiwNCiAgICAgICAgICAgICAgICAgICAgICBtYXRyaXgudHlwZT0iYWRqYWNlbmN5IiwNCiAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RlZD1GKSAgIyBjb252ZXJ0IGludG8gJ25ldHdvcmsnIGZvcm1hdA0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIGhhbWJ1cmcgcGxvdCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0NCnBhcihtZnJvdyA9IGMoMSwyKSkNCnBhcihtYXI9YygwLDAsMSwwKSkNCg0KI3Bsb3QgZm9yIDE5OTY6MjAwNg0KcGxvdC5uZXR3b3JrKGhhbWJ1cmdfbndfMDYsDQogICAgICAgICAgICAgdmVydGV4LmNvbD0iIzk5Qjg5OCIsDQogICAgICAgICAgICAgdmVydGV4LmNleD0xLA0KICAgICAgICAgICAgIHZlcnRleC5ib3JkZXI9ImJsYWNrIiwNCiAgICAgICAgICAgICBtYWluPSJJbnZlbnRvcnMgTmV0d29yayBmb3IgSGFtYnVyZyAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBwYWQ9NCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsoaGFtYnVyZ19ud18xNiwNCiAgICAgICAgICAgICB2ZXJ0ZXguY29sPSIjOTlCODk4IiwNCiAgICAgICAgICAgICB2ZXJ0ZXguY2V4PTEsDQogICAgICAgICAgICAgdmVydGV4LmJvcmRlcj0iYmxhY2siLA0KICAgICAgICAgICAgIG1haW49IkludmVudG9ycyBOZXR3b3JrIGZvciBIYW1idXJnIDIwMDc6MjAxNiIsDQogICAgICAgICAgICAgZnJhbWUgPSBULA0KICAgICAgICAgICAgIGNleC5tYWluPS44KQ0KY2F0KCJUb3RhbCBub2RlcyAxOTk2LTIwMDY6IiwgbmV0d29yay5zaXplKGhhbWJ1cmdfbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUoaGFtYnVyZ19ud18xNikpDQpgYGANCg0KIyMgQmVybGluDQoNCmBgYHtyIGJlcmxpbiBuZXR9DQojIyBCZXJsaW4gMTk5NjoyMDA2IG5ldHdvcmsNCmJlcmxpbl9kYXRhXzA2IDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUNCiAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoY2l0eT09IkJlcmxpbiIsIGFwcF95ZWFyPj0xOTk2ICYgYXBwX3llYXI8PTIwMDYpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgYXBwbG5faWQpKQ0KDQpiZXJsaW5fZGF0YV8wNiA8LSB0YWJsZShiZXJsaW5fZGF0YV8wNikNCmRpbShiZXJsaW5fZGF0YV8wNikNCmJlcmxpbl9hZGpfMDYgPC0gYmVybGluX2RhdGFfMDYgJSolIHQoYmVybGluX2RhdGFfMDYpDQpkaW0oYmVybGluX2Fkal8wNikNCmNsYXNzKGJlcmxpbl9hZGpfMDYpDQpiZXJsaW5fbndfMDYgPC0gIG5ldHdvcmsoYmVybGluX2Fkal8wNiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4LnR5cGU9ImFkamFjZW5jeSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGVkPUYpICAjIGNvbnZlcnQgaW50byAnbmV0d29yaycgZm9ybWF0DQoNCg0KIyMgQmVybGluIDIwMDc6MjAxNiBuZXR3b3JrDQpiZXJsaW5fZGF0YV8xNiA8LSAoZGF0YV9tYWluXzE1X2F0dHIgJT4lDQogICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKGNpdHk9PSJCZXJsaW4iLCBhcHBfeWVhcj49MjAwNyAmIGFwcF95ZWFyPD0yMDE2KSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QoaW52X25hbWUsIGFwcGxuX2lkKSkNCg0KYmVybGluX2RhdGFfMTYgPC0gdGFibGUoYmVybGluX2RhdGFfMTYpDQpkaW0oYmVybGluX2RhdGFfMTYpDQpiZXJsaW5fYWRqXzE2IDwtIGJlcmxpbl9kYXRhXzE2ICUqJSB0KGJlcmxpbl9kYXRhXzE2KQ0KZGltKGJlcmxpbl9hZGpfMTYpDQpjbGFzcyhiZXJsaW5fYWRqXzE2KQ0KYmVybGluX253XzE2IDwtICBuZXR3b3JrKGJlcmxpbl9hZGpfMTYsDQogICAgICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeC50eXBlPSJhZGphY2VuY3kiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RlZD1GKSAgIyBjb252ZXJ0IGludG8gJ25ldHdvcmsnIGZvcm1hdA0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIGJlcmxpbiBwbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93ID0gYygxLDIpKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KDQojcGxvdCBmb3IgMTk5NjoyMDA2DQpwbG90Lm5ldHdvcmsoYmVybGluX253XzA2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiNGMjZCMzgiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIEJlcmxpbiAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBwYWQ9NCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsoYmVybGluX253XzE2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiNGMjZCMzgiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIEJlcmxpbiAyMDA3OjIwMTYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCmNhdCgiVG90YWwgbm9kZXMgMTk5Ni0yMDA2OiIsIG5ldHdvcmsuc2l6ZShiZXJsaW5fbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUoYmVybGluX253XzE2KSkNCg0KYGBgDQoNCiMjIFNhbHpiZXJnZW4NCg0KYGBge3Igc2FsemJlcmdlbiBuZXR9DQojIyBTYWx6YmVyZ2VuIDE5OTY6MjAwNiBuZXR3b3JrDQpzYWx6YmVyZ2VuX2RhdGFfMDYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjaXR5PT0iU2FsemJlcmdlbiIsIGFwcF95ZWFyPj0xOTk2ICYgYXBwX3llYXI8PTIwMDYpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgYXBwbG5faWQpKQ0KDQpzYWx6YmVyZ2VuX2RhdGFfMDYgPC0gdGFibGUoc2FsemJlcmdlbl9kYXRhXzA2KQ0KZGltKHNhbHpiZXJnZW5fZGF0YV8wNikNCnNhbHpiZXJnZW5fYWRqXzA2IDwtIHNhbHpiZXJnZW5fZGF0YV8wNiAlKiUgdChzYWx6YmVyZ2VuX2RhdGFfMDYpDQpkaW0oc2FsemJlcmdlbl9hZGpfMDYpDQpjbGFzcyhzYWx6YmVyZ2VuX2Fkal8wNikNCnNhbHpiZXJnZW5fbndfMDYgPC0gIG5ldHdvcmsoc2FsemJlcmdlbl9hZGpfMDYsDQogICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4LnR5cGU9ImFkamFjZW5jeSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0ZWQ9RikgICMgY29udmVydCBpbnRvICduZXR3b3JrJyBmb3JtYXQNCg0KDQojIyBTYWx6YmVyZ2VuIDIwMDc6MjAxNyBuZXR3b3JrDQpzYWx6YmVyZ2VuX2RhdGFfMTYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjaXR5PT0iU2FsemJlcmdlbiIsIGFwcF95ZWFyPj0yMDA3ICYgYXBwX3llYXI8PTIwMTYpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgYXBwbG5faWQpKQ0KDQpzYWx6YmVyZ2VuX2RhdGFfMTYgPC0gdGFibGUoc2FsemJlcmdlbl9kYXRhXzE2KQ0KZGltKHNhbHpiZXJnZW5fZGF0YV8xNikNCnNhbHpiZXJnZW5fYWRqXzE2IDwtIHNhbHpiZXJnZW5fZGF0YV8xNiAlKiUgdChzYWx6YmVyZ2VuX2RhdGFfMTYpDQpkaW0oc2FsemJlcmdlbl9hZGpfMTYpDQpjbGFzcyhzYWx6YmVyZ2VuX2Fkal8xNikNCnNhbHpiZXJnZW5fbndfMTYgPC0gIG5ldHdvcmsoc2FsemJlcmdlbl9hZGpfMTYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeC50eXBlPSJhZGphY2VuY3kiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RlZD1GKSAgIyBjb252ZXJ0IGludG8gJ25ldHdvcmsnIGZvcm1hdA0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIHNhbHpiZXJnZW4gcGxvdCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0NCnBhcihtZnJvdyA9IGMoMSwyKSkNCnBhcihtYXI9YygwLDAsMSwwKSkNCg0KI3Bsb3QgZm9yIDE5OTY6MjAwNg0KcGxvdC5uZXR3b3JrKHNhbHpiZXJnZW5fbndfMDYsDQogICAgICAgICAgICAgdmVydGV4LmNvbD0iIzU5NEY0RiIsDQogICAgICAgICAgICAgdmVydGV4LmNleD0xLA0KICAgICAgICAgICAgIHZlcnRleC5ib3JkZXI9ImJsYWNrIiwNCiAgICAgICAgICAgICBtYWluPSJJbnZlbnRvcnMgTmV0d29yayBmb3IgU2FsemJlcmdlbiAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBwYWQ9NCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsoc2FsemJlcmdlbl9ud18xNiwNCiAgICAgICAgICAgICB2ZXJ0ZXguY29sPSIjNTk0RjRGIiwNCiAgICAgICAgICAgICB2ZXJ0ZXguY2V4PTEsDQogICAgICAgICAgICAgdmVydGV4LmJvcmRlcj0iYmxhY2siLA0KICAgICAgICAgICAgIG1haW49IkludmVudG9ycyBOZXR3b3JrIGZvciBTYWx6YmVyZ2VuIDIwMDc6MjAxNiIsDQogICAgICAgICAgICAgZnJhbWUgPSBULA0KICAgICAgICAgICAgIGNleC5tYWluPS44KQ0KY2F0KCJUb3RhbCBub2RlcyAxOTk2LTIwMDY6IiwgbmV0d29yay5zaXplKHNhbHpiZXJnZW5fbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUoc2FsemJlcmdlbl9ud18xNikpDQoNCmBgYA0KDQojIyBSZW5kc2J1cmcNCg0KYGBge3IgcmVuZHNidXJnIG5ldH0NCiMjIFJlbmRzYnVyZyAxOTk2OjIwMDYgbmV0d29yaw0KcmVuZHNidXJnX2RhdGFfMDYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjaXR5PT0iUmVuZHNidXJnIiwgYXBwX3llYXI+PTE5OTYgJiBhcHBfeWVhcjw9MjAwNikgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCnJlbmRzYnVyZ19kYXRhXzA2IDwtIHRhYmxlKHJlbmRzYnVyZ19kYXRhXzA2KQ0KZGltKHJlbmRzYnVyZ19kYXRhXzA2KQ0KcmVuZHNidXJnX2Fkal8wNiA8LSByZW5kc2J1cmdfZGF0YV8wNiAlKiUgdChyZW5kc2J1cmdfZGF0YV8wNikNCmRpbShyZW5kc2J1cmdfYWRqXzA2KQ0KY2xhc3MocmVuZHNidXJnX2Fkal8wNikNCnJlbmRzYnVyZ19ud18wNiA8LSAgbmV0d29yayhyZW5kc2J1cmdfYWRqXzA2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXgudHlwZT0iYWRqYWNlbmN5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0ZWQ9RikgICMgY29udmVydCBpbnRvICduZXR3b3JrJyBmb3JtYXQNCg0KDQojIyBSZW5kc2J1cmcgMjAwOjIwMTYgbmV0d29yaw0KcmVuZHNidXJnX2RhdGFfMTYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjaXR5PT0iUmVuZHNidXJnIiwgYXBwX3llYXI+PTIwMDcgJiBhcHBfeWVhcjw9MjAxNikgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCnJlbmRzYnVyZ19kYXRhXzE2IDwtIHRhYmxlKHJlbmRzYnVyZ19kYXRhXzE2KQ0KZGltKHJlbmRzYnVyZ19kYXRhXzE2KQ0KcmVuZHNidXJnX2Fkal8xNiA8LSByZW5kc2J1cmdfZGF0YV8xNiAlKiUgdChyZW5kc2J1cmdfZGF0YV8xNikNCmRpbShyZW5kc2J1cmdfYWRqXzE2KQ0KY2xhc3MocmVuZHNidXJnX2Fkal8xNikNCnJlbmRzYnVyZ19ud18xNiA8LSAgbmV0d29yayhyZW5kc2J1cmdfYWRqXzE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXgudHlwZT0iYWRqYWNlbmN5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0ZWQ9RikgICMgY29udmVydCBpbnRvICduZXR3b3JrJyBmb3JtYXQNCg0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIHJlbmRzYnVyZyBwbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93ID0gYygxLDIpKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KDQojcGxvdCBmb3IgMTk5NjoyMDA2DQpwbG90Lm5ldHdvcmsocmVuZHNidXJnX253XzA2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiMzNTVDN0QiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIFJlbmRzYnVyZyAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBwYWQ9NCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsocmVuZHNidXJnX253XzE2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiMzNTVDN0QiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIFJlbmRzYnVyZyAyMDA3OjIwMTYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCmNhdCgiVG90YWwgbm9kZXMgMTk5Ni0yMDA2OiIsIG5ldHdvcmsuc2l6ZShyZW5kc2J1cmdfbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUocmVuZHNidXJnX253XzE2KSkNCmBgYA0KDQojIFBvc2l0aW9uIG9mIHRoZSBUb3AgNSBDaXRpZXMgaW4gMTUgQ2l0eSdzIE5ldHdvcmsNCg0KRGV0YWNoaW5nIHBhY2thZ2VzIHRvIGF2b2lkIGNvbmZsaWN0cyBiZXR3ZWVuIHBhY2thZ2Ugb3BlcmF0aW9ucy4NCg0KYGBge3IgZGV0YWNoaW5nIGxpYnJhcmllc30NCmRldGFjaChwYWNrYWdlOm5ldHdvcmspDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoaWdyYXBoKSkNCmBgYA0KDQojIyBBdXJpY2gNCg0KYGBge3IgYXVyaWNoIHBvc2l0aW9ufQ0KIyMgcG9zaXRpb24gb2YgdGhlIGNpdGllcyBpbiB0aGUgb3ZlcmFsbCBuZXR3b3JrDQppbnZfcGVyc29uX3BhcnNlZCRjaXR5IDwtIGludl9wZXJfYXR0ciRjaXR5W21hdGNoKGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkLCBpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPC0gaW52X3BlcnNvbl9wYXJzZWQkY2l0eVttYXRjaChWKGludl9hZmZfaWcpJGlkLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KDQpWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciA8LSBpZmVsc2UoVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPT0gIkF1cmljaCIsICJyZWQiLCJhenVyZTEiKQ0KI1YoaW52X2FmZl9pZykkaWRbZGVncmVlKGludl9hZmZfaWcpPjVdDQojZGVncmVlKGludl9hZmZfaWcpDQoNCnNldC5zZWVkKDEwMCkNCnBhcihtYXI9YygwLDAsMSwwKSkNCnBsb3QoaW52X2FmZl9pZywNCiAgICAgbGF5b3V0ID0gbGF5b3V0LmF1dG8oaW52X2FmZl9pZyksDQogICAgIHZlcnRleC5zaXplID0gMywNCiAgICAgdmVydGV4LmZyYW1lLmNvbG9yPSJibGFjayIsDQogICAgIHZlcnRleC5jb2xvciA9IFYoaW52X2FmZl9pZykkY2l0eV9uYW1lX2NvbG9yLA0KICAgICB2ZXJ0ZXgubGFiZWwgPSBOQSwNCiAgICAgZWRnZS5jb2xvcj0gImJsYWNrIiwNCiAgICAgbWFpbj0iSW52ZW50b3JzIGZyb20gQXVyaWNoIGluIHRvcCAxNSBjaXR5J3MgbmV0d29yayIpDQoNCmBgYA0KDQojIyBIYW1idXJnDQoNCmBgYHtyIGhhbWJ1cmcgcG9zaXRpb259DQojIyBwb3NpdGlvbiBvZiB0aGUgY2l0aWVzIGluIHRoZSBvdmVyYWxsIG5ldHdvcmsNCmludl9wZXJzb25fcGFyc2VkJGNpdHkgPC0gaW52X3Blcl9hdHRyJGNpdHlbbWF0Y2goaW52X3BlcnNvbl9wYXJzZWQkYXBwbG5faWQsIGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkKV0NClYoaW52X2FmZl9pZykkaWQgPC0gY29sbmFtZXMoaW52X3BlcnNvbl9hZGopDQpWKGludl9hZmZfaWcpJGNpdHlfbmFtZSA8LSBpbnZfcGVyc29uX3BhcnNlZCRjaXR5W21hdGNoKFYoaW52X2FmZl9pZykkaWQsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lKV0NClYoaW52X2FmZl9pZykkaWQgPC0gY29sbmFtZXMoaW52X3BlcnNvbl9hZGopDQoNClYoaW52X2FmZl9pZykkY2l0eV9uYW1lX2NvbG9yIDwtIGlmZWxzZShWKGludl9hZmZfaWcpJGNpdHlfbmFtZSA9PSAiSGFtYnVyZyIsICJibHVlIiwiYXp1cmUxIikNCiNWKGludl9hZmZfaWcpJGlkW2RlZ3JlZShpbnZfYWZmX2lnKT41XQ0KI2RlZ3JlZShpbnZfYWZmX2lnKQ0KDQpzZXQuc2VlZCgxMDApDQpwYXIobWFyPWMoMCwwLDEsMCkpDQpwbG90KGludl9hZmZfaWcsDQogICAgIGxheW91dCA9IGxheW91dC5hdXRvKGludl9hZmZfaWcpLA0KICAgICB2ZXJ0ZXguc2l6ZSA9IDMsDQogICAgIHZlcnRleC5mcmFtZS5jb2xvcj0iYmxhY2siLA0KICAgICB2ZXJ0ZXguY29sb3IgPSBWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciwNCiAgICAgdmVydGV4LmxhYmVsID0gTkEsDQogICAgIGVkZ2UuY29sb3I9ICJibGFjayIsDQogICAgIG1haW49IkludmVudG9ycyBmcm9tIEhhbWJ1cmcgaW4gdG9wIDE1IGNpdHkncyBuZXR3b3JrIikNCg0KYGBgDQoNCiMjIEJlcmxpbg0KDQpgYGB7ciBiZXJsaW4gcG9zaXRpb259DQojIyBwb3NpdGlvbiBvZiB0aGUgY2l0aWVzIGluIHRoZSBvdmVyYWxsIG5ldHdvcmsNCmludl9wZXJzb25fcGFyc2VkJGNpdHkgPC0gaW52X3Blcl9hdHRyJGNpdHlbbWF0Y2goaW52X3BlcnNvbl9wYXJzZWQkYXBwbG5faWQsIGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkKV0NClYoaW52X2FmZl9pZykkaWQgPC0gY29sbmFtZXMoaW52X3BlcnNvbl9hZGopDQpWKGludl9hZmZfaWcpJGNpdHlfbmFtZSA8LSBpbnZfcGVyc29uX3BhcnNlZCRjaXR5W21hdGNoKFYoaW52X2FmZl9pZykkaWQsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lKV0NClYoaW52X2FmZl9pZykkaWQgPC0gY29sbmFtZXMoaW52X3BlcnNvbl9hZGopDQoNClYoaW52X2FmZl9pZykkY2l0eV9uYW1lX2NvbG9yIDwtIGlmZWxzZShWKGludl9hZmZfaWcpJGNpdHlfbmFtZSA9PSAiQmVybGluIiwgImRhcmtzbGF0ZWdyYXk0IiwiYXp1cmUxIikNCiNWKGludl9hZmZfaWcpJGlkW2RlZ3JlZShpbnZfYWZmX2lnKT41XQ0KI2RlZ3JlZShpbnZfYWZmX2lnKQ0KDQpzZXQuc2VlZCgxMDApDQpwYXIobWFyPWMoMCwwLDEsMCkpDQpwbG90KGludl9hZmZfaWcsDQogICAgIGxheW91dCA9IGxheW91dC5hdXRvKGludl9hZmZfaWcpLA0KICAgICB2ZXJ0ZXguc2l6ZSA9IDMsDQogICAgIHZlcnRleC5mcmFtZS5jb2xvcj0iYmxhY2siLA0KICAgICB2ZXJ0ZXguY29sb3IgPSBWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciwNCiAgICAgdmVydGV4LmxhYmVsID0gTkEsDQogICAgIGVkZ2UuY29sb3I9ICJibGFjayIsDQogICAgIG1haW49IkludmVudG9ycyBmcm9tIEJlcmxpbiBpbiB0b3AgMTUgY2l0eSdzIG5ldHdvcmsiKQ0KYGBgDQoNCiMjIFNhbHpiZXJnZW4NCg0KYGBge3Igc2FsemJlcmdlbiBwb3NpdGlvbn0NCiMjIHBvc2l0aW9uIG9mIHRoZSBjaXRpZXMgaW4gdGhlIG92ZXJhbGwgbmV0d29yaw0KaW52X3BlcnNvbl9wYXJzZWQkY2l0eSA8LSBpbnZfcGVyX2F0dHIkY2l0eVttYXRjaChpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCwgaW52X3BlcnNvbl9wYXJzZWQkYXBwbG5faWQpXQ0KVihpbnZfYWZmX2lnKSRpZCA8LSBjb2xuYW1lcyhpbnZfcGVyc29uX2FkaikNClYoaW52X2FmZl9pZykkY2l0eV9uYW1lIDwtIGludl9wZXJzb25fcGFyc2VkJGNpdHlbbWF0Y2goVihpbnZfYWZmX2lnKSRpZCwgaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWUpXQ0KVihpbnZfYWZmX2lnKSRpZCA8LSBjb2xuYW1lcyhpbnZfcGVyc29uX2FkaikNCg0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWVfY29sb3IgPC0gaWZlbHNlKFYoaW52X2FmZl9pZykkY2l0eV9uYW1lID09ICJTYWx6YmVyZ2VuIiwgImRhcmtvcmFuZ2UxIiwiYXp1cmUxIikNCiNWKGludl9hZmZfaWcpJGlkW2RlZ3JlZShpbnZfYWZmX2lnKT41XQ0KI2RlZ3JlZShpbnZfYWZmX2lnKQ0KDQpzZXQuc2VlZCgxMDApDQpwYXIobWFyPWMoMCwwLDEsMCkpDQpwbG90KGludl9hZmZfaWcsDQogICAgIGxheW91dCA9IGxheW91dC5hdXRvKGludl9hZmZfaWcpLA0KICAgICB2ZXJ0ZXguc2l6ZSA9IDMsDQogICAgIHZlcnRleC5mcmFtZS5jb2xvcj0iYmxhY2siLA0KICAgICB2ZXJ0ZXguY29sb3IgPSBWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciwNCiAgICAgdmVydGV4LmxhYmVsID0gTkEsDQogICAgIGVkZ2UuY29sb3I9ICJibGFjayIsDQogICAgIG1haW49IkludmVudG9ycyBmcm9tIFNhbHpiZXJnZW4gaW4gdG9wIDE1IGNpdHkncyBuZXR3b3JrIikNCmBgYA0KDQojIyBSZW5kc2J1cmcNCg0KYGBge3IgcmVuZHNidXJnIHBvc2l0aW9ufQ0KIyMgcG9zaXRpb24gb2YgdGhlIGNpdGllcyBpbiB0aGUgb3ZlcmFsbCBuZXR3b3JrDQppbnZfcGVyc29uX3BhcnNlZCRjaXR5IDwtIGludl9wZXJfYXR0ciRjaXR5W21hdGNoKGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkLCBpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPC0gaW52X3BlcnNvbl9wYXJzZWQkY2l0eVttYXRjaChWKGludl9hZmZfaWcpJGlkLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KDQpWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciA8LSBpZmVsc2UoVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPT0gIlJlbmRzYnVyZyIsICJkYXJrbWFnZW50YSIsImF6dXJlMSIpDQojVihpbnZfYWZmX2lnKSRpZFtkZWdyZWUoaW52X2FmZl9pZyk+NV0NCiNkZWdyZWUoaW52X2FmZl9pZykNCg0Kc2V0LnNlZWQoMTAwKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KcGxvdChpbnZfYWZmX2lnLA0KICAgICBsYXlvdXQgPSBsYXlvdXQuYXV0byhpbnZfYWZmX2lnKSwNCiAgICAgdmVydGV4LnNpemUgPSAzLA0KICAgICB2ZXJ0ZXguZnJhbWUuY29sb3I9ImJsYWNrIiwNCiAgICAgdmVydGV4LmNvbG9yID0gVihpbnZfYWZmX2lnKSRjaXR5X25hbWVfY29sb3IsDQogICAgIHZlcnRleC5sYWJlbCA9IE5BLA0KICAgICBlZGdlLmNvbG9yPSAiYmxhY2siLA0KICAgICBtYWluPSJJbnZlbnRvcnMgZnJvbSBSZW5kc2J1cmcgaW4gdG9wIDE1IGNpdHkncyBuZXR3b3JrIikNCmBgYA0KDQojIEludmVudG9ycyBieSBIaWdoZXN0IERlZ3JlZSAoPjYpDQoNCmBgYHtyIGludiBkZWdyZWV9DQppbnZfcGVyc29uX3BhcnNlZCRjaXR5IDwtIGludl9wZXJfYXR0ciRjaXR5W21hdGNoKGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkLCBpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPC0gaW52X3BlcnNvbl9wYXJzZWQkY2l0eVttYXRjaChWKGludl9hZmZfaWcpJGlkLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWVfY29sb3IgPC0gaWZlbHNlKFYoaW52X2FmZl9pZykkY2l0eV9uYW1lID09ICJBdXJpY2giLCAieWVsbG93IiwgImdyYXkiKQ0KYGBgDQoNCiMjIFBvc2l0aW9uIGluIHRoZSBuZXR3b3JrDQoNCmBgYHtyIGhpZ2ggZGVnIGludiBwbG90fQ0Kc2V0LnNlZWQoMTAwKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KcGxvdChpbnZfYWZmX2lnLA0KICAgICBsYXlvdXQgPSBsYXlvdXQuYXV0byhpbnZfYWZmX2lnKSwNCiAgICAgdmVydGV4LnNpemUgPSBkZWdyZWUoaW52X2FmZl9pZyksDQogICAgIHZlcnRleC5jb2xvciA9IE5BLA0KICAgICB2ZXJ0ZXgubGFiZWwgPSBpZmVsc2UoZGVncmVlKGludl9hZmZfaWcpPiA2LCBWKGludl9hZmZfaWcpJGlkLCBOQSksDQogICAgIG1haW49IkhpZ2Voc3QgRGVncmVlIEludmVudG9ycyIpDQoNCmBgYA0KDQojIyBDaXR5IGFmZmlsaWF0aW9uIG9mIHRoZSBpbnZlbnRvcnMNCg0KYGBge3IgaGlnaCBkZWcgaW52IGluIHRhYmxlfQ0KaGlnaF9kZWdyZWVfaW52IDwtIGFzLmRhdGEuZnJhbWUodW5pcXVlKGhpZ2hfZGVncmVlX2ludiA8LSAoaW52X3BlcnNvbl9wYXJzZWQgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihpbnZfbmFtZSAlaW4lIGMoImFsdGVtYXJrLCBqZW5zIiwiaGFybXMsIHVscmljaCIsImp1cmthdCwgbWFyayIpKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgY2l0eSkpKSkNCmhpZ2hfZGVncmVlX2ludiAlPiUgDQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gIkludmVudG9ycyB3aXRoIEhpZ2hlc3QgRGVncmVlIGFuZCBUaGVpciBDaXR5IEFmZmlsaXRpb25zIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsInJlc3BvbnNpdmUiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEYpDQpgYGA=