SNA Grad Seminar, Fall 2017 Due: October 24th, 11:59 pm Name of Student:

The purpose of this lab is to develop your familiarity conducting descriptive network analysis using the statistical software package R. This assignment will make use of a data set you collect by defining a search query (a collection of your user-defined search terms) from the New York Times’s Article Search Application Programming Interface. Networks are generated from the co-occurrences between search terms included in the same search query. For example, a link exists between “apple” and “orange” if there are articles in the New York Times that contained these two terms. You will be visualizing and interpreting individual and global network properties of this network.

You will be graded primarily on the completeness and accuracy of your responses, but the clarity of the prepared report will also affect your grade. While students may work together to perform the analysis, each student must submit his or her own report and is responsible for writing the narrative in the report. You must answer all of the bolded questions.

Part 1: Collect Network Data (20 pts)

For this lab, you will search the New York Times, save that data, create networks from that data, compare the differences among networks, and demonstrate your proficiency with basic network descriptive statistics.

Loading and Installing Packages, Set Working Directory

When working with R, you should run each line of code individually, unless it is part of a function definition, so you can see the results. Generally speaking, any line of code that includes ‘{’ (the beginning of a function definition) should be run with all the other lines until you hit ‘}’.

# Lines that start with a hashtag/pound symbol, like this one, are comment lines. Comment lines are ignored by R when it is interpreting code.
# You only need to install packages once. Remove the # in front of each line and then run it to install each package. After successful installation, delete the line of code or replace the #s so the R Notebook doesn't run into problems.
# install.packages('magrittr', repos = "https://cran.rstudio.com")
# install.packages('igraph', repos = "https://cran.rstudio.com")
# install.packages('httr', repos = "https://cran.rstudio.com")
# install.packages('data.table', repos = "https://cran.rstudio.com")
# install.packages('dplyr', repos = "https://cran.rstudio.com")
# install.packages('xml2', repos = "https://cran.rstudio.com")
# You need to load packages every time you run the script or restart R.
library(magrittr)
library(httr)
library(data.table)
library(igraph)
library(dplyr)
library(xml2)
# Set your directory for the project
# You can either enter your filename path within the parentheses below and remove the # creating the comment, or select "Session > Set Working Directory ... Source File Location" in R Studio.
# setwd("Input Directory")

Choose a topic for your search terms

You can decide search terms based on personal interests, research interests, or popular topical areas, among others. You have flexibility in selecting your search term list. For example, you can search for some commercial brands, celebrities, countries, universities, etc. It will be most useful if you choose a collection of words that are not all extremely common. Think about a set of words that might have interesting co-occurrences in articles within the New York Times website. For example, you might be interested in the last names of every Senator involved in a certain political debate, football teams, or cities and their co-occurrence in news articles. Generally speaking, proper nouns are best, but you might have compelling reasons to choose verbs or adjectives. You might want to throw a couple of terms in that aren’t thematically related to make sure you don’t get a totally connected component. The more interesting your network is in terms of differing centrality, distinct components, etc., the easier it will be to do the written analysis. Keep in mind that the Article Search archive is very large; many terms co-occur. You might want to consider two tenuously related subjects. The example file uses four football teams and their home senators, plus a few topical terms.

Create your text input

Create a plain text file with .txt extension in the same directory as the R Markdown Notebook used in this assignment. Make a note of the file name for use in the next code snippet. Place one search term per line, and use 15–20 terms. You’ll also likely want to add quotation marks around your search terms to ensure that you’re only receiving results for the complete term. NOTE: The function will process your terms so that they work in the URL request. You do not need to encode non-alphabetic characters.

The text file cannot include any additional information or characters and it must be a .txt file; Word or RTF documents won’t work.

Analysis

a. Provide a high level overview of the terms you included in the search query. In my word list I have the names of NFL teams, NFL players and commissioner. Also, there are names of some senators of the united states and president Trump who are politicians in general. Almost all of these politicians are republicans except Bill Nelson and president Trump who are democrats.

b. Why did you choose this collection of terms? Were there some specific overarching question—intellectual or extracurricular curiosity—that motivated this collection of terms? I have chosen this word list because I was interested to see the relationship between different NFL teams and their players. The connections of the politicians with each other. Also, It was interesting to see if there is a tie between politicians and the NFL teams and their players. On the other hand, it is expected that president Trump have connections with both politicians, NFL teams and players. c. How did you decide which terms to use in the search query? Were these terms you intuitively deemed important? Were they culled from a specific source or the result of some separate analysis or search query? This list of words was given in the lab. Since I mainly wanted to understand the relationships between politicians and NFL teams, I searched the names of some famous senators and the names of the NFL teams and their players. d. What are the insights you hope to glean by looking at the network of terms in terms of individual node metrics, sub-grouping of nodes, overall global network properties? I am curious to see that if any of my expectations from the network is true. For example, I hope to see a close relationships between politicians themselves, especially the ones who are republicans or democrats. Also, I want to see that if there are any connections between politicians and the NFL teams and their players. The charictristics of the network such as centerality and density is intresting too. Are people just connect with each other based on their jobs? ## Working with the API to Collect Your Data The New York Times controls access to its API by assigning each user a key. Each key has a limited number of calls that can be made within a certain time period. You can read more about the limitations of the API system here.

You will need to create your own API key to complete this assignment. Go to the New York Times developers page and request a key. You will copy that key (received via email) into the api variable below.

# Import your word list
name_of_file <- "NFL.txt" # Creates a variable called name_of_file that you should populate with the name of your text file between quotation marks.
word_list <- read.table(name_of_file, sep = "\n", stringsAsFactors = F) %>% unlist %>% as.vector # Reads the content of your file into a variable.
num_words <- length(word_list) # Creates a variable with the number of words in your list.
url_base <- "https://api.nytimes.com/svc/search/v2/articlesearch.json"
# When you receive the email with your API key, paste it below between the quotation marks.
api <- '76f06c3d16c54280b9233d8f3d76e4bf'

Our first function will gather all of the search terms and their number of hits to be placed in a table. All lines of a function should be run together.

Get_hits_one <- function(keyword1) {
  Sys.sleep(time=3)
  url <- paste0(url_base, "?api-key=", api, "&q=", URLencode(keyword1),"&begin_date=","20160101") # Begin date is in format YYYYMMDD; you can change it if you want only more recent results, for example.
  # The number of results
  print(keyword1)
  hits <- content(GET(url))$response$meta$hits %>% as.numeric
  print(hits)
  # Put results in table
  c(SearchTerm=keyword1,ResultsTotal=hits)
}

Now we will invoke our function to put information from the API into our global environment.

#Create a table of your words and their number of results.
total_table <- t(sapply(word_list,Get_hits_one))
total_table <- as.data.frame(total_table)
total_table$ResultsTotal <- as.numeric(as.character(total_table$ResultsTotal))

If you get zero hits for any of these terms, you should substitute that term for somethign else and rerun the lab up to this point. Next, we will define the function that will collect the article co-occurences network.

Get_hits_two <- function(row_input) {
  keyword1 <- row_input[1]
  keyword2 <- row_input[2]
  url <- paste0(url_base, "?api-key=", api, "&q=", URLencode(keyword1),"+", URLencode(keyword2),"&begin_date=","20160101") #match w/ Begin Date in Get_hits_one.
  # The number of results
  print(paste0(keyword1," ",keyword2)) 
  hits <- content(GET(url))$response$meta$hits %>% as.numeric
  print(hits)
  Sys.sleep(time=3)
  # Put results in table
  c(SearchTerm1=keyword1,SearchTerm2=keyword2,CoOccurrences=hits)
} 

In this next step, we will call the API and collect the co-occurrence network. This may take some time. If you receive “numeric(0)” in any of your resposnes, you’ve likely hit your API key limit and will either need to wait for the calls to reset (24 hours) or request a new key. If you receive the error message “$ operator is invalid for atomic vectors,” you have also hit the API call limit. This could be due to running the script multiple times, or due to hitting too many results based on very common search terms. Request a new API, shorten your word list, and try again. Don’t forget you need to reload your word list from the first part of the Lab in order to get a different set of results! You must also rerun the functions to reassign the API value. If none of your results come back as “0,” you might want to redo your search with the appropriate words.

# Convert the pairs list into a table
pairs_list <- expand.grid(word_list,word_list) %>% filter(Var1 != Var2)
pairs_list <- t(combn(word_list,2))
#Create a network table, run the Get_hits_two function using the pairs lists
network_table <- t(apply(pairs_list,1,Get_hits_two))
#Convert the network table into a dataframe
network_table <- as.data.frame(network_table)
# Read each the content of each item within the $CoOccurreences factor as characters, 
# then force those characters into the "numeric" or "double" type.
network_table$CoOccurrences <- as.numeric(as.character(network_table$CoOccurrences))
# Convert data to data.table type.
total_table <- as.data.table(total_table)
network_table <- as.data.table(network_table)

# Remove zero edges from your network
network_table <- network_table[!CoOccurrences==0] 

# Create a graph object with your data
g_valued <- graph_from_data_frame(d = network_table[,1:3,with=FALSE],directed = FALSE,vertices = total_table)

# If you're having trouble with data collection, you can load the 'NFL Lab Results.RData' file now by clicking the open folder icon on the "Environment"" tab and continue the lab from here. You'll need to figure out what the significance of the terms are yourself, however.
# You should save your data at this point by clicking the floppy disk icon under the "Environment" tab.

Analysis

Is the graph directed or undirected? This is an undirected network. How many nodes and links does your network have? 15

numVertices <- vcount(g_valued)
numVertices
numEdges <- ecount(g_valued)
numEdges

What is the number of possible links in your network? 105

maxEdges <- numVertices*(numVertices-1)/2
maxEdges

What is the density of your network? The density is 0.3333333

graphDensity <- numEdges/maxEdges # manual calculation
graphDensity
graphDensity1 <- graph.density(g_valued) # using the graph.density function from igraph
graphDensity1

Briefly describe how your choice of dataset may influence your findings.
Our search results are completely depend on which term we use.If we use different search terms, we would expect completely different graph structures. For example, if we use “Sen. Bill Cassidy” the search result would include the articles that have this exact words (Sen. Bill Cassidy) and it would skip the articles that have just mentioned this senator as “Bill Cassidy”. As a result we can conclude that search terms might end up with differences in number of the links,(base on the relationships between subgroups of our terms).Also, there would be differences in desity. Moreover, selecting differnt style of a specific word could effect our result. For example, choosing “Carolina”" over “Carolina Panthers”" would give us redundant information about the city and it’s relationship to the other nodes. # Part 2: Visualize Your Network (20 points)

Let’s start by visualizing the network that we’ve collected from the New York Times Article Search API. We’ll need to choose node colors and set a layout. You can learn more about Fruchterman Reingold layout and other layouts here.

## Learn more about plotting with igraph
?? igraph.plotting
colbar = rainbow(length(word_list)) ## we are selecting different colors to correspond to each word
V(g_valued)$color = colbar
# Set layout here 
L = layout_with_fr(g_valued)  # Fruchterman Reingold
plot(g_valued,vertex.color=V(g_valued)$color, layout = L, vertex.size=6) 

Analysis

In a paragraph, describe the macro-level structure of your graphs based on the Fruchterman Reingold visualization. It is a giant connected component and there are several sub-components (subgroups) in the graph. There is no isolated component. As expected, we can see that based on their jobs, all senators are connected to each other. Also, there is a tie between republicans and democrats. All of the sub-components are connected with each other by liaison node trump. In the other hand we can see that President Trump have relationship with both NFL teams and senators. The subgroup of the NFL teams seem to be more connected than the subgroup of the politicians. One of the reasons could be because we have used “Sen” before the names of the senators, we might have skiped some of the links between senators.

Now we’ll create a second visualization using a different layout.

## You can change the layout by picking one of the other options. Uncomment one of the lines below by erasing the # and running the line. Try to find a layout that gives you different information that Fruchterman Reingold.

 L = layout_with_dh(g_valued) ## Davidson and Harel

# L = layout_with_drl(g_valued) ## Force-directed

# L = layout_with_kk(g_valued) ## Spring
plot(g_valued,vertex.color=V(g_valued)$color, layout = L, vertex.size=6) 

Analysis

In a paragraph, compare and contrast the information given to you by the two different layouts. Using different layouts and compare them with each other help us to find whether if any of the information have been missed in one layout or not. For instance, in the Fruchterman Reingold layout we cannot see the relation between Trump and Nelson or Trump and some NFL teams. So, we might think that there is no connection between them. But, in the Davidson and Harel layout Trump have connections with Nelson and NFL eams like “Carolina Panthers” . Therefore, comparing different layouts with each other is can help us to better understand the links between the nodes and gain all the possible information. # Part 3: Community Detection Analysis with R (20 Points)

Identifying subgroups within a network is of great interest to social network researchers, so a variety of algorithms have been developed to identify and measure subgroups. We will use some of R’s built-in tools to identify subgroups and central nodes for visual inspection.

For the remainder of the visualizations we will use the Fruchterman Reingold layout.

L = layout_with_fr(g_valued) 

Cluster the nodes in your network.

# Learn more about the clustering algorithm.
?? cluster_walktrap
cluster <- cluster_walktrap(g_valued)
# Find the number of clusters
membership(cluster)   # affiliation list
length(sizes(cluster)) # number of clusters
# Find the size the each cluster 
# Note that communities with one node are isolates, or have only a single tie
sizes(cluster) 

How many communities have been created? 3 How many nodes are in each community? first community have 2 nodes, second community have 7 nodes and the last one has 6 nodes.

For your network, what might each cluster of nodes potentially have in common? Describe each cluster, its membership, and the relationship between nodes in the cluster. First, the community with 6 nodes is all NFL teams. they are each others rival in football league, They trade their players and coaches with each other, etc. Second, the community with 7 nodes consists of Donald Trump, Steve Scalise, Sen.Bill Nelson, Sen. Marco Rubio, Sen. Lindsey Graham, Sen. David Perdue, and Sen.Johnoy Isakson. They are all politician, they all work in congress. Third, the community with 2 nodes is include of Bill cassidy and Tim Scott who are both republicans and they both have joined the congress in recent years. Also, their connection might be because of sen. Bill Cassidy’s job as a physician he had a relation to Scott about health care.

Next we visualize the clusters by coloring nodes according to their modularity class.

plot(cluster, g_valued, col = V(g_valued)$color, layout = L, vertex.size=6)

What information does this layout convey? Are the clusters well-separated, or is there a great deal of overlap? Is it easier to identify the common themes among clusters in this layout rather than looking only at the graphs? It shows the common interest and intraction between each nodes of one cluster. The clusters are well-separated and there are no overlaps between them. It is easier to identify the common themes among clusters in this layout rather than looking only at the graphs since this layout determine each cluster with differnt color.

What differences are there between nodes in the same cluster and across clusters? In the politicians cluster with 7 nodes, the number of the links of each senator with the other nodes differs with the other senators. This might be because of 1.being republican or a democrat senator, 2.the residency states of each of the senators, or 3.our use of search term(use of Sen before the names of the senators). In the cluster of NFL teams all of them are connected to each other. In this cluster differences could be the states of the NFL teams and their players. In the cluster with 2 nodes we have Bill cassidy and Tim Scott. Tim Scott is the only node which does not have a link with Trump and he is just have a tie with Bill cassidy.

Describe the brokers between any components and cliques. What are common features of these brokers? About how many brokers would you have to remove from your network to “shatter” it into two or more disconnected components? The brokers here are Trump and Cassidy and they role as an only connector of the two clusters. Donald Trump is the broker between NFL teams and the politicians clusters. Cassidy is a broker between the cluster with 7 politicians and the cluster with Cassidy and Scott. These brokers control the information flow between each two clusters and they should have high centrality. If we eliminate Donald Trump from the network, we can shatter it into two disconnected components. # Part 4: Centrality Visualization & Weighted Values (20 Points)

For each network, you will use centrality metrics to improve your visualization. You may need to adjust the size parameter to make your network more easily visible.

Degree Centrality

totalDegree <- degree(g_valued,mode="all")
sort(totalDegree,decreasing=TRUE)[1:5]
g2 <- g_valued
V(g2)$size <- totalDegree*2 #can adjust the number if nodes are too big
plot(g2, layout = L, vertex.label=NA)

Briefly explain degree centrality and why nodes are more or less central in the network. Degree centrality is defined by the number of the links that one node have. The more a node have links, the more central it is. In this network, since Donald Trump have a connection with every other nodes (except Tim Scott) it has the highest degree centrality in the network. Likewise, nodes with just one links such as Tim Scott have the lowest degree centrality in this network.

Weighted Degree Centrality

wd <- graph.strength(g_valued,weights = E(g_valued)$CoOccurrences)
sort(wd,decreasing=TRUE)[1:5]
wg2 <- g_valued
V(wg2)$size <- wd*.1 # adjust the number if nodes are too big
plot(wg2, layout = L, vertex.label=NA, edge.width=sqrt(E(g_valued)$CoOccurrences)) #taking the square root is a good way to make a large range of numbers visible in an edge. Otherwise edges tend to cover up all the other edges and obscure the relationships.

What does the addition of weighted degree and edge information tell you about your graph? In weighted networks the degree centrality is calculated as the sum of weights assigned to the node’s by the number of two words which exist in one article. We can see that the nodes with the highest weighted degree are in the cluster which consists of NFL teams. Edge information shows the square root of the number of the two nodes which exist in one article. Also, the size of the each node shows the degree centrality of this particular node. If the node has a high centrality, it appears larger in it’s size. Moreover, it can be seen that there are more articles about NFL teams than politicians in New York Times.

Betweenness Centrality

b <- betweenness(g_valued,directed=TRUE)
sort(b,decreasing=TRUE)[1:5]
g4 <- g_valued
V(g4)$size <- b*1.2#can adjust the number
plot(g4, layout = L, vertex.label=NA)

Briefly explain betweenness centrality and why nodes are more or less central in the network. Betweenness centality shows that how much a node have been involved between different groups of the network. The nodes which are brokers have the highest betweenness centrality. In our network the brokers are Trump and Cassidy. Trump has lied between all 3 subgroups(the NFL teams, 2 groups of politicians), so it has the highest betweenness centrality in the graph. Cassidy is a broker too and he lies between the 2 groups of the politicians. Therefore, Cassidy have the second highest betweenness centrality in the network. Since the other nodes of the network only have participated in their own subgroups, they have low betweenness centrality.

Weighted Betweenness Centrality

wbtwn <- betweenness(g_valued,weights = E(g_valued)$CoOccurrences)
sort(wbtwn,decreasing=TRUE)[1:5]
wBtwnG <- g_valued
V(wBtwnG)$size <- wbtwn*.5 # adjust the number if nodes are too big
plot(wBtwnG, layout = L, vertex.label=NA, edge.width=sqrt(E(g_valued)$CoOccurrences)) #taking the square root is a good way to make a large range of numbers visible in an edge.

What does the addition of weighted degree and edge information tell you about your graph? we can see that in this gragh Trump is still have the highest weighted betweenness but instead of Cassidy, Sen. Bill Nelson have the second highest betweenness centrality. I guess that it might be because of the number of their links and their costs. We can add that in Igragh since the distances of the links with less width are shorter, we prefer to use the links with less width in betweenness centrality. As we know when the size of a node shows it’s betweenness centrality.

Closeness Centrality

c <- closeness(g_valued)
sort(c,decreasing=TRUE)[1:5]
g5 <- g_valued
V(g5)$size <- c*500  #can adjust the number
plot(g5, layout = L, vertex.label=NA)

Briefly explain closeness centrality and why nodes are more or less central in the network. Closeness centrality shows how easily one actor can reach to the rest of network. The node with the shortest path to access to the other nodes have the highest closeness centrality. we can see since Trump lies between all three clusters in this network, it has the shortest path to the others and the highest closeness centrality. ### Weighted Closeness Centrality

wClsnss <- closeness(g_valued,weights = E(g_valued)$CoOccurrences)
sort(wClsnss,decreasing=TRUE)[1:5]
wClsnssG <- g_valued
V(wClsnssG)$size <- wClsnss*1000 # adjust the number if nodes are too big
plot(wClsnssG, layout = L, vertex.label=NA, edge.width=sqrt(E(g_valued)$CoOccurrences)) #taking the square root is a good way to make a large range of numbers visible in an edge.

What does the addition of weighted degree and edge information tell you about your graph? Here, we have a weighted network which every links have wieghts. This weightening assignment is based on the number if existence of both two actors in the same article. Also node’s size is sum of wieghts of its links. So we can conclude that node’s size is closeness centerallity for that node and links wigths show how many article have both two actor in it. In this network, Trump and Sen. Bill Nelson have the highest Centerality(Trump is highest). We can also mentions that ipraph is based on costs. Lower cost nodes have easier way to reach another nodes. Like here, between Trump and Sen. Nelson. ## Eigenvector Centrality

eigc <- eigen_centrality(g_valued,directed=TRUE)
sort(eigc$vector,decreasing=TRUE)[1:5]
g6 <- g_valued
V(g6)$size <- eigc$vector*50 #can adjust the number
plot(g6, layout = L, vertex.label=NA)

Briefly explain eigenvector centrality and why nodes are more or less central in the network. Eigenvector centrality is based on the node’s neighbour’s centeralities. the more centerality of the neighbours of a node are higher, the eigenvector centerality of this node would be higher too. based on this definition we can see that a node that has more influence in the network is more central (here is the Trump node(broker)). Also, since all the NFL teams are connected to each other and to the Trump, they have high eigenvector centrality too. ## Analysis Choose the visualization that you think is most interesting and briefly explain what it tells you about a central node in your network. Discuss the type of centrality, and what that node’s centrality score tells you about the search co-occurrence network. I think the most interesting visualization is the Weighted degree centrality. It can be seen that politicians and senators are less appeared in the articles than NFL teams maybe it is because NFL teams are more popular than the politicians among the people or it might be because of our search terms. These NFL teams have more weighted centrality than the politicians. Briefly discuss an interesting difference between types of centrality for your network. It is interesting than almost in all the graphs the broker(Trump node) have the highest centrality. But node Cassidy is almost different in each of the centeralities(degree,betweenness,weighed). Moreover, we can see that the graph of the combination of two kinds of centrality could be very differnt from each individual one of them. For example the graph of weighted closeness centrality is different from closeness centrality. Furthermore, it can be seen that if a node has high degree centrality, it does not mean that it would have high betweeness centrality or high eigenvector value too. ## Global Network Metrics with R

Compute the network centralization scores for your network for degree, betweenness, closeness, and eigenvector centrality.

# Degree centralization
centralization.degree(g_valued,normalized = TRUE)

# Betweenness centralization
centralization.betweenness(g_valued,normalized = TRUE)

# Closeness centralization 
centralization.closeness(g_valued,normalized = TRUE)

# Eigenvector centralization 
centralization.evcent(g_valued,normalized = TRUE)

Record the centralization score of each centrality measure. Degree centralization = 0.5952381 Betweenness centralization = 0.7056515 Closeness centralization = 0.7779971 Eigenvector centralization = 0.5904349 Briefly explain what the centralization of a network is. The centeralization of a network shows that is a nework is centeralized on overall or not. If we have one node which has the highest centrality in the nework, our network is globally centeralized. But, when we have several nodes with high centralization, our network is not considered as a centeralized network. Compare the centralization scores above with the graphs you created where the nodes are scaled by centrality. Describe the appearance of more centralized v. less centralized networks. Since betweenness and closeness centralities of the network which are 0.7056515 and 0.7779971 are more than degree and Eigenvecto centeralization, our network is more centeralized in betweenness and closeness than degree and Eigenvecto. ## Part 5. Power Laws & Small Worlds (20)

Power Laws

Networks often demonstrate power law distributions. Plot the degree distribution of the nodes in your base graph.

# Calculate degree distribution
deg <- degree(g_valued,v=V(g_valued), mode="all")
deg

# Degree distribution is the cumulative frequency of nodes with a given degree
deg_distr <-degree.distribution(g_valued, cumulative=T, mode="all")
deg_distr
plot(deg_distr, ylim=c(.01,10), bg="black",pch=21, xlab="Degree", ylab="Cumulative Frequency") #You may need to adjust the ylim to a larger or smaller number to make the graph show more data.

Test whether it’s approximately a power law, estimate log f (k) = log a − c log k. “This says that if we have a power-law relationship, and we plot log f (k) as a function of log k, then we should see a straight line: −c will be the slope, and log a will be the y-intercept. Such a “log-log” plot thus provides a quick way to see if one’s data exhibits an approximate power-law: it is easy to see if one has an approximately straight line, and one can read off the exponent from the slope.” (E&K, Chapter 18, p.546).

power <- power.law.fit(deg_distr)
power
plot(deg_distr, log="xy", ylim=c(.01,10), bg="black",pch=21, xlab="Degree", ylab="Cumulative Frequency")

Does your network exhibit a power law distribution of degree centrality? Since we do not have any long tail in the degree distribution plot we can see that our network does not exhibit a power low distribution. the other reason is that if our network was a power law distribution the log plot would be like a staight line, which is not in this network.

Small Worlds

Networks often demonstrate small world characteristics. Compute the average clustering coefficient (ACC) and the characteristic path length (CPL).

# Average clustering coefficient (ACC)
transitivity(g_valued, type = c("average"))

# Characteristic path length (CPL)
average.path.length(g_valued)

Compute the ACC and CPL for 100 random networks with the same number of nodes and ties as your test network.

accSum <- 0
cplSum <- 0
for (i in 1:100){
  grph <- erdos.renyi.game(numVertices, numEdges, type = "gnm")
  accSum <- accSum + transitivity(grph, type = c("average"))
  cplSum <- cplSum + average.path.length(grph)
}
accSum/100
cplSum/100

Based on these data, would you conclude that the observed network demonstrates small world properties? Why or why not? Since the ACC of the network is about 0.82 and it is more than average Acc of the random network, Networks demonstrate small world characteristics. Also because CPL of the network which is about CPL 1.7 is less than the CPL of the random network it also affirms that the network is small world. ## Wrapping up To complete the lab, make sure output/previews have been generated for each block of code. Then click the “Publish” button on the upper right hand corner of this screen and sign up for an RPubs account. Submit the URL of the published, completed lab on Canvas.

LS0tDQp0aXRsZTogJ0Rlc2NyaXB0aXZlIEFuYWx5dGljIEV4ZXJjaXNlIDE6IFZpc3VhbGl6aW5nIGFuZCBJbnRlcnByZXRpbmcgTmV0d29ya3MnDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdA0KICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQNCiAgd29yZF9kb2N1bWVudDogZGVmYXVsdA0KLS0tDQoqKlNOQSBHcmFkIFNlbWluYXIsIEZhbGwgMjAxNyoqDQoqKkR1ZToqKiBPY3RvYmVyIDI0dGgsIDExOjU5IHBtDQoqKk5hbWUgb2YgU3R1ZGVudCoqOiANCg0KVGhlIHB1cnBvc2Ugb2YgdGhpcyBsYWIgaXMgdG8gZGV2ZWxvcCB5b3VyIGZhbWlsaWFyaXR5IGNvbmR1Y3RpbmcgZGVzY3JpcHRpdmUgbmV0d29yayBhbmFseXNpcyB1c2luZyB0aGUgc3RhdGlzdGljYWwgc29mdHdhcmUgcGFja2FnZSBSLiBUaGlzIGFzc2lnbm1lbnQgd2lsbCBtYWtlIHVzZSBvZiBhIGRhdGEgc2V0IHlvdSBjb2xsZWN0IGJ5IGRlZmluaW5nIGEgc2VhcmNoIHF1ZXJ5IChhIGNvbGxlY3Rpb24gb2YgeW91ciB1c2VyLWRlZmluZWQgc2VhcmNoIHRlcm1zKSBmcm9tIHRoZSAqW05ldyBZb3JrIFRpbWVzXSh3d3cubnl0aW1lcy5jb20pKidzIEFydGljbGUgU2VhcmNoIFtBcHBsaWNhdGlvbiBQcm9ncmFtbWluZyBJbnRlcmZhY2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0FwcGxpY2F0aW9uX3Byb2dyYW1taW5nX2ludGVyZmFjZSkuIE5ldHdvcmtzIGFyZSBnZW5lcmF0ZWQgZnJvbSB0aGUgY28tb2NjdXJyZW5jZXMgYmV0d2VlbiBzZWFyY2ggdGVybXMgaW5jbHVkZWQgaW4gdGhlIHNhbWUgc2VhcmNoIHF1ZXJ5LiBGb3IgZXhhbXBsZSwgYSBsaW5rIGV4aXN0cyBiZXR3ZWVuIOKAnGFwcGxl4oCdIGFuZCDigJxvcmFuZ2XigJ0gaWYgdGhlcmUgYXJlIGFydGljbGVzIGluIHRoZSAqTmV3IFlvcmsgVGltZXMqIHRoYXQgY29udGFpbmVkIHRoZXNlIHR3byB0ZXJtcy4gIFlvdSB3aWxsIGJlIHZpc3VhbGl6aW5nIGFuZCBpbnRlcnByZXRpbmcgaW5kaXZpZHVhbCBhbmQgZ2xvYmFsIG5ldHdvcmsgcHJvcGVydGllcyBvZiB0aGlzIG5ldHdvcmsuDQoNCllvdSB3aWxsIGJlIGdyYWRlZCBwcmltYXJpbHkgb24gdGhlIGNvbXBsZXRlbmVzcyBhbmQgYWNjdXJhY3kgb2YgeW91ciByZXNwb25zZXMsIGJ1dCB0aGUgY2xhcml0eSBvZiB0aGUgcHJlcGFyZWQgcmVwb3J0IHdpbGwgYWxzbyBhZmZlY3QgeW91ciBncmFkZS4gIFdoaWxlIHN0dWRlbnRzIG1heSB3b3JrIHRvZ2V0aGVyIHRvIHBlcmZvcm0gdGhlIGFuYWx5c2lzLCBlYWNoIHN0dWRlbnQgbXVzdCBzdWJtaXQgaGlzIG9yIGhlciBvd24gcmVwb3J0IGFuZCBpcyByZXNwb25zaWJsZSBmb3Igd3JpdGluZyB0aGUgbmFycmF0aXZlIGluIHRoZSByZXBvcnQuIFlvdSBtdXN0IGFuc3dlciBhbGwgb2YgdGhlIGJvbGRlZCBxdWVzdGlvbnMuDQoNCiMgUGFydCAxOiBDb2xsZWN0IE5ldHdvcmsgRGF0YSAoMjAgcHRzKQ0KDQpGb3IgdGhpcyBsYWIsIHlvdSB3aWxsIHNlYXJjaCB0aGUgKk5ldyBZb3JrIFRpbWVzKiwgc2F2ZSB0aGF0IGRhdGEsIGNyZWF0ZSBuZXR3b3JrcyBmcm9tIHRoYXQgZGF0YSwgY29tcGFyZSB0aGUgZGlmZmVyZW5jZXMgYW1vbmcgbmV0d29ya3MsIGFuZCBkZW1vbnN0cmF0ZSB5b3VyIHByb2ZpY2llbmN5IHdpdGggYmFzaWMgbmV0d29yayBkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzLg0KDQojIyBMb2FkaW5nIGFuZCBJbnN0YWxsaW5nIFBhY2thZ2VzLCBTZXQgV29ya2luZyBEaXJlY3RvcnkNCg0KV2hlbiB3b3JraW5nIHdpdGggUiwgeW91IHNob3VsZCBydW4gZWFjaCBsaW5lIG9mIGNvZGUgaW5kaXZpZHVhbGx5LCB1bmxlc3MgaXQgaXMgcGFydCBvZiBhIGZ1bmN0aW9uIGRlZmluaXRpb24sIHNvIHlvdSBjYW4gc2VlIHRoZSByZXN1bHRzLiBHZW5lcmFsbHkgc3BlYWtpbmcsIGFueSBsaW5lIG9mIGNvZGUgdGhhdCBpbmNsdWRlcyAneycgKHRoZSBiZWdpbm5pbmcgb2YgYSBmdW5jdGlvbiBkZWZpbml0aW9uKSBzaG91bGQgYmUgcnVuIHdpdGggYWxsIHRoZSBvdGhlciBsaW5lcyB1bnRpbCB5b3UgaGl0ICd9Jy4NCg0KYGBge3J9DQojIExpbmVzIHRoYXQgc3RhcnQgd2l0aCBhIGhhc2h0YWcvcG91bmQgc3ltYm9sLCBsaWtlIHRoaXMgb25lLCBhcmUgY29tbWVudCBsaW5lcy4gQ29tbWVudCBsaW5lcyBhcmUgaWdub3JlZCBieSBSIHdoZW4gaXQgaXMgaW50ZXJwcmV0aW5nIGNvZGUuDQojIFlvdSBvbmx5IG5lZWQgdG8gaW5zdGFsbCBwYWNrYWdlcyBvbmNlLiBSZW1vdmUgdGhlICMgaW4gZnJvbnQgb2YgZWFjaCBsaW5lIGFuZCB0aGVuIHJ1biBpdCB0byBpbnN0YWxsIGVhY2ggcGFja2FnZS4gQWZ0ZXIgc3VjY2Vzc2Z1bCBpbnN0YWxsYXRpb24sIGRlbGV0ZSB0aGUgbGluZSBvZiBjb2RlIG9yIHJlcGxhY2UgdGhlICNzIHNvIHRoZSBSIE5vdGVib29rIGRvZXNuJ3QgcnVuIGludG8gcHJvYmxlbXMuDQojIGluc3RhbGwucGFja2FnZXMoJ21hZ3JpdHRyJywgcmVwb3MgPSAiaHR0cHM6Ly9jcmFuLnJzdHVkaW8uY29tIikNCiMgaW5zdGFsbC5wYWNrYWdlcygnaWdyYXBoJywgcmVwb3MgPSAiaHR0cHM6Ly9jcmFuLnJzdHVkaW8uY29tIikNCiMgaW5zdGFsbC5wYWNrYWdlcygnaHR0cicsIHJlcG9zID0gImh0dHBzOi8vY3Jhbi5yc3R1ZGlvLmNvbSIpDQojIGluc3RhbGwucGFja2FnZXMoJ2RhdGEudGFibGUnLCByZXBvcyA9ICJodHRwczovL2NyYW4ucnN0dWRpby5jb20iKQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCdkcGx5cicsIHJlcG9zID0gImh0dHBzOi8vY3Jhbi5yc3R1ZGlvLmNvbSIpDQojIGluc3RhbGwucGFja2FnZXMoJ3htbDInLCByZXBvcyA9ICJodHRwczovL2NyYW4ucnN0dWRpby5jb20iKQ0KIyBZb3UgbmVlZCB0byBsb2FkIHBhY2thZ2VzIGV2ZXJ5IHRpbWUgeW91IHJ1biB0aGUgc2NyaXB0IG9yIHJlc3RhcnQgUi4NCmxpYnJhcnkobWFncml0dHIpDQpsaWJyYXJ5KGh0dHIpDQpsaWJyYXJ5KGRhdGEudGFibGUpDQpsaWJyYXJ5KGlncmFwaCkNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHhtbDIpDQojIFNldCB5b3VyIGRpcmVjdG9yeSBmb3IgdGhlIHByb2plY3QNCiMgWW91IGNhbiBlaXRoZXIgZW50ZXIgeW91ciBmaWxlbmFtZSBwYXRoIHdpdGhpbiB0aGUgcGFyZW50aGVzZXMgYmVsb3cgYW5kIHJlbW92ZSB0aGUgIyBjcmVhdGluZyB0aGUgY29tbWVudCwgb3Igc2VsZWN0ICJTZXNzaW9uID4gU2V0IFdvcmtpbmcgRGlyZWN0b3J5IC4uLiBTb3VyY2UgRmlsZSBMb2NhdGlvbiIgaW4gUiBTdHVkaW8uDQojIHNldHdkKCJJbnB1dCBEaXJlY3RvcnkiKQ0KYGBgDQoNCiMjIENob29zZSBhIHRvcGljIGZvciB5b3VyIHNlYXJjaCB0ZXJtcw0KDQpZb3UgY2FuIGRlY2lkZSBzZWFyY2ggdGVybXMgYmFzZWQgb24gcGVyc29uYWwgaW50ZXJlc3RzLCByZXNlYXJjaCBpbnRlcmVzdHMsIG9yIHBvcHVsYXIgdG9waWNhbCBhcmVhcywgYW1vbmcgb3RoZXJzLiBZb3UgaGF2ZSBmbGV4aWJpbGl0eSBpbiBzZWxlY3RpbmcgeW91ciBzZWFyY2ggdGVybSBsaXN0LiBGb3IgZXhhbXBsZSwgeW91IGNhbiBzZWFyY2ggZm9yIHNvbWUgY29tbWVyY2lhbCBicmFuZHMsIGNlbGVicml0aWVzLCBjb3VudHJpZXMsIHVuaXZlcnNpdGllcywgZXRjLiBJdCB3aWxsIGJlIG1vc3QgdXNlZnVsIGlmIHlvdSBjaG9vc2UgYSBjb2xsZWN0aW9uIG9mIHdvcmRzIHRoYXQgYXJlIG5vdCBhbGwgZXh0cmVtZWx5IGNvbW1vbi4gVGhpbmsgYWJvdXQgYSBzZXQgb2Ygd29yZHMgdGhhdCBtaWdodCBoYXZlIGludGVyZXN0aW5nIGNvLW9jY3VycmVuY2VzIGluIGFydGljbGVzIHdpdGhpbiB0aGUgKk5ldyBZb3JrIFRpbWVzKiB3ZWJzaXRlLiBGb3IgZXhhbXBsZSwgeW91IG1pZ2h0IGJlIGludGVyZXN0ZWQgaW4gdGhlIGxhc3QgbmFtZXMgb2YgZXZlcnkgU2VuYXRvciBpbnZvbHZlZCBpbiBhIGNlcnRhaW4gcG9saXRpY2FsIGRlYmF0ZSwgZm9vdGJhbGwgdGVhbXMsIG9yIGNpdGllcyBhbmQgdGhlaXIgY28tb2NjdXJyZW5jZSBpbiBuZXdzIGFydGljbGVzLiBHZW5lcmFsbHkgc3BlYWtpbmcsIHByb3BlciBub3VucyBhcmUgYmVzdCwgYnV0IHlvdSBtaWdodCBoYXZlIGNvbXBlbGxpbmcgcmVhc29ucyB0byBjaG9vc2UgdmVyYnMgb3IgYWRqZWN0aXZlcy4gWW91IG1pZ2h0IHdhbnQgdG8gdGhyb3cgYSBjb3VwbGUgb2YgdGVybXMgaW4gdGhhdCBhcmVuJ3QgdGhlbWF0aWNhbGx5IHJlbGF0ZWQgdG8gbWFrZSBzdXJlIHlvdSBkb24ndCBnZXQgYSB0b3RhbGx5IGNvbm5lY3RlZCBjb21wb25lbnQuIFRoZSBtb3JlIGludGVyZXN0aW5nIHlvdXIgbmV0d29yayBpcyBpbiB0ZXJtcyBvZiBkaWZmZXJpbmcgY2VudHJhbGl0eSwgZGlzdGluY3QgY29tcG9uZW50cywgZXRjLiwgdGhlIGVhc2llciBpdCB3aWxsIGJlIHRvIGRvIHRoZSB3cml0dGVuIGFuYWx5c2lzLiBLZWVwIGluIG1pbmQgdGhhdCB0aGUgQXJ0aWNsZSBTZWFyY2ggYXJjaGl2ZSBpcyB2ZXJ5IGxhcmdlOyBtYW55IHRlcm1zIGNvLW9jY3VyLiBZb3UgbWlnaHQgd2FudCB0byBjb25zaWRlciB0d28gdGVudW91c2x5IHJlbGF0ZWQgc3ViamVjdHMuIFRoZSBleGFtcGxlIGZpbGUgdXNlcyBmb3VyIGZvb3RiYWxsIHRlYW1zIGFuZCB0aGVpciBob21lIHNlbmF0b3JzLCBwbHVzIGEgZmV3IHRvcGljYWwgdGVybXMuDQoNCiMjIENyZWF0ZSB5b3VyIHRleHQgaW5wdXQNCg0KQ3JlYXRlIGEgcGxhaW4gdGV4dCBmaWxlIHdpdGggLnR4dCBleHRlbnNpb24gaW4gdGhlIHNhbWUgZGlyZWN0b3J5IGFzIHRoZSBSIE1hcmtkb3duIE5vdGVib29rIHVzZWQgaW4gdGhpcyBhc3NpZ25tZW50LiBNYWtlIGEgbm90ZSBvZiB0aGUgZmlsZSBuYW1lIGZvciB1c2UgaW4gdGhlIG5leHQgY29kZSBzbmlwcGV0LiBQbGFjZSBvbmUgc2VhcmNoIHRlcm0gcGVyIGxpbmUsIGFuZCB1c2UgMTXigJMyMCB0ZXJtcy4gIFlvdSdsbCBhbHNvIGxpa2VseSB3YW50IHRvIGFkZCBxdW90YXRpb24gbWFya3MgYXJvdW5kIHlvdXIgc2VhcmNoIHRlcm1zIHRvIGVuc3VyZSB0aGF0IHlvdSdyZSBvbmx5IHJlY2VpdmluZyByZXN1bHRzIGZvciB0aGUgY29tcGxldGUgdGVybS4gTk9URTogVGhlIGZ1bmN0aW9uIHdpbGwgcHJvY2VzcyB5b3VyIHRlcm1zIHNvIHRoYXQgdGhleSB3b3JrIGluIHRoZSBVUkwgcmVxdWVzdC4gWW91IGRvIG5vdCBuZWVkIHRvIGVuY29kZSBub24tYWxwaGFiZXRpYyBjaGFyYWN0ZXJzLg0KDQpUaGUgdGV4dCBmaWxlIGNhbm5vdCBpbmNsdWRlIGFueSBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9yIGNoYXJhY3RlcnMgYW5kIGl0IG11c3QgYmUgYSAudHh0IGZpbGU7IFdvcmQgb3IgUlRGIGRvY3VtZW50cyB3b27igJl0IHdvcmsuDQoNCiMjIEFuYWx5c2lzDQoNCioqYS4JUHJvdmlkZSBhIGhpZ2ggbGV2ZWwgb3ZlcnZpZXcgb2YgdGhlIHRlcm1zIHlvdSBpbmNsdWRlZCBpbiB0aGUgc2VhcmNoIHF1ZXJ5LioqDQpJbiBteSB3b3JkIGxpc3QgSSBoYXZlIHRoZSBuYW1lcyBvZiBORkwgdGVhbXMsIE5GTCBwbGF5ZXJzIGFuZCBjb21taXNzaW9uZXIuIEFsc28sIHRoZXJlIGFyZSBuYW1lcyBvZiBzb21lIHNlbmF0b3JzIG9mIHRoZSB1bml0ZWQgc3RhdGVzIGFuZCBwcmVzaWRlbnQgVHJ1bXAgd2hvIGFyZSBwb2xpdGljaWFucyBpbiBnZW5lcmFsLiBBbG1vc3QgYWxsIG9mIHRoZXNlIHBvbGl0aWNpYW5zIGFyZSByZXB1YmxpY2FucyBleGNlcHQgQmlsbCBOZWxzb24gYW5kIHByZXNpZGVudCBUcnVtcCB3aG8gYXJlIGRlbW9jcmF0cy4gDQoNCioqYi4JV2h5IGRpZCB5b3UgY2hvb3NlIHRoaXMgY29sbGVjdGlvbiBvZiB0ZXJtcz8gIFdlcmUgdGhlcmUgc29tZSBzcGVjaWZpYyBvdmVyYXJjaGluZyBxdWVzdGlvbuKAlGludGVsbGVjdHVhbCBvciBleHRyYWN1cnJpY3VsYXIgY3VyaW9zaXR54oCUdGhhdCBtb3RpdmF0ZWQgdGhpcyBjb2xsZWN0aW9uIG9mIHRlcm1zPyoqDQpJIGhhdmUgY2hvc2VuIHRoaXMgd29yZCBsaXN0IGJlY2F1c2UgSSB3YXMgaW50ZXJlc3RlZCB0byBzZWUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRpZmZlcmVudCBORkwgdGVhbXMgYW5kIHRoZWlyIHBsYXllcnMuIFRoZSBjb25uZWN0aW9ucyBvZiB0aGUgcG9saXRpY2lhbnMgd2l0aCBlYWNoIG90aGVyLiBBbHNvLCBJdCB3YXMgaW50ZXJlc3RpbmcgdG8gc2VlIGlmIHRoZXJlIGlzIGEgdGllIGJldHdlZW4gcG9saXRpY2lhbnMgYW5kIHRoZSBORkwgdGVhbXMgYW5kIHRoZWlyIHBsYXllcnMuIE9uIHRoZSBvdGhlciBoYW5kLCBpdCBpcyBleHBlY3RlZCB0aGF0IHByZXNpZGVudCBUcnVtcCBoYXZlIGNvbm5lY3Rpb25zIHdpdGggYm90aCBwb2xpdGljaWFucywgTkZMIHRlYW1zIGFuZCBwbGF5ZXJzLg0KKipjLglIb3cgZGlkIHlvdSBkZWNpZGUgd2hpY2ggdGVybXMgdG8gdXNlIGluIHRoZSBzZWFyY2ggcXVlcnk/IFdlcmUgdGhlc2UgdGVybXMgeW91IGludHVpdGl2ZWx5IGRlZW1lZCBpbXBvcnRhbnQ/IFdlcmUgdGhleSBjdWxsZWQgZnJvbSBhIHNwZWNpZmljIHNvdXJjZSBvciB0aGUgcmVzdWx0IG9mIHNvbWUgc2VwYXJhdGUgYW5hbHlzaXMgb3Igc2VhcmNoIHF1ZXJ5PyoqDQpUaGlzIGxpc3Qgb2Ygd29yZHMgd2FzIGdpdmVuIGluIHRoZSBsYWIuIFNpbmNlIEkgbWFpbmx5IHdhbnRlZCB0byB1bmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gcG9saXRpY2lhbnMgYW5kIE5GTCB0ZWFtcywgSSBzZWFyY2hlZCB0aGUgbmFtZXMgb2Ygc29tZSBmYW1vdXMgc2VuYXRvcnMgYW5kIHRoZSBuYW1lcyBvZiB0aGUgTkZMIHRlYW1zIGFuZCB0aGVpciBwbGF5ZXJzLg0KKipkLglXaGF0IGFyZSB0aGUgaW5zaWdodHMgeW91IGhvcGUgdG8gZ2xlYW4gYnkgbG9va2luZyBhdCB0aGUgbmV0d29yayBvZiB0ZXJtcyBpbiB0ZXJtcyBvZiBpbmRpdmlkdWFsIG5vZGUgbWV0cmljcywgc3ViLWdyb3VwaW5nIG9mIG5vZGVzLCBvdmVyYWxsIGdsb2JhbCBuZXR3b3JrIHByb3BlcnRpZXM/KioNCkkgYW0gY3VyaW91cyB0byBzZWUgdGhhdCBpZiBhbnkgb2YgbXkgZXhwZWN0YXRpb25zIGZyb20gdGhlIG5ldHdvcmsgaXMgdHJ1ZS4gRm9yIGV4YW1wbGUsIEkgaG9wZSB0byBzZWUgYSBjbG9zZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gcG9saXRpY2lhbnMgdGhlbXNlbHZlcywgZXNwZWNpYWxseSB0aGUgb25lcyB3aG8gYXJlIHJlcHVibGljYW5zIG9yIGRlbW9jcmF0cy4gQWxzbywgSSB3YW50IHRvIHNlZSB0aGF0IGlmIHRoZXJlIGFyZSBhbnkgY29ubmVjdGlvbnMgYmV0d2VlbiBwb2xpdGljaWFucyBhbmQgdGhlIE5GTCB0ZWFtcyBhbmQgdGhlaXIgcGxheWVycy4gVGhlIGNoYXJpY3RyaXN0aWNzIG9mIHRoZSBuZXR3b3JrIHN1Y2ggYXMgY2VudGVyYWxpdHkgYW5kIGRlbnNpdHkgaXMgaW50cmVzdGluZyB0b28uIEFyZSBwZW9wbGUganVzdCBjb25uZWN0IHdpdGggZWFjaCBvdGhlciBiYXNlZCBvbiB0aGVpciBqb2JzPw0KIyMgV29ya2luZyB3aXRoIHRoZSBBUEkgdG8gQ29sbGVjdCBZb3VyIERhdGENClRoZSAqTmV3IFlvcmsgVGltZXMqIGNvbnRyb2xzIGFjY2VzcyB0byBpdHMgQVBJIGJ5IGFzc2lnbmluZyBlYWNoIHVzZXIgYSBrZXkuIEVhY2gga2V5IGhhcyBhIGxpbWl0ZWQgbnVtYmVyIG9mIGNhbGxzIHRoYXQgY2FuIGJlIG1hZGUgd2l0aGluIGEgY2VydGFpbiB0aW1lIHBlcmlvZC4gWW91IGNhbiByZWFkIG1vcmUgYWJvdXQgdGhlIGxpbWl0YXRpb25zIG9mIHRoZSBBUEkgc3lzdGVtIFtoZXJlXShodHRwOi8vZGV2ZWxvcGVyLm55dGltZXMuY29tL2FydGljbGVfc2VhcmNoX3YyLmpzb24jKS4NCg0KWW91IHdpbGwgbmVlZCB0byBjcmVhdGUgeW91ciBvd24gQVBJIGtleSB0byBjb21wbGV0ZSB0aGlzIGFzc2lnbm1lbnQuIEdvIHRvIHRoZSAqTmV3IFlvcmsgVGltZXMqIFtkZXZlbG9wZXJzIHBhZ2VdKGh0dHBzOi8vZGV2ZWxvcGVyLm55dGltZXMuY29tL3NpZ251cCkgYW5kIHJlcXVlc3QgYSBrZXkuIFlvdSB3aWxsIGNvcHkgdGhhdCBrZXkgKHJlY2VpdmVkIHZpYSBlbWFpbCkgaW50byB0aGUgYXBpIHZhcmlhYmxlIGJlbG93Lg0KDQpgYGB7cn0NCiMgSW1wb3J0IHlvdXIgd29yZCBsaXN0DQpuYW1lX29mX2ZpbGUgPC0gIk5GTC50eHQiICMgQ3JlYXRlcyBhIHZhcmlhYmxlIGNhbGxlZCBuYW1lX29mX2ZpbGUgdGhhdCB5b3Ugc2hvdWxkIHBvcHVsYXRlIHdpdGggdGhlIG5hbWUgb2YgeW91ciB0ZXh0IGZpbGUgYmV0d2VlbiBxdW90YXRpb24gbWFya3MuDQp3b3JkX2xpc3QgPC0gcmVhZC50YWJsZShuYW1lX29mX2ZpbGUsIHNlcCA9ICJcbiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGKSAlPiUgdW5saXN0ICU+JSBhcy52ZWN0b3IgIyBSZWFkcyB0aGUgY29udGVudCBvZiB5b3VyIGZpbGUgaW50byBhIHZhcmlhYmxlLg0KbnVtX3dvcmRzIDwtIGxlbmd0aCh3b3JkX2xpc3QpICMgQ3JlYXRlcyBhIHZhcmlhYmxlIHdpdGggdGhlIG51bWJlciBvZiB3b3JkcyBpbiB5b3VyIGxpc3QuDQp1cmxfYmFzZSA8LSAiaHR0cHM6Ly9hcGkubnl0aW1lcy5jb20vc3ZjL3NlYXJjaC92Mi9hcnRpY2xlc2VhcmNoLmpzb24iDQojIFdoZW4geW91IHJlY2VpdmUgdGhlIGVtYWlsIHdpdGggeW91ciBBUEkga2V5LCBwYXN0ZSBpdCBiZWxvdyBiZXR3ZWVuIHRoZSBxdW90YXRpb24gbWFya3MuDQphcGkgPC0gJzc2ZjA2YzNkMTZjNTQyODBiOTIzM2Q4ZjNkNzZlNGJmJw0KYGBgDQoNCk91ciBmaXJzdCBmdW5jdGlvbiB3aWxsIGdhdGhlciBhbGwgb2YgdGhlIHNlYXJjaCB0ZXJtcyBhbmQgdGhlaXIgbnVtYmVyIG9mIGhpdHMgdG8gYmUgcGxhY2VkIGluIGEgdGFibGUuIEFsbCBsaW5lcyBvZiBhIGZ1bmN0aW9uIHNob3VsZCBiZSBydW4gdG9nZXRoZXIuDQoNCmBgYHtyfQ0KR2V0X2hpdHNfb25lIDwtIGZ1bmN0aW9uKGtleXdvcmQxKSB7DQogIFN5cy5zbGVlcCh0aW1lPTMpDQogIHVybCA8LSBwYXN0ZTAodXJsX2Jhc2UsICI/YXBpLWtleT0iLCBhcGksICImcT0iLCBVUkxlbmNvZGUoa2V5d29yZDEpLCImYmVnaW5fZGF0ZT0iLCIyMDE2MDEwMSIpICMgQmVnaW4gZGF0ZSBpcyBpbiBmb3JtYXQgWVlZWU1NREQ7IHlvdSBjYW4gY2hhbmdlIGl0IGlmIHlvdSB3YW50IG9ubHkgbW9yZSByZWNlbnQgcmVzdWx0cywgZm9yIGV4YW1wbGUuDQogICMgVGhlIG51bWJlciBvZiByZXN1bHRzDQogIHByaW50KGtleXdvcmQxKQ0KICBoaXRzIDwtIGNvbnRlbnQoR0VUKHVybCkpJHJlc3BvbnNlJG1ldGEkaGl0cyAlPiUgYXMubnVtZXJpYw0KICBwcmludChoaXRzKQ0KICAjIFB1dCByZXN1bHRzIGluIHRhYmxlDQogIGMoU2VhcmNoVGVybT1rZXl3b3JkMSxSZXN1bHRzVG90YWw9aGl0cykNCn0NCmBgYA0KDQpOb3cgd2Ugd2lsbCBpbnZva2Ugb3VyIGZ1bmN0aW9uIHRvIHB1dCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBBUEkgaW50byBvdXIgZ2xvYmFsIGVudmlyb25tZW50Lg0KDQpgYGB7cn0NCiNDcmVhdGUgYSB0YWJsZSBvZiB5b3VyIHdvcmRzIGFuZCB0aGVpciBudW1iZXIgb2YgcmVzdWx0cy4NCnRvdGFsX3RhYmxlIDwtIHQoc2FwcGx5KHdvcmRfbGlzdCxHZXRfaGl0c19vbmUpKQ0KdG90YWxfdGFibGUgPC0gYXMuZGF0YS5mcmFtZSh0b3RhbF90YWJsZSkNCnRvdGFsX3RhYmxlJFJlc3VsdHNUb3RhbCA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3Rlcih0b3RhbF90YWJsZSRSZXN1bHRzVG90YWwpKQ0KYGBgDQpJZiB5b3UgZ2V0IHplcm8gaGl0cyBmb3IgYW55IG9mIHRoZXNlIHRlcm1zLCB5b3Ugc2hvdWxkIHN1YnN0aXR1dGUgdGhhdCB0ZXJtIGZvciBzb21ldGhpZ24gZWxzZSBhbmQgcmVydW4gdGhlIGxhYiB1cCB0byB0aGlzIHBvaW50Lg0KTmV4dCwgd2Ugd2lsbCBkZWZpbmUgdGhlIGZ1bmN0aW9uIHRoYXQgd2lsbCBjb2xsZWN0IHRoZSBhcnRpY2xlIGNvLW9jY3VyZW5jZXMgbmV0d29yay4NCmBgYHtyfQ0KR2V0X2hpdHNfdHdvIDwtIGZ1bmN0aW9uKHJvd19pbnB1dCkgew0KICBrZXl3b3JkMSA8LSByb3dfaW5wdXRbMV0NCiAga2V5d29yZDIgPC0gcm93X2lucHV0WzJdDQogIHVybCA8LSBwYXN0ZTAodXJsX2Jhc2UsICI/YXBpLWtleT0iLCBhcGksICImcT0iLCBVUkxlbmNvZGUoa2V5d29yZDEpLCIrIiwgVVJMZW5jb2RlKGtleXdvcmQyKSwiJmJlZ2luX2RhdGU9IiwiMjAxNjAxMDEiKSAjbWF0Y2ggdy8gQmVnaW4gRGF0ZSBpbiBHZXRfaGl0c19vbmUuDQogICMgVGhlIG51bWJlciBvZiByZXN1bHRzDQogIHByaW50KHBhc3RlMChrZXl3b3JkMSwiICIsa2V5d29yZDIpKSANCiAgaGl0cyA8LSBjb250ZW50KEdFVCh1cmwpKSRyZXNwb25zZSRtZXRhJGhpdHMgJT4lIGFzLm51bWVyaWMNCiAgcHJpbnQoaGl0cykNCiAgU3lzLnNsZWVwKHRpbWU9MykNCiAgIyBQdXQgcmVzdWx0cyBpbiB0YWJsZQ0KICBjKFNlYXJjaFRlcm0xPWtleXdvcmQxLFNlYXJjaFRlcm0yPWtleXdvcmQyLENvT2NjdXJyZW5jZXM9aGl0cykNCn0gDQpgYGANCg0KSW4gdGhpcyBuZXh0IHN0ZXAsIHdlIHdpbGwgY2FsbCB0aGUgQVBJIGFuZCBjb2xsZWN0IHRoZSBjby1vY2N1cnJlbmNlIG5ldHdvcmsuIFRoaXMgbWF5IHRha2Ugc29tZSB0aW1lLiBJZiB5b3UgcmVjZWl2ZSAibnVtZXJpYygwKSIgaW4gYW55IG9mIHlvdXIgcmVzcG9zbmVzLCB5b3UndmUgbGlrZWx5IGhpdCB5b3VyIEFQSSBrZXkgbGltaXQgYW5kIHdpbGwgZWl0aGVyIG5lZWQgdG8gd2FpdCBmb3IgdGhlIGNhbGxzIHRvIHJlc2V0ICgyNCBob3Vycykgb3IgcmVxdWVzdCBhIG5ldyBrZXkuIElmIHlvdSByZWNlaXZlIHRoZSBlcnJvciBtZXNzYWdlICIkIG9wZXJhdG9yIGlzIGludmFsaWQgZm9yIGF0b21pYyB2ZWN0b3JzLCIgeW91IGhhdmUgYWxzbyBoaXQgdGhlIEFQSSBjYWxsIGxpbWl0LiBUaGlzIGNvdWxkIGJlIGR1ZSB0byBydW5uaW5nIHRoZSBzY3JpcHQgbXVsdGlwbGUgdGltZXMsIG9yIGR1ZSB0byBoaXR0aW5nIHRvbyBtYW55IHJlc3VsdHMgYmFzZWQgb24gdmVyeSBjb21tb24gc2VhcmNoIHRlcm1zLiBSZXF1ZXN0IGEgbmV3IEFQSSwgc2hvcnRlbiB5b3VyIHdvcmQgbGlzdCwgYW5kIHRyeSBhZ2Fpbi4gRG9uJ3QgZm9yZ2V0IHlvdSBuZWVkIHRvIHJlbG9hZCB5b3VyIHdvcmQgbGlzdCBmcm9tIHRoZSBmaXJzdCBwYXJ0IG9mIHRoZSBMYWIgaW4gb3JkZXIgdG8gZ2V0IGEgZGlmZmVyZW50IHNldCBvZiByZXN1bHRzISBZb3UgbXVzdCBhbHNvIHJlcnVuIHRoZSBmdW5jdGlvbnMgdG8gcmVhc3NpZ24gdGhlIEFQSSB2YWx1ZS4gSWYgbm9uZSBvZiB5b3VyIHJlc3VsdHMgY29tZSBiYWNrIGFzICIwLCIgeW91IG1pZ2h0IHdhbnQgdG8gcmVkbyB5b3VyIHNlYXJjaCB3aXRoIHRoZSBhcHByb3ByaWF0ZSB3b3Jkcy4NCg0KYGBge3J9DQojIENvbnZlcnQgdGhlIHBhaXJzIGxpc3QgaW50byBhIHRhYmxlDQpwYWlyc19saXN0IDwtIGV4cGFuZC5ncmlkKHdvcmRfbGlzdCx3b3JkX2xpc3QpICU+JSBmaWx0ZXIoVmFyMSAhPSBWYXIyKQ0KcGFpcnNfbGlzdCA8LSB0KGNvbWJuKHdvcmRfbGlzdCwyKSkNCiNDcmVhdGUgYSBuZXR3b3JrIHRhYmxlLCBydW4gdGhlIEdldF9oaXRzX3R3byBmdW5jdGlvbiB1c2luZyB0aGUgcGFpcnMgbGlzdHMNCm5ldHdvcmtfdGFibGUgPC0gdChhcHBseShwYWlyc19saXN0LDEsR2V0X2hpdHNfdHdvKSkNCiNDb252ZXJ0IHRoZSBuZXR3b3JrIHRhYmxlIGludG8gYSBkYXRhZnJhbWUNCm5ldHdvcmtfdGFibGUgPC0gYXMuZGF0YS5mcmFtZShuZXR3b3JrX3RhYmxlKQ0KIyBSZWFkIGVhY2ggdGhlIGNvbnRlbnQgb2YgZWFjaCBpdGVtIHdpdGhpbiB0aGUgJENvT2NjdXJyZWVuY2VzIGZhY3RvciBhcyBjaGFyYWN0ZXJzLCANCiMgdGhlbiBmb3JjZSB0aG9zZSBjaGFyYWN0ZXJzIGludG8gdGhlICJudW1lcmljIiBvciAiZG91YmxlIiB0eXBlLg0KbmV0d29ya190YWJsZSRDb09jY3VycmVuY2VzIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG5ldHdvcmtfdGFibGUkQ29PY2N1cnJlbmNlcykpDQojIENvbnZlcnQgZGF0YSB0byBkYXRhLnRhYmxlIHR5cGUuDQp0b3RhbF90YWJsZSA8LSBhcy5kYXRhLnRhYmxlKHRvdGFsX3RhYmxlKQ0KbmV0d29ya190YWJsZSA8LSBhcy5kYXRhLnRhYmxlKG5ldHdvcmtfdGFibGUpDQoNCiMgUmVtb3ZlIHplcm8gZWRnZXMgZnJvbSB5b3VyIG5ldHdvcmsNCm5ldHdvcmtfdGFibGUgPC0gbmV0d29ya190YWJsZVshQ29PY2N1cnJlbmNlcz09MF0gDQoNCiMgQ3JlYXRlIGEgZ3JhcGggb2JqZWN0IHdpdGggeW91ciBkYXRhDQpnX3ZhbHVlZCA8LSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoZCA9IG5ldHdvcmtfdGFibGVbLDE6Myx3aXRoPUZBTFNFXSxkaXJlY3RlZCA9IEZBTFNFLHZlcnRpY2VzID0gdG90YWxfdGFibGUpDQoNCiMgSWYgeW91J3JlIGhhdmluZyB0cm91YmxlIHdpdGggZGF0YSBjb2xsZWN0aW9uLCB5b3UgY2FuIGxvYWQgdGhlICdORkwgTGFiIFJlc3VsdHMuUkRhdGEnIGZpbGUgbm93IGJ5IGNsaWNraW5nIHRoZSBvcGVuIGZvbGRlciBpY29uIG9uIHRoZSAiRW52aXJvbm1lbnQiIiB0YWIgYW5kIGNvbnRpbnVlIHRoZSBsYWIgZnJvbSBoZXJlLiBZb3UnbGwgbmVlZCB0byBmaWd1cmUgb3V0IHdoYXQgdGhlIHNpZ25pZmljYW5jZSBvZiB0aGUgdGVybXMgYXJlIHlvdXJzZWxmLCBob3dldmVyLg0KIyBZb3Ugc2hvdWxkIHNhdmUgeW91ciBkYXRhIGF0IHRoaXMgcG9pbnQgYnkgY2xpY2tpbmcgdGhlIGZsb3BweSBkaXNrIGljb24gdW5kZXIgdGhlICJFbnZpcm9ubWVudCIgdGFiLg0KYGBgDQoNCiMjIEFuYWx5c2lzDQoNCioqSXMgdGhlIGdyYXBoIGRpcmVjdGVkIG9yIHVuZGlyZWN0ZWQ/KiogDQpUaGlzIGlzIGFuIHVuZGlyZWN0ZWQgbmV0d29yay4NCioqSG93IG1hbnkgbm9kZXMgYW5kIGxpbmtzIGRvZXMgeW91ciBuZXR3b3JrIGhhdmU/ICoqDQoxNQ0KYGBge3J9DQpudW1WZXJ0aWNlcyA8LSB2Y291bnQoZ192YWx1ZWQpDQpudW1WZXJ0aWNlcw0KbnVtRWRnZXMgPC0gZWNvdW50KGdfdmFsdWVkKQ0KbnVtRWRnZXMNCmBgYA0KDQoqKldoYXQgaXMgdGhlIG51bWJlciBvZiBwb3NzaWJsZSBsaW5rcyBpbiB5b3VyIG5ldHdvcms/ICoqDQoxMDUNCmBgYHtyfQ0KbWF4RWRnZXMgPC0gbnVtVmVydGljZXMqKG51bVZlcnRpY2VzLTEpLzINCm1heEVkZ2VzDQpgYGANCg0KKipXaGF0IGlzIHRoZSBkZW5zaXR5IG9mIHlvdXIgbmV0d29yaz8qKiANClRoZSBkZW5zaXR5IGlzIDAuMzMzMzMzMw0KYGBge3J9DQpncmFwaERlbnNpdHkgPC0gbnVtRWRnZXMvbWF4RWRnZXMgIyBtYW51YWwgY2FsY3VsYXRpb24NCmdyYXBoRGVuc2l0eQ0KZ3JhcGhEZW5zaXR5MSA8LSBncmFwaC5kZW5zaXR5KGdfdmFsdWVkKSAjIHVzaW5nIHRoZSBncmFwaC5kZW5zaXR5IGZ1bmN0aW9uIGZyb20gaWdyYXBoDQpncmFwaERlbnNpdHkxDQpgYGANCg0KKipCcmllZmx5IGRlc2NyaWJlIGhvdyB5b3VyIGNob2ljZSBvZiBkYXRhc2V0IG1heSBpbmZsdWVuY2UgeW91ciBmaW5kaW5ncy4qKiAgDQpPdXIgc2VhcmNoIHJlc3VsdHMgYXJlIGNvbXBsZXRlbHkgZGVwZW5kIG9uIHdoaWNoIHRlcm0gd2UgdXNlLklmIHdlIHVzZSBkaWZmZXJlbnQgc2VhcmNoIHRlcm1zLCB3ZSB3b3VsZCBleHBlY3QgY29tcGxldGVseSBkaWZmZXJlbnQgZ3JhcGggc3RydWN0dXJlcy4gRm9yIGV4YW1wbGUsIGlmIHdlIHVzZSAiU2VuLiBCaWxsIENhc3NpZHkiIHRoZSBzZWFyY2ggcmVzdWx0IHdvdWxkIGluY2x1ZGUgdGhlIGFydGljbGVzIHRoYXQgaGF2ZSB0aGlzIGV4YWN0IHdvcmRzIChTZW4uIEJpbGwgQ2Fzc2lkeSkgYW5kIGl0IHdvdWxkIHNraXAgdGhlIGFydGljbGVzIHRoYXQgaGF2ZSBqdXN0IG1lbnRpb25lZCB0aGlzIHNlbmF0b3IgYXMgIkJpbGwgQ2Fzc2lkeSIuIEFzIGEgcmVzdWx0IHdlIGNhbiBjb25jbHVkZSB0aGF0IHNlYXJjaCB0ZXJtcyBtaWdodCBlbmQgdXAgd2l0aCAgZGlmZmVyZW5jZXMgaW4gbnVtYmVyIG9mIHRoZSBsaW5rcywoYmFzZSBvbiB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHN1Ymdyb3VwcyBvZiBvdXIgdGVybXMpLkFsc28sIHRoZXJlIHdvdWxkIGJlIGRpZmZlcmVuY2VzIGluIGRlc2l0eS4gTW9yZW92ZXIsIHNlbGVjdGluZyBkaWZmZXJudCBzdHlsZSBvZiBhIHNwZWNpZmljIHdvcmQgY291bGQgZWZmZWN0IG91ciByZXN1bHQuIEZvciBleGFtcGxlLCBjaG9vc2luZyAiQ2Fyb2xpbmEiIiBvdmVyICJDYXJvbGluYSBQYW50aGVycyIiIHdvdWxkIGdpdmUgdXMgcmVkdW5kYW50IGluZm9ybWF0aW9uIGFib3V0IHRoZSBjaXR5IGFuZCBpdCdzIHJlbGF0aW9uc2hpcCB0byB0aGUgb3RoZXIgbm9kZXMuDQojIFBhcnQgMjogVmlzdWFsaXplIFlvdXIgTmV0d29yayAoMjAgcG9pbnRzKQ0KDQpMZXQncyBzdGFydCBieSB2aXN1YWxpemluZyB0aGUgbmV0d29yayB0aGF0IHdlJ3ZlIGNvbGxlY3RlZCBmcm9tIHRoZSAqTmV3IFlvcmsgVGltZXMqIEFydGljbGUgU2VhcmNoIEFQSS4gV2UnbGwgbmVlZCB0byBjaG9vc2Ugbm9kZSBjb2xvcnMgYW5kIHNldCBhIGxheW91dC4gWW91IGNhbiBsZWFybiBtb3JlIGFib3V0IEZydWNodGVybWFuIFJlaW5nb2xkIGxheW91dCBhbmQgb3RoZXIgbGF5b3V0cyBbaGVyZV0oaHR0cDovL2lncmFwaC5vcmcvci9kb2MvbGF5b3V0X3dpdGhfZnIuaHRtbCkuDQoNCmBgYHtyfQ0KIyMgTGVhcm4gbW9yZSBhYm91dCBwbG90dGluZyB3aXRoIGlncmFwaA0KPz8gaWdyYXBoLnBsb3R0aW5nDQpjb2xiYXIgPSByYWluYm93KGxlbmd0aCh3b3JkX2xpc3QpKSAjIyB3ZSBhcmUgc2VsZWN0aW5nIGRpZmZlcmVudCBjb2xvcnMgdG8gY29ycmVzcG9uZCB0byBlYWNoIHdvcmQNClYoZ192YWx1ZWQpJGNvbG9yID0gY29sYmFyDQojIFNldCBsYXlvdXQgaGVyZSANCkwgPSBsYXlvdXRfd2l0aF9mcihnX3ZhbHVlZCkgICMgRnJ1Y2h0ZXJtYW4gUmVpbmdvbGQNCnBsb3QoZ192YWx1ZWQsdmVydGV4LmNvbG9yPVYoZ192YWx1ZWQpJGNvbG9yLCBsYXlvdXQgPSBMLCB2ZXJ0ZXguc2l6ZT02KSANCg0KYGBgDQojIyBBbmFseXNpcw0KKipJbiBhIHBhcmFncmFwaCwgZGVzY3JpYmUgdGhlIG1hY3JvLWxldmVsIHN0cnVjdHVyZSBvZiB5b3VyIGdyYXBocyBiYXNlZCBvbiB0aGUgRnJ1Y2h0ZXJtYW4gUmVpbmdvbGQgdmlzdWFsaXphdGlvbi4qKg0KSXQgaXMgYSBnaWFudCBjb25uZWN0ZWQgY29tcG9uZW50IGFuZCB0aGVyZSBhcmUgc2V2ZXJhbCBzdWItY29tcG9uZW50cyAoc3ViZ3JvdXBzKSBpbiB0aGUgZ3JhcGguIFRoZXJlIGlzIG5vIGlzb2xhdGVkIGNvbXBvbmVudC4gQXMgZXhwZWN0ZWQsIHdlIGNhbiBzZWUgdGhhdCBiYXNlZCBvbiB0aGVpciBqb2JzLCBhbGwgc2VuYXRvcnMgYXJlIGNvbm5lY3RlZCB0byBlYWNoIG90aGVyLiBBbHNvLCB0aGVyZSBpcyBhIHRpZSBiZXR3ZWVuIHJlcHVibGljYW5zIGFuZCBkZW1vY3JhdHMuIEFsbCBvZiB0aGUgc3ViLWNvbXBvbmVudHMgYXJlIGNvbm5lY3RlZCB3aXRoIGVhY2ggb3RoZXIgYnkgbGlhaXNvbiBub2RlIHRydW1wLiBJbiB0aGUgb3RoZXIgaGFuZCB3ZSBjYW4gc2VlIHRoYXQgUHJlc2lkZW50IFRydW1wIGhhdmUgcmVsYXRpb25zaGlwIHdpdGggYm90aCBORkwgdGVhbXMgYW5kIHNlbmF0b3JzLiBUaGUgc3ViZ3JvdXAgb2YgdGhlIE5GTCB0ZWFtcyBzZWVtIHRvIGJlIG1vcmUgY29ubmVjdGVkIHRoYW4gdGhlIHN1Ymdyb3VwIG9mIHRoZSBwb2xpdGljaWFucy4gT25lIG9mIHRoZSByZWFzb25zIGNvdWxkIGJlIGJlY2F1c2Ugd2UgaGF2ZSB1c2VkICJTZW4iIGJlZm9yZSB0aGUgbmFtZXMgb2YgdGhlIHNlbmF0b3JzLCB3ZSBtaWdodCBoYXZlIHNraXBlZCBzb21lIG9mIHRoZSBsaW5rcyBiZXR3ZWVuIHNlbmF0b3JzLg0KDQpOb3cgd2UnbGwgY3JlYXRlIGEgc2Vjb25kIHZpc3VhbGl6YXRpb24gdXNpbmcgYSBkaWZmZXJlbnQgbGF5b3V0Lg0KYGBge3J9DQojIyBZb3UgY2FuIGNoYW5nZSB0aGUgbGF5b3V0IGJ5IHBpY2tpbmcgb25lIG9mIHRoZSBvdGhlciBvcHRpb25zLiBVbmNvbW1lbnQgb25lIG9mIHRoZSBsaW5lcyBiZWxvdyBieSBlcmFzaW5nIHRoZSAjIGFuZCBydW5uaW5nIHRoZSBsaW5lLiBUcnkgdG8gZmluZCBhIGxheW91dCB0aGF0IGdpdmVzIHlvdSBkaWZmZXJlbnQgaW5mb3JtYXRpb24gdGhhdCBGcnVjaHRlcm1hbiBSZWluZ29sZC4NCg0KIEwgPSBsYXlvdXRfd2l0aF9kaChnX3ZhbHVlZCkgIyMgRGF2aWRzb24gYW5kIEhhcmVsDQoNCiMgTCA9IGxheW91dF93aXRoX2RybChnX3ZhbHVlZCkgIyMgRm9yY2UtZGlyZWN0ZWQNCg0KIyBMID0gbGF5b3V0X3dpdGhfa2soZ192YWx1ZWQpICMjIFNwcmluZw0KcGxvdChnX3ZhbHVlZCx2ZXJ0ZXguY29sb3I9VihnX3ZhbHVlZCkkY29sb3IsIGxheW91dCA9IEwsIHZlcnRleC5zaXplPTYpIA0KYGBgDQojIyBBbmFseXNpcw0KDQoqKkluIGEgcGFyYWdyYXBoLCBjb21wYXJlIGFuZCBjb250cmFzdCB0aGUgaW5mb3JtYXRpb24gZ2l2ZW4gdG8geW91IGJ5IHRoZSB0d28gZGlmZmVyZW50IGxheW91dHMuKioNClVzaW5nIGRpZmZlcmVudCBsYXlvdXRzIGFuZCBjb21wYXJlIHRoZW0gd2l0aCBlYWNoIG90aGVyIGhlbHAgdXMgdG8gZmluZCB3aGV0aGVyIGlmIGFueSBvZiB0aGUgaW5mb3JtYXRpb24gaGF2ZSBiZWVuIG1pc3NlZCBpbiBvbmUgbGF5b3V0IG9yIG5vdC4gRm9yIGluc3RhbmNlLCBpbiB0aGUgRnJ1Y2h0ZXJtYW4gUmVpbmdvbGQgbGF5b3V0IHdlIGNhbm5vdCBzZWUgdGhlIHJlbGF0aW9uIGJldHdlZW4gVHJ1bXAgYW5kIE5lbHNvbiBvciBUcnVtcCBhbmQgc29tZSBORkwgdGVhbXMuIFNvLCB3ZSBtaWdodCB0aGluayB0aGF0IHRoZXJlIGlzIG5vIGNvbm5lY3Rpb24gYmV0d2VlbiB0aGVtLiBCdXQsIGluIHRoZSBEYXZpZHNvbiBhbmQgSGFyZWwgbGF5b3V0IFRydW1wIGhhdmUgY29ubmVjdGlvbnMgd2l0aCBOZWxzb24gYW5kIE5GTCBlYW1zIGxpa2UgIkNhcm9saW5hIFBhbnRoZXJzIiAuIFRoZXJlZm9yZSwgY29tcGFyaW5nIGRpZmZlcmVudCBsYXlvdXRzIHdpdGggZWFjaCBvdGhlciBpcyBjYW4gaGVscCB1cyB0byBiZXR0ZXIgdW5kZXJzdGFuZCB0aGUgbGlua3MgYmV0d2VlbiB0aGUgbm9kZXMgYW5kIGdhaW4gYWxsIHRoZSBwb3NzaWJsZSBpbmZvcm1hdGlvbi4NCiMgUGFydCAzOiBDb21tdW5pdHkgRGV0ZWN0aW9uIEFuYWx5c2lzIHdpdGggUiAoMjAgUG9pbnRzKQ0KDQpJZGVudGlmeWluZyBzdWJncm91cHMgd2l0aGluIGEgbmV0d29yayBpcyBvZiBncmVhdCBpbnRlcmVzdCB0byBzb2NpYWwgbmV0d29yayByZXNlYXJjaGVycywgc28gYSB2YXJpZXR5IG9mIGFsZ29yaXRobXMgaGF2ZSBiZWVuIGRldmVsb3BlZCB0byBpZGVudGlmeSBhbmQgbWVhc3VyZSBzdWJncm91cHMuICBXZSB3aWxsIHVzZSBzb21lIG9mIFLigJlzIGJ1aWx0LWluIHRvb2xzIHRvIGlkZW50aWZ5IHN1Ymdyb3VwcyBhbmQgY2VudHJhbCBub2RlcyBmb3IgdmlzdWFsIGluc3BlY3Rpb24uDQoNCkZvciB0aGUgcmVtYWluZGVyIG9mIHRoZSB2aXN1YWxpemF0aW9ucyB3ZSB3aWxsIHVzZSB0aGUgRnJ1Y2h0ZXJtYW4gUmVpbmdvbGQgbGF5b3V0Lg0KYGBge3J9DQpMID0gbGF5b3V0X3dpdGhfZnIoZ192YWx1ZWQpIA0KYGBgDQoNCkNsdXN0ZXIgdGhlIG5vZGVzIGluIHlvdXIgbmV0d29yay4NCmBgYHtyfQ0KIyBMZWFybiBtb3JlIGFib3V0IHRoZSBjbHVzdGVyaW5nIGFsZ29yaXRobS4NCj8/IGNsdXN0ZXJfd2Fsa3RyYXANCmNsdXN0ZXIgPC0gY2x1c3Rlcl93YWxrdHJhcChnX3ZhbHVlZCkNCiMgRmluZCB0aGUgbnVtYmVyIG9mIGNsdXN0ZXJzDQptZW1iZXJzaGlwKGNsdXN0ZXIpICAgIyBhZmZpbGlhdGlvbiBsaXN0DQpsZW5ndGgoc2l6ZXMoY2x1c3RlcikpICMgbnVtYmVyIG9mIGNsdXN0ZXJzDQojIEZpbmQgdGhlIHNpemUgdGhlIGVhY2ggY2x1c3RlciANCiMgTm90ZSB0aGF0IGNvbW11bml0aWVzIHdpdGggb25lIG5vZGUgYXJlIGlzb2xhdGVzLCBvciBoYXZlIG9ubHkgYSBzaW5nbGUgdGllDQpzaXplcyhjbHVzdGVyKSANCmBgYA0KDQoqKkhvdyBtYW55IGNvbW11bml0aWVzIGhhdmUgYmVlbiBjcmVhdGVkPyoqDQozDQoqKkhvdyBtYW55IG5vZGVzIGFyZSBpbiBlYWNoIGNvbW11bml0eT8qKg0KZmlyc3QgY29tbXVuaXR5IGhhdmUgMiBub2Rlcywgc2Vjb25kIGNvbW11bml0eSBoYXZlIDcgbm9kZXMgYW5kIHRoZSBsYXN0IG9uZSBoYXMgNiBub2Rlcy4NCg0KKipGb3IgeW91ciBuZXR3b3JrLCB3aGF0IG1pZ2h0IGVhY2ggY2x1c3RlciBvZiBub2RlcyBwb3RlbnRpYWxseSBoYXZlIGluIGNvbW1vbj8gRGVzY3JpYmUgZWFjaCBjbHVzdGVyLCBpdHMgbWVtYmVyc2hpcCwgYW5kIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBub2RlcyBpbiB0aGUgY2x1c3Rlci4qKg0KRmlyc3QsIHRoZSBjb21tdW5pdHkgd2l0aCA2IG5vZGVzIGlzIGFsbCBORkwgdGVhbXMuIHRoZXkgYXJlIGVhY2ggb3RoZXJzIHJpdmFsIGluIGZvb3RiYWxsIGxlYWd1ZSwgVGhleSB0cmFkZSB0aGVpciBwbGF5ZXJzIGFuZCBjb2FjaGVzIHdpdGggZWFjaCBvdGhlciwgZXRjLiBTZWNvbmQsIHRoZSBjb21tdW5pdHkgd2l0aCA3IG5vZGVzIGNvbnNpc3RzIG9mIERvbmFsZCBUcnVtcCwgU3RldmUgU2NhbGlzZSwgU2VuLkJpbGwgTmVsc29uLCBTZW4uIE1hcmNvIFJ1YmlvLCBTZW4uIExpbmRzZXkgR3JhaGFtLCBTZW4uIERhdmlkIFBlcmR1ZSwgYW5kIFNlbi5Kb2hub3kgSXNha3Nvbi4gVGhleSBhcmUgYWxsIHBvbGl0aWNpYW4sIHRoZXkgYWxsIHdvcmsgaW4gY29uZ3Jlc3MuIFRoaXJkLCB0aGUgY29tbXVuaXR5IHdpdGggMiBub2RlcyBpcyBpbmNsdWRlIG9mIEJpbGwgY2Fzc2lkeSBhbmQgVGltIFNjb3R0IHdobyBhcmUgYm90aCByZXB1YmxpY2FucyBhbmQgdGhleSBib3RoIGhhdmUgam9pbmVkIHRoZSBjb25ncmVzcyBpbiByZWNlbnQgeWVhcnMuIEFsc28sIHRoZWlyIGNvbm5lY3Rpb24gbWlnaHQgYmUgYmVjYXVzZSBvZiBzZW4uIEJpbGwgQ2Fzc2lkeSdzIGpvYiBhcyBhIHBoeXNpY2lhbiBoZSBoYWQgYSByZWxhdGlvbiB0byBTY290dCBhYm91dCBoZWFsdGggY2FyZS4NCg0KTmV4dCB3ZSB2aXN1YWxpemUgdGhlIGNsdXN0ZXJzIGJ5IGNvbG9yaW5nIG5vZGVzIGFjY29yZGluZyB0byB0aGVpciBtb2R1bGFyaXR5IGNsYXNzLiANCmBgYHtyfQ0KcGxvdChjbHVzdGVyLCBnX3ZhbHVlZCwgY29sID0gVihnX3ZhbHVlZCkkY29sb3IsIGxheW91dCA9IEwsIHZlcnRleC5zaXplPTYpDQpgYGANCg0KKipXaGF0IGluZm9ybWF0aW9uIGRvZXMgdGhpcyBsYXlvdXQgY29udmV5PyAgQXJlIHRoZSBjbHVzdGVycyB3ZWxsLXNlcGFyYXRlZCwgb3IgaXMgdGhlcmUgYSBncmVhdCBkZWFsIG9mIG92ZXJsYXA/IElzIGl0IGVhc2llciB0byBpZGVudGlmeSB0aGUgY29tbW9uIHRoZW1lcyBhbW9uZyBjbHVzdGVycyBpbiB0aGlzIGxheW91dCByYXRoZXIgdGhhbiBsb29raW5nIG9ubHkgYXQgdGhlIGdyYXBocz8qKg0KSXQgc2hvd3MgdGhlIGNvbW1vbiBpbnRlcmVzdCBhbmQgaW50cmFjdGlvbiBiZXR3ZWVuIGVhY2ggbm9kZXMgb2Ygb25lIGNsdXN0ZXIuIFRoZSBjbHVzdGVycyBhcmUgd2VsbC1zZXBhcmF0ZWQgYW5kIHRoZXJlIGFyZSBubyBvdmVybGFwcyBiZXR3ZWVuIHRoZW0uIEl0IGlzIGVhc2llciB0byBpZGVudGlmeSB0aGUgY29tbW9uIHRoZW1lcyBhbW9uZyBjbHVzdGVycyBpbiB0aGlzIGxheW91dCByYXRoZXIgdGhhbiBsb29raW5nIG9ubHkgYXQgdGhlIGdyYXBocyBzaW5jZSB0aGlzIGxheW91dCBkZXRlcm1pbmUgZWFjaCBjbHVzdGVyIHdpdGggZGlmZmVybnQgY29sb3IuDQoNCioqV2hhdCBkaWZmZXJlbmNlcyBhcmUgdGhlcmUgYmV0d2VlbiBub2RlcyBpbiB0aGUgc2FtZSBjbHVzdGVyIGFuZCBhY3Jvc3MgY2x1c3RlcnM/KioNCkluIHRoZSBwb2xpdGljaWFucyBjbHVzdGVyIHdpdGggNyBub2RlcywgdGhlIG51bWJlciBvZiB0aGUgbGlua3Mgb2YgZWFjaCBzZW5hdG9yIHdpdGggdGhlIG90aGVyIG5vZGVzIGRpZmZlcnMgd2l0aCB0aGUgb3RoZXIgc2VuYXRvcnMuIFRoaXMgbWlnaHQgYmUgYmVjYXVzZSBvZiAxLmJlaW5nIHJlcHVibGljYW4gb3IgYSBkZW1vY3JhdCBzZW5hdG9yLCAyLnRoZSByZXNpZGVuY3kgc3RhdGVzIG9mIGVhY2ggb2YgdGhlIHNlbmF0b3JzLCBvciAzLm91ciB1c2Ugb2Ygc2VhcmNoIA0KdGVybSh1c2Ugb2YgU2VuIGJlZm9yZSB0aGUgbmFtZXMgb2YgdGhlIHNlbmF0b3JzKS4NCkluIHRoZSBjbHVzdGVyIG9mIE5GTCB0ZWFtcyBhbGwgb2YgdGhlbSBhcmUgY29ubmVjdGVkIHRvIGVhY2ggb3RoZXIuIEluIHRoaXMgY2x1c3RlciBkaWZmZXJlbmNlcyBjb3VsZCBiZSB0aGUgc3RhdGVzIG9mIHRoZSBORkwgdGVhbXMgYW5kIHRoZWlyIHBsYXllcnMuDQpJbiB0aGUgY2x1c3RlciB3aXRoIDIgbm9kZXMgd2UgaGF2ZSAgQmlsbCBjYXNzaWR5IGFuZCBUaW0gU2NvdHQuIFRpbSBTY290dCBpcyB0aGUgb25seSBub2RlIHdoaWNoIGRvZXMgbm90IGhhdmUgYSBsaW5rIHdpdGggVHJ1bXAgYW5kIGhlIGlzIGp1c3QgaGF2ZSBhIHRpZSB3aXRoIEJpbGwgY2Fzc2lkeS4NCg0KKipEZXNjcmliZSB0aGUgYnJva2VycyBiZXR3ZWVuIGFueSBjb21wb25lbnRzIGFuZCBjbGlxdWVzLiAgV2hhdCBhcmUgY29tbW9uIGZlYXR1cmVzIG9mIHRoZXNlIGJyb2tlcnM/ICBBYm91dCBob3cgbWFueSBicm9rZXJzIHdvdWxkIHlvdSBoYXZlIHRvIHJlbW92ZSBmcm9tIHlvdXIgbmV0d29yayB0byAic2hhdHRlciIgaXQgaW50byB0d28gb3IgbW9yZSBkaXNjb25uZWN0ZWQgY29tcG9uZW50cz8qKg0KVGhlIGJyb2tlcnMgaGVyZSBhcmUgVHJ1bXAgYW5kIENhc3NpZHkgYW5kIHRoZXkgcm9sZSBhcyBhbiBvbmx5IGNvbm5lY3RvciBvZiB0aGUgdHdvIGNsdXN0ZXJzLiBEb25hbGQgVHJ1bXAgaXMgdGhlIGJyb2tlciBiZXR3ZWVuIE5GTCB0ZWFtcyBhbmQgdGhlIHBvbGl0aWNpYW5zIGNsdXN0ZXJzLiBDYXNzaWR5IGlzIGEgYnJva2VyIGJldHdlZW4gdGhlIGNsdXN0ZXIgd2l0aCA3IHBvbGl0aWNpYW5zIGFuZCB0aGUgY2x1c3RlciB3aXRoIENhc3NpZHkgYW5kIFNjb3R0LiBUaGVzZSBicm9rZXJzIGNvbnRyb2wgdGhlIGluZm9ybWF0aW9uIGZsb3cgYmV0d2VlbiBlYWNoIHR3byBjbHVzdGVycyBhbmQgdGhleSBzaG91bGQgaGF2ZSBoaWdoIGNlbnRyYWxpdHkuIElmIHdlIGVsaW1pbmF0ZSBEb25hbGQgVHJ1bXAgZnJvbSB0aGUgbmV0d29yaywgd2UgY2FuIHNoYXR0ZXIgaXQgaW50byB0d28gZGlzY29ubmVjdGVkIGNvbXBvbmVudHMuDQojIFBhcnQgNDogQ2VudHJhbGl0eSBWaXN1YWxpemF0aW9uICYgV2VpZ2h0ZWQgVmFsdWVzICgyMCBQb2ludHMpDQoNCkZvciBlYWNoIG5ldHdvcmssIHlvdSB3aWxsIHVzZSBjZW50cmFsaXR5IG1ldHJpY3MgdG8gaW1wcm92ZSB5b3VyIHZpc3VhbGl6YXRpb24uIFlvdSBtYXkgbmVlZCB0byBhZGp1c3QgdGhlIHNpemUgcGFyYW1ldGVyIHRvIG1ha2UgeW91ciBuZXR3b3JrIG1vcmUgZWFzaWx5IHZpc2libGUuDQoNCiMjIERlZ3JlZSBDZW50cmFsaXR5DQpgYGB7cn0NCnRvdGFsRGVncmVlIDwtIGRlZ3JlZShnX3ZhbHVlZCxtb2RlPSJhbGwiKQ0Kc29ydCh0b3RhbERlZ3JlZSxkZWNyZWFzaW5nPVRSVUUpWzE6NV0NCmcyIDwtIGdfdmFsdWVkDQpWKGcyKSRzaXplIDwtIHRvdGFsRGVncmVlKjIgI2NhbiBhZGp1c3QgdGhlIG51bWJlciBpZiBub2RlcyBhcmUgdG9vIGJpZw0KcGxvdChnMiwgbGF5b3V0ID0gTCwgdmVydGV4LmxhYmVsPU5BKQ0KYGBgDQoqKkJyaWVmbHkgZXhwbGFpbiBkZWdyZWUgY2VudHJhbGl0eSBhbmQgd2h5IG5vZGVzIGFyZSBtb3JlIG9yIGxlc3MgY2VudHJhbCBpbiB0aGUgbmV0d29yay4qKg0KRGVncmVlIGNlbnRyYWxpdHkgaXMgZGVmaW5lZCBieSB0aGUgbnVtYmVyIG9mIHRoZSBsaW5rcyB0aGF0IG9uZSBub2RlIGhhdmUuIFRoZSBtb3JlIGEgbm9kZSBoYXZlIGxpbmtzLCB0aGUgbW9yZSBjZW50cmFsIGl0IGlzLiBJbiB0aGlzIG5ldHdvcmssIHNpbmNlIERvbmFsZCBUcnVtcCBoYXZlIGEgY29ubmVjdGlvbiB3aXRoIGV2ZXJ5IG90aGVyIG5vZGVzIChleGNlcHQgVGltIFNjb3R0KSBpdCBoYXMgdGhlIGhpZ2hlc3QgZGVncmVlIGNlbnRyYWxpdHkgaW4gdGhlIG5ldHdvcmsuIExpa2V3aXNlLCBub2RlcyB3aXRoIGp1c3Qgb25lIGxpbmtzIHN1Y2ggYXMgVGltIFNjb3R0IGhhdmUgdGhlIGxvd2VzdCBkZWdyZWUgY2VudHJhbGl0eSBpbiB0aGlzIG5ldHdvcmsuIA0KDQojIyBXZWlnaHRlZCBEZWdyZWUgQ2VudHJhbGl0eQ0KYGBge3J9DQp3ZCA8LSBncmFwaC5zdHJlbmd0aChnX3ZhbHVlZCx3ZWlnaHRzID0gRShnX3ZhbHVlZCkkQ29PY2N1cnJlbmNlcykNCnNvcnQod2QsZGVjcmVhc2luZz1UUlVFKVsxOjVdDQp3ZzIgPC0gZ192YWx1ZWQNClYod2cyKSRzaXplIDwtIHdkKi4xICMgYWRqdXN0IHRoZSBudW1iZXIgaWYgbm9kZXMgYXJlIHRvbyBiaWcNCnBsb3Qod2cyLCBsYXlvdXQgPSBMLCB2ZXJ0ZXgubGFiZWw9TkEsIGVkZ2Uud2lkdGg9c3FydChFKGdfdmFsdWVkKSRDb09jY3VycmVuY2VzKSkgI3Rha2luZyB0aGUgc3F1YXJlIHJvb3QgaXMgYSBnb29kIHdheSB0byBtYWtlIGEgbGFyZ2UgcmFuZ2Ugb2YgbnVtYmVycyB2aXNpYmxlIGluIGFuIGVkZ2UuIE90aGVyd2lzZSBlZGdlcyB0ZW5kIHRvIGNvdmVyIHVwIGFsbCB0aGUgb3RoZXIgZWRnZXMgYW5kIG9ic2N1cmUgdGhlIHJlbGF0aW9uc2hpcHMuDQpgYGANCioqV2hhdCBkb2VzIHRoZSBhZGRpdGlvbiBvZiB3ZWlnaHRlZCBkZWdyZWUgYW5kIGVkZ2UgaW5mb3JtYXRpb24gdGVsbCB5b3UgYWJvdXQgeW91ciBncmFwaD8qKg0KSW4gd2VpZ2h0ZWQgbmV0d29ya3MgdGhlIGRlZ3JlZSBjZW50cmFsaXR5IGlzIGNhbGN1bGF0ZWQgYXMgdGhlIHN1bSBvZiB3ZWlnaHRzIGFzc2lnbmVkIHRvIHRoZSBub2RlJ3MgYnkgdGhlIG51bWJlciBvZiB0d28gd29yZHMgd2hpY2ggZXhpc3QgaW4gb25lIGFydGljbGUuIFdlIGNhbiBzZWUgdGhhdCB0aGUgbm9kZXMgd2l0aCB0aGUgaGlnaGVzdCB3ZWlnaHRlZCBkZWdyZWUgYXJlIGluIHRoZSBjbHVzdGVyIHdoaWNoIGNvbnNpc3RzIG9mIE5GTCB0ZWFtcy4gRWRnZSBpbmZvcm1hdGlvbiBzaG93cyB0aGUgc3F1YXJlIHJvb3Qgb2YgdGhlIG51bWJlciBvZiB0aGUgdHdvIG5vZGVzIHdoaWNoIGV4aXN0IGluIG9uZSBhcnRpY2xlLiBBbHNvLCB0aGUgc2l6ZSBvZiB0aGUgZWFjaCBub2RlIHNob3dzIHRoZSBkZWdyZWUgY2VudHJhbGl0eSBvZiB0aGlzIHBhcnRpY3VsYXIgbm9kZS4gSWYgdGhlIG5vZGUgaGFzIGEgaGlnaCBjZW50cmFsaXR5LCBpdCBhcHBlYXJzIGxhcmdlciBpbiBpdCdzIHNpemUuIE1vcmVvdmVyLCBpdCBjYW4gYmUgc2VlbiB0aGF0IHRoZXJlIGFyZSBtb3JlIGFydGljbGVzIGFib3V0IE5GTCB0ZWFtcyB0aGFuIHBvbGl0aWNpYW5zIGluIE5ldyBZb3JrIFRpbWVzLiANCg0KIyMgQmV0d2Vlbm5lc3MgQ2VudHJhbGl0eQ0KYGBge3J9DQpiIDwtIGJldHdlZW5uZXNzKGdfdmFsdWVkLGRpcmVjdGVkPVRSVUUpDQpzb3J0KGIsZGVjcmVhc2luZz1UUlVFKVsxOjVdDQpnNCA8LSBnX3ZhbHVlZA0KVihnNCkkc2l6ZSA8LSBiKjEuMiNjYW4gYWRqdXN0IHRoZSBudW1iZXINCnBsb3QoZzQsIGxheW91dCA9IEwsIHZlcnRleC5sYWJlbD1OQSkNCmBgYA0KKipCcmllZmx5IGV4cGxhaW4gYmV0d2Vlbm5lc3MgY2VudHJhbGl0eSBhbmQgd2h5IG5vZGVzIGFyZSBtb3JlIG9yIGxlc3MgY2VudHJhbCBpbiB0aGUgbmV0d29yay4qKg0KQmV0d2Vlbm5lc3MgY2VudGFsaXR5IHNob3dzIHRoYXQgaG93IG11Y2ggYSBub2RlIGhhdmUgYmVlbiBpbnZvbHZlZCBiZXR3ZWVuIGRpZmZlcmVudCBncm91cHMgb2YgdGhlIG5ldHdvcmsuIFRoZSBub2RlcyB3aGljaCBhcmUgYnJva2VycyBoYXZlIHRoZSBoaWdoZXN0IGJldHdlZW5uZXNzIGNlbnRyYWxpdHkuIEluIG91ciBuZXR3b3JrIHRoZSBicm9rZXJzIGFyZSBUcnVtcCBhbmQgQ2Fzc2lkeS4gVHJ1bXAgaGFzIGxpZWQgYmV0d2VlbiBhbGwgMyBzdWJncm91cHModGhlIE5GTCB0ZWFtcywgMiBncm91cHMgb2YgcG9saXRpY2lhbnMpLCBzbyBpdCBoYXMgdGhlIGhpZ2hlc3QgYmV0d2Vlbm5lc3MgY2VudHJhbGl0eSBpbiB0aGUgZ3JhcGguIENhc3NpZHkgaXMgYSBicm9rZXIgdG9vIGFuZCBoZSBsaWVzIGJldHdlZW4gdGhlIDIgZ3JvdXBzIG9mIHRoZSBwb2xpdGljaWFucy4gVGhlcmVmb3JlLCBDYXNzaWR5IGhhdmUgdGhlIHNlY29uZCBoaWdoZXN0IGJldHdlZW5uZXNzIGNlbnRyYWxpdHkgaW4gdGhlIG5ldHdvcmsuIFNpbmNlIHRoZSBvdGhlciBub2RlcyBvZiB0aGUgbmV0d29yayBvbmx5IGhhdmUgcGFydGljaXBhdGVkIGluIHRoZWlyIG93biBzdWJncm91cHMsIHRoZXkgaGF2ZSBsb3cgYmV0d2Vlbm5lc3MgY2VudHJhbGl0eS4gDQoNCiMjIyBXZWlnaHRlZCBCZXR3ZWVubmVzcyBDZW50cmFsaXR5DQpgYGB7cn0NCndidHduIDwtIGJldHdlZW5uZXNzKGdfdmFsdWVkLHdlaWdodHMgPSBFKGdfdmFsdWVkKSRDb09jY3VycmVuY2VzKQ0Kc29ydCh3YnR3bixkZWNyZWFzaW5nPVRSVUUpWzE6NV0NCndCdHduRyA8LSBnX3ZhbHVlZA0KVih3QnR3bkcpJHNpemUgPC0gd2J0d24qLjUgIyBhZGp1c3QgdGhlIG51bWJlciBpZiBub2RlcyBhcmUgdG9vIGJpZw0KcGxvdCh3QnR3bkcsIGxheW91dCA9IEwsIHZlcnRleC5sYWJlbD1OQSwgZWRnZS53aWR0aD1zcXJ0KEUoZ192YWx1ZWQpJENvT2NjdXJyZW5jZXMpKSAjdGFraW5nIHRoZSBzcXVhcmUgcm9vdCBpcyBhIGdvb2Qgd2F5IHRvIG1ha2UgYSBsYXJnZSByYW5nZSBvZiBudW1iZXJzIHZpc2libGUgaW4gYW4gZWRnZS4NCmBgYA0KKipXaGF0IGRvZXMgdGhlIGFkZGl0aW9uIG9mIHdlaWdodGVkIGRlZ3JlZSBhbmQgZWRnZSBpbmZvcm1hdGlvbiB0ZWxsIHlvdSBhYm91dCB5b3VyIGdyYXBoPyoqDQp3ZSBjYW4gc2VlIHRoYXQgaW4gdGhpcyBncmFnaCBUcnVtcCBpcyBzdGlsbCBoYXZlIHRoZSBoaWdoZXN0IHdlaWdodGVkIGJldHdlZW5uZXNzIGJ1dCBpbnN0ZWFkIG9mIENhc3NpZHksIFNlbi4gQmlsbCBOZWxzb24gaGF2ZSB0aGUgc2Vjb25kIGhpZ2hlc3QgYmV0d2Vlbm5lc3MgY2VudHJhbGl0eS4gSSBndWVzcyB0aGF0IGl0IG1pZ2h0IGJlIGJlY2F1c2Ugb2YgdGhlIG51bWJlciBvZiB0aGVpciBsaW5rcyBhbmQgdGhlaXIgY29zdHMuIFdlIGNhbiBhZGQgdGhhdCBpbiBJZ3JhZ2ggc2luY2UgdGhlIGRpc3RhbmNlcyBvZiB0aGUgbGlua3Mgd2l0aCBsZXNzIHdpZHRoIGFyZSBzaG9ydGVyLCB3ZSBwcmVmZXIgdG8gdXNlIHRoZSBsaW5rcyB3aXRoIGxlc3Mgd2lkdGggaW4gYmV0d2Vlbm5lc3MgY2VudHJhbGl0eS4gQXMgd2Uga25vdyB3aGVuIHRoZSBzaXplIG9mIGEgbm9kZSBzaG93cyBpdCdzIGJldHdlZW5uZXNzIGNlbnRyYWxpdHkuIA0KDQojIyBDbG9zZW5lc3MgQ2VudHJhbGl0eQ0KYGBge3J9DQpjIDwtIGNsb3NlbmVzcyhnX3ZhbHVlZCkNCnNvcnQoYyxkZWNyZWFzaW5nPVRSVUUpWzE6NV0NCmc1IDwtIGdfdmFsdWVkDQpWKGc1KSRzaXplIDwtIGMqNTAwICAjY2FuIGFkanVzdCB0aGUgbnVtYmVyDQpwbG90KGc1LCBsYXlvdXQgPSBMLCB2ZXJ0ZXgubGFiZWw9TkEpDQpgYGANCioqQnJpZWZseSBleHBsYWluIGNsb3NlbmVzcyBjZW50cmFsaXR5IGFuZCB3aHkgbm9kZXMgYXJlIG1vcmUgb3IgbGVzcyBjZW50cmFsIGluIHRoZSBuZXR3b3JrLioqDQpDbG9zZW5lc3MgY2VudHJhbGl0eSBzaG93cyBob3cgZWFzaWx5IG9uZSBhY3RvciBjYW4gcmVhY2ggdG8gdGhlICByZXN0IG9mIG5ldHdvcmsuIFRoZSBub2RlIHdpdGggIHRoZSBzaG9ydGVzdCBwYXRoIHRvIGFjY2VzcyB0byB0aGUgb3RoZXIgbm9kZXMgaGF2ZSB0aGUgaGlnaGVzdCBjbG9zZW5lc3MgY2VudHJhbGl0eS4gd2UgY2FuIHNlZSBzaW5jZSBUcnVtcCBsaWVzIGJldHdlZW4gYWxsIHRocmVlIGNsdXN0ZXJzIGluIHRoaXMgbmV0d29yaywgaXQgaGFzIHRoZSBzaG9ydGVzdCBwYXRoIHRvIHRoZSBvdGhlcnMgYW5kIHRoZSBoaWdoZXN0IGNsb3NlbmVzcyBjZW50cmFsaXR5LiANCiMjIyBXZWlnaHRlZCBDbG9zZW5lc3MgQ2VudHJhbGl0eQ0KDQpgYGB7cn0NCndDbHNuc3MgPC0gY2xvc2VuZXNzKGdfdmFsdWVkLHdlaWdodHMgPSBFKGdfdmFsdWVkKSRDb09jY3VycmVuY2VzKQ0Kc29ydCh3Q2xzbnNzLGRlY3JlYXNpbmc9VFJVRSlbMTo1XQ0Kd0Nsc25zc0cgPC0gZ192YWx1ZWQNClYod0Nsc25zc0cpJHNpemUgPC0gd0Nsc25zcyoxMDAwICMgYWRqdXN0IHRoZSBudW1iZXIgaWYgbm9kZXMgYXJlIHRvbyBiaWcNCnBsb3Qod0Nsc25zc0csIGxheW91dCA9IEwsIHZlcnRleC5sYWJlbD1OQSwgZWRnZS53aWR0aD1zcXJ0KEUoZ192YWx1ZWQpJENvT2NjdXJyZW5jZXMpKSAjdGFraW5nIHRoZSBzcXVhcmUgcm9vdCBpcyBhIGdvb2Qgd2F5IHRvIG1ha2UgYSBsYXJnZSByYW5nZSBvZiBudW1iZXJzIHZpc2libGUgaW4gYW4gZWRnZS4NCmBgYA0KKipXaGF0IGRvZXMgdGhlIGFkZGl0aW9uIG9mIHdlaWdodGVkIGRlZ3JlZSBhbmQgZWRnZSBpbmZvcm1hdGlvbiB0ZWxsIHlvdSBhYm91dCB5b3VyIGdyYXBoPyoqDQpIZXJlLCB3ZSBoYXZlIGEgd2VpZ2h0ZWQgbmV0d29yayB3aGljaCBldmVyeSBsaW5rcyBoYXZlIHdpZWdodHMuIFRoaXMgd2VpZ2h0ZW5pbmcgYXNzaWdubWVudCBpcyBiYXNlZCBvbiB0aGUgbnVtYmVyIGlmIGV4aXN0ZW5jZSBvZiBib3RoIHR3byBhY3RvcnMgaW4gdGhlIHNhbWUgYXJ0aWNsZS4NCkFsc28gbm9kZSdzIHNpemUgaXMgc3VtIG9mIHdpZWdodHMgb2YgaXRzIGxpbmtzLg0KU28gd2UgY2FuIGNvbmNsdWRlIHRoYXQgbm9kZSdzIHNpemUgaXMgY2xvc2VuZXNzIGNlbnRlcmFsbGl0eSBmb3IgdGhhdCBub2RlIGFuZCBsaW5rcyB3aWd0aHMgc2hvdyBob3cgbWFueSBhcnRpY2xlIGhhdmUgYm90aCB0d28gYWN0b3IgaW4gaXQuDQpJbiB0aGlzIG5ldHdvcmssIFRydW1wIGFuZCBTZW4uIEJpbGwgTmVsc29uIGhhdmUgdGhlIGhpZ2hlc3QgQ2VudGVyYWxpdHkoVHJ1bXAgaXMgaGlnaGVzdCkuDQpXZSBjYW4gYWxzbyBtZW50aW9ucyB0aGF0IGlwcmFwaCBpcyBiYXNlZCBvbiBjb3N0cy4gTG93ZXIgY29zdCBub2RlcyBoYXZlIGVhc2llciB3YXkgdG8gcmVhY2ggYW5vdGhlciBub2Rlcy4gTGlrZSBoZXJlLCBiZXR3ZWVuIFRydW1wIGFuZCBTZW4uIE5lbHNvbi4NCiMjIEVpZ2VudmVjdG9yIENlbnRyYWxpdHkNCmBgYHtyfQ0KZWlnYyA8LSBlaWdlbl9jZW50cmFsaXR5KGdfdmFsdWVkLGRpcmVjdGVkPVRSVUUpDQpzb3J0KGVpZ2MkdmVjdG9yLGRlY3JlYXNpbmc9VFJVRSlbMTo1XQ0KZzYgPC0gZ192YWx1ZWQNClYoZzYpJHNpemUgPC0gZWlnYyR2ZWN0b3IqNTAgI2NhbiBhZGp1c3QgdGhlIG51bWJlcg0KcGxvdChnNiwgbGF5b3V0ID0gTCwgdmVydGV4LmxhYmVsPU5BKQ0KYGBgDQoNCioqQnJpZWZseSBleHBsYWluIGVpZ2VudmVjdG9yIGNlbnRyYWxpdHkgYW5kIHdoeSBub2RlcyBhcmUgbW9yZSBvciBsZXNzIGNlbnRyYWwgaW4gdGhlIG5ldHdvcmsuKioNCiBFaWdlbnZlY3RvciBjZW50cmFsaXR5IGlzIGJhc2VkIG9uIHRoZSBub2RlJ3MgbmVpZ2hib3VyJ3MgY2VudGVyYWxpdGllcy4gIHRoZSBtb3JlIGNlbnRlcmFsaXR5IG9mIHRoZSBuZWlnaGJvdXJzIG9mIGEgbm9kZSBhcmUgaGlnaGVyLCB0aGUgZWlnZW52ZWN0b3IgY2VudGVyYWxpdHkgb2YgdGhpcyBub2RlIHdvdWxkIGJlIGhpZ2hlciB0b28uICBiYXNlZCBvbiB0aGlzIGRlZmluaXRpb24gd2UgY2FuIHNlZSB0aGF0IGEgbm9kZSB0aGF0IGhhcyBtb3JlIGluZmx1ZW5jZSBpbiB0aGUgbmV0d29yayBpcyBtb3JlIGNlbnRyYWwgKGhlcmUgaXMgdGhlIFRydW1wIG5vZGUoYnJva2VyKSkuIEFsc28sIHNpbmNlIGFsbCB0aGUgTkZMIHRlYW1zIGFyZSBjb25uZWN0ZWQgdG8gZWFjaCBvdGhlciBhbmQgdG8gdGhlIFRydW1wLCB0aGV5IGhhdmUgaGlnaCBlaWdlbnZlY3RvciBjZW50cmFsaXR5IHRvby4NCiMjIEFuYWx5c2lzDQoqKkNob29zZSB0aGUgdmlzdWFsaXphdGlvbiB0aGF0IHlvdSB0aGluayBpcyBtb3N0IGludGVyZXN0aW5nIGFuZCBicmllZmx5IGV4cGxhaW4gd2hhdCBpdCB0ZWxscyB5b3UgYWJvdXQgYSBjZW50cmFsIG5vZGUgaW4geW91ciBuZXR3b3JrLiBEaXNjdXNzIHRoZSB0eXBlIG9mIGNlbnRyYWxpdHksIGFuZCB3aGF0IHRoYXQgbm9kZeKAmXMgY2VudHJhbGl0eSBzY29yZSB0ZWxscyB5b3UgYWJvdXQgdGhlIHNlYXJjaCBjby1vY2N1cnJlbmNlIG5ldHdvcmsuKioNCkkgdGhpbmsgdGhlIG1vc3QgaW50ZXJlc3RpbmcgdmlzdWFsaXphdGlvbiBpcyB0aGUgV2VpZ2h0ZWQgZGVncmVlIGNlbnRyYWxpdHkuIEl0IGNhbiBiZSBzZWVuIHRoYXQgcG9saXRpY2lhbnMgYW5kIHNlbmF0b3JzIGFyZSBsZXNzIGFwcGVhcmVkIGluIHRoZSBhcnRpY2xlcyB0aGFuIE5GTCB0ZWFtcyBtYXliZSBpdCBpcyBiZWNhdXNlIE5GTCB0ZWFtcyBhcmUgbW9yZSBwb3B1bGFyIHRoYW4gdGhlIHBvbGl0aWNpYW5zIGFtb25nIHRoZSBwZW9wbGUgb3IgaXQgbWlnaHQgYmUgYmVjYXVzZSBvZiBvdXIgc2VhcmNoIHRlcm1zLiBUaGVzZSBORkwgdGVhbXMgaGF2ZSBtb3JlIHdlaWdodGVkIGNlbnRyYWxpdHkgdGhhbiB0aGUgcG9saXRpY2lhbnMuIA0KKipCcmllZmx5IGRpc2N1c3MgYW4gaW50ZXJlc3RpbmcgZGlmZmVyZW5jZSBiZXR3ZWVuIHR5cGVzIG9mIGNlbnRyYWxpdHkgZm9yIHlvdXIgbmV0d29yay4qKg0KSXQgaXMgaW50ZXJlc3RpbmcgdGhhbiBhbG1vc3QgaW4gYWxsIHRoZSBncmFwaHMgdGhlIGJyb2tlcihUcnVtcCBub2RlKSBoYXZlIHRoZSBoaWdoZXN0IGNlbnRyYWxpdHkuIEJ1dCBub2RlIENhc3NpZHkgaXMgYWxtb3N0IGRpZmZlcmVudCBpbiBlYWNoIG9mIHRoZSBjZW50ZXJhbGl0aWVzKGRlZ3JlZSxiZXR3ZWVubmVzcyx3ZWlnaGVkKS4gTW9yZW92ZXIsIHdlIGNhbiBzZWUgdGhhdCB0aGUgZ3JhcGggb2YgdGhlIGNvbWJpbmF0aW9uIG9mIHR3byBraW5kcyBvZiBjZW50cmFsaXR5IGNvdWxkIGJlIHZlcnkgZGlmZmVybnQgZnJvbSBlYWNoIGluZGl2aWR1YWwgb25lIG9mIHRoZW0uIEZvciBleGFtcGxlIHRoZSBncmFwaCBvZiB3ZWlnaHRlZCBjbG9zZW5lc3MgY2VudHJhbGl0eSBpcyBkaWZmZXJlbnQgZnJvbSBjbG9zZW5lc3MgY2VudHJhbGl0eS4gRnVydGhlcm1vcmUsIGl0IGNhbiBiZSBzZWVuIHRoYXQgaWYgYSBub2RlIGhhcyBoaWdoIGRlZ3JlZSBjZW50cmFsaXR5LCBpdCBkb2VzIG5vdCBtZWFuIHRoYXQgaXQgd291bGQgaGF2ZSBoaWdoIGJldHdlZW5lc3MgY2VudHJhbGl0eSBvciBoaWdoIGVpZ2VudmVjdG9yIHZhbHVlIHRvby4NCiMjIEdsb2JhbCBOZXR3b3JrIE1ldHJpY3Mgd2l0aCBSDQoNCkNvbXB1dGUgdGhlIG5ldHdvcmsgY2VudHJhbGl6YXRpb24gc2NvcmVzIGZvciB5b3VyIG5ldHdvcmsgZm9yIGRlZ3JlZSwgYmV0d2Vlbm5lc3MsIGNsb3NlbmVzcywgYW5kIGVpZ2VudmVjdG9yIGNlbnRyYWxpdHkuDQoNCmBgYHtyfQ0KIyBEZWdyZWUgY2VudHJhbGl6YXRpb24NCmNlbnRyYWxpemF0aW9uLmRlZ3JlZShnX3ZhbHVlZCxub3JtYWxpemVkID0gVFJVRSkNCg0KIyBCZXR3ZWVubmVzcyBjZW50cmFsaXphdGlvbg0KY2VudHJhbGl6YXRpb24uYmV0d2Vlbm5lc3MoZ192YWx1ZWQsbm9ybWFsaXplZCA9IFRSVUUpDQoNCiMgQ2xvc2VuZXNzIGNlbnRyYWxpemF0aW9uIA0KY2VudHJhbGl6YXRpb24uY2xvc2VuZXNzKGdfdmFsdWVkLG5vcm1hbGl6ZWQgPSBUUlVFKQ0KDQojIEVpZ2VudmVjdG9yIGNlbnRyYWxpemF0aW9uIA0KY2VudHJhbGl6YXRpb24uZXZjZW50KGdfdmFsdWVkLG5vcm1hbGl6ZWQgPSBUUlVFKQ0KDQpgYGANCioqUmVjb3JkIHRoZSBjZW50cmFsaXphdGlvbiBzY29yZSBvZiBlYWNoIGNlbnRyYWxpdHkgbWVhc3VyZS4qKg0KRGVncmVlIGNlbnRyYWxpemF0aW9uID0gMC41OTUyMzgxIA0KQmV0d2Vlbm5lc3MgY2VudHJhbGl6YXRpb24gPSAwLjcwNTY1MTUgDQpDbG9zZW5lc3MgY2VudHJhbGl6YXRpb24gPSAwLjc3Nzk5NzEgDQpFaWdlbnZlY3RvciBjZW50cmFsaXphdGlvbiA9IDAuNTkwNDM0OQ0KKipCcmllZmx5IGV4cGxhaW4gd2hhdCB0aGUgY2VudHJhbGl6YXRpb24gb2YgYSBuZXR3b3JrIGlzLioqDQpUaGUgY2VudGVyYWxpemF0aW9uIG9mIGEgbmV0d29yayBzaG93cyB0aGF0IGlzIGEgbmV3b3JrIGlzIGNlbnRlcmFsaXplZCBvbiBvdmVyYWxsIG9yIG5vdC4gSWYgd2UgaGF2ZSBvbmUgbm9kZSB3aGljaCBoYXMgdGhlIGhpZ2hlc3QgY2VudHJhbGl0eSBpbiB0aGUgbmV3b3JrLCBvdXIgbmV0d29yayBpcyBnbG9iYWxseSBjZW50ZXJhbGl6ZWQuIEJ1dCwgd2hlbiB3ZSBoYXZlIHNldmVyYWwgbm9kZXMgd2l0aCBoaWdoIGNlbnRyYWxpemF0aW9uLCBvdXIgbmV0d29yayBpcyBub3QgY29uc2lkZXJlZCBhcyBhIGNlbnRlcmFsaXplZCBuZXR3b3JrLg0KKipDb21wYXJlIHRoZSBjZW50cmFsaXphdGlvbiBzY29yZXMgYWJvdmUgd2l0aCB0aGUgZ3JhcGhzIHlvdSBjcmVhdGVkIHdoZXJlIHRoZSBub2RlcyBhcmUgc2NhbGVkIGJ5IGNlbnRyYWxpdHkuIERlc2NyaWJlIHRoZSBhcHBlYXJhbmNlIG9mIG1vcmUgY2VudHJhbGl6ZWQgdi4gbGVzcyBjZW50cmFsaXplZCBuZXR3b3Jrcy4qKg0KU2luY2UgYmV0d2Vlbm5lc3MgYW5kIGNsb3NlbmVzcyBjZW50cmFsaXRpZXMgb2YgdGhlIG5ldHdvcmsgd2hpY2ggYXJlIDAuNzA1NjUxNSBhbmQgMC43Nzc5OTcxICBhcmUgbW9yZSB0aGFuIGRlZ3JlZSBhbmQgRWlnZW52ZWN0byBjZW50ZXJhbGl6YXRpb24sIG91ciBuZXR3b3JrIGlzIG1vcmUgY2VudGVyYWxpemVkIGluIGJldHdlZW5uZXNzIGFuZCBjbG9zZW5lc3MgdGhhbiBkZWdyZWUgYW5kIEVpZ2VudmVjdG8uDQojIyBQYXJ0IDUuIFBvd2VyIExhd3MgJiBTbWFsbCBXb3JsZHMgKDIwKQ0KDQojIyBQb3dlciBMYXdzDQpOZXR3b3JrcyBvZnRlbiBkZW1vbnN0cmF0ZSBwb3dlciBsYXcgZGlzdHJpYnV0aW9ucy4gUGxvdCB0aGUgZGVncmVlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgbm9kZXMgaW4geW91ciBiYXNlIGdyYXBoLiANCmBgYHtyfQ0KIyBDYWxjdWxhdGUgZGVncmVlIGRpc3RyaWJ1dGlvbg0KZGVnIDwtIGRlZ3JlZShnX3ZhbHVlZCx2PVYoZ192YWx1ZWQpLCBtb2RlPSJhbGwiKQ0KZGVnDQoNCiMgRGVncmVlIGRpc3RyaWJ1dGlvbiBpcyB0aGUgY3VtdWxhdGl2ZSBmcmVxdWVuY3kgb2Ygbm9kZXMgd2l0aCBhIGdpdmVuIGRlZ3JlZQ0KZGVnX2Rpc3RyIDwtZGVncmVlLmRpc3RyaWJ1dGlvbihnX3ZhbHVlZCwgY3VtdWxhdGl2ZT1ULCBtb2RlPSJhbGwiKQ0KZGVnX2Rpc3RyDQpwbG90KGRlZ19kaXN0ciwgeWxpbT1jKC4wMSwxMCksIGJnPSJibGFjayIscGNoPTIxLCB4bGFiPSJEZWdyZWUiLCB5bGFiPSJDdW11bGF0aXZlIEZyZXF1ZW5jeSIpICNZb3UgbWF5IG5lZWQgdG8gYWRqdXN0IHRoZSB5bGltIHRvIGEgbGFyZ2VyIG9yIHNtYWxsZXIgbnVtYmVyIHRvIG1ha2UgdGhlIGdyYXBoIHNob3cgbW9yZSBkYXRhLg0KYGBgDQoNClRlc3Qgd2hldGhlciBpdOKAmXMgYXBwcm94aW1hdGVseSBhIHBvd2VyIGxhdywgZXN0aW1hdGUgbG9nIGYgKGspID0gbG9nIGEg4oiSIGMgbG9nIGsuIOKAnFRoaXMgc2F5cyB0aGF0IGlmIHdlIGhhdmUgYSBwb3dlci1sYXcgcmVsYXRpb25zaGlwLCBhbmQgd2UgcGxvdCBsb2cgZiAoaykgYXMgYSBmdW5jdGlvbiBvZiBsb2cgaywgdGhlbiB3ZSBzaG91bGQgc2VlIGEgc3RyYWlnaHQgbGluZTog4oiSYyB3aWxsIGJlIHRoZSBzbG9wZSwgYW5kIGxvZyBhIHdpbGwgYmUgdGhlIHktaW50ZXJjZXB0LiBTdWNoIGEg4oCcbG9nLWxvZ+KAnSBwbG90IHRodXMgcHJvdmlkZXMgYSBxdWljayB3YXkgdG8gc2VlIGlmIG9uZeKAmXMgZGF0YSBleGhpYml0cyBhbiBhcHByb3hpbWF0ZSBwb3dlci1sYXc6IGl0IGlzIGVhc3kgdG8gc2VlIGlmIG9uZSBoYXMgYW4gYXBwcm94aW1hdGVseSBzdHJhaWdodCBsaW5lLCBhbmQgb25lIGNhbiByZWFkIG9mZiB0aGUgZXhwb25lbnQgZnJvbSB0aGUgc2xvcGUu4oCdIChFJkssIENoYXB0ZXIgMTgsIHAuNTQ2KS4NCg0KYGBge3J9DQpwb3dlciA8LSBwb3dlci5sYXcuZml0KGRlZ19kaXN0cikNCnBvd2VyDQpwbG90KGRlZ19kaXN0ciwgbG9nPSJ4eSIsIHlsaW09YyguMDEsMTApLCBiZz0iYmxhY2siLHBjaD0yMSwgeGxhYj0iRGVncmVlIiwgeWxhYj0iQ3VtdWxhdGl2ZSBGcmVxdWVuY3kiKQ0KYGBgDQoNCioqRG9lcyB5b3VyIG5ldHdvcmsgZXhoaWJpdCBhIHBvd2VyIGxhdyBkaXN0cmlidXRpb24gb2YgZGVncmVlIGNlbnRyYWxpdHk/KioNClNpbmNlIHdlIGRvIG5vdCBoYXZlIGFueSBsb25nIHRhaWwgaW4gdGhlIGRlZ3JlZSBkaXN0cmlidXRpb24gcGxvdCB3ZSBjYW4gc2VlIHRoYXQgb3VyIG5ldHdvcmsgZG9lcyBub3QgZXhoaWJpdCBhIHBvd2VyIGxvdyBkaXN0cmlidXRpb24uIHRoZSBvdGhlciByZWFzb24gaXMgdGhhdCBpZiBvdXIgbmV0d29yayB3YXMgYSBwb3dlciBsYXcgZGlzdHJpYnV0aW9uIHRoZSBsb2cgcGxvdCB3b3VsZCBiZSBsaWtlIGEgc3RhaWdodCBsaW5lLCB3aGljaCBpcyBub3QgaW4gdGhpcyBuZXR3b3JrLiANCg0KIyMgU21hbGwgV29ybGRzDQoNCk5ldHdvcmtzIG9mdGVuIGRlbW9uc3RyYXRlIHNtYWxsIHdvcmxkIGNoYXJhY3RlcmlzdGljcy4gQ29tcHV0ZSB0aGUgYXZlcmFnZSBjbHVzdGVyaW5nIGNvZWZmaWNpZW50IChBQ0MpIGFuZCB0aGUgY2hhcmFjdGVyaXN0aWMgcGF0aCBsZW5ndGggKENQTCkuDQpgYGB7cn0NCiMgQXZlcmFnZSBjbHVzdGVyaW5nIGNvZWZmaWNpZW50IChBQ0MpDQp0cmFuc2l0aXZpdHkoZ192YWx1ZWQsIHR5cGUgPSBjKCJhdmVyYWdlIikpDQoNCiMgQ2hhcmFjdGVyaXN0aWMgcGF0aCBsZW5ndGggKENQTCkNCmF2ZXJhZ2UucGF0aC5sZW5ndGgoZ192YWx1ZWQpDQpgYGANCg0KQ29tcHV0ZSB0aGUgQUNDIGFuZCBDUEwgZm9yIDEwMCByYW5kb20gbmV0d29ya3Mgd2l0aCB0aGUgc2FtZSBudW1iZXIgb2Ygbm9kZXMgYW5kIHRpZXMgYXMgeW91ciB0ZXN0IG5ldHdvcmsuIA0KDQpgYGB7cn0NCmFjY1N1bSA8LSAwDQpjcGxTdW0gPC0gMA0KZm9yIChpIGluIDE6MTAwKXsNCiAgZ3JwaCA8LSBlcmRvcy5yZW55aS5nYW1lKG51bVZlcnRpY2VzLCBudW1FZGdlcywgdHlwZSA9ICJnbm0iKQ0KICBhY2NTdW0gPC0gYWNjU3VtICsgdHJhbnNpdGl2aXR5KGdycGgsIHR5cGUgPSBjKCJhdmVyYWdlIikpDQogIGNwbFN1bSA8LSBjcGxTdW0gKyBhdmVyYWdlLnBhdGgubGVuZ3RoKGdycGgpDQp9DQphY2NTdW0vMTAwDQpjcGxTdW0vMTAwDQpgYGANCg0KKipCYXNlZCBvbiB0aGVzZSBkYXRhLCB3b3VsZCB5b3UgY29uY2x1ZGUgdGhhdCB0aGUgb2JzZXJ2ZWQgbmV0d29yayBkZW1vbnN0cmF0ZXMgc21hbGwgd29ybGQgcHJvcGVydGllcz8gV2h5IG9yIHdoeSBub3Q/KioNClNpbmNlIHRoZSBBQ0Mgb2YgdGhlIG5ldHdvcmsgaXMgYWJvdXQgMC44MiBhbmQgaXQgaXMgbW9yZSB0aGFuIGF2ZXJhZ2UgQWNjICBvZiB0aGUgcmFuZG9tIG5ldHdvcmssIE5ldHdvcmtzIGRlbW9uc3RyYXRlIHNtYWxsIHdvcmxkIGNoYXJhY3RlcmlzdGljcy4gQWxzbyBiZWNhdXNlIENQTCBvZiB0aGUgbmV0d29yayB3aGljaCBpcyBhYm91dCBDUEwgMS43IGlzIGxlc3MgdGhhbiB0aGUgQ1BMIG9mIHRoZSByYW5kb20gbmV0d29yayBpdCBhbHNvIGFmZmlybXMgdGhhdCB0aGUgbmV0d29yayBpcyBzbWFsbCB3b3JsZC4NCiMjIFdyYXBwaW5nIHVwDQpUbyBjb21wbGV0ZSB0aGUgbGFiLCBtYWtlIHN1cmUgb3V0cHV0L3ByZXZpZXdzIGhhdmUgYmVlbiBnZW5lcmF0ZWQgZm9yIGVhY2ggYmxvY2sgb2YgY29kZS4gVGhlbiBjbGljayB0aGUgIlB1Ymxpc2giIGJ1dHRvbiBvbiB0aGUgdXBwZXIgcmlnaHQgaGFuZCBjb3JuZXIgb2YgdGhpcyBzY3JlZW4gYW5kIHNpZ24gdXAgZm9yIGFuIFJQdWJzIGFjY291bnQuIFN1Ym1pdCB0aGUgVVJMIG9mIHRoZSBwdWJsaXNoZWQsIGNvbXBsZXRlZCBsYWIgb24gQ2FudmFzLg0K