Description
In this assignment, you will be performing an analysis of a social network of bottle nose dolphins. The nodes in the network each represent a member of a bottle nose dolphin community living off Doubtful Sounds in New Zealand. An edge exists between two nodes if there is a frequent association between the dolphins represented by those nodes. The observations were gathered between 1994 and 2001.
Load Packages
Begin by loading the igraph, dplyr, and RColorBrewer packages.
r
r require(igraph) require(dplyr) require(RColorBrewer)
Load Contents
The file nodes.txt
contains the names of the dolphins, as well as a numerical code that has been assigned to each dolphin. The file edges.txt
contains a list of edges.
Run the code below to read in and prepare the data for our analysis.
Perform the following steps in the cell below:
- Use the
graph_from_data_frame()
function to create an undirected graph from the edges.
- For the sake of reproducability, set the seed to 1 using
set.seed()
.
- Plot the graph without vertex labels. Select an appropriate vertex size for your graph.
r
r g <- graph_from_data_frame(edges,directed=FALSE) set.seed(1) plot(g, vertex.size = 4, vertex.label = NA)

Calculate Centrality Measures
Perform the following steps in the cell below:
- Calculate the degree centrality of the nodes in the graph. Store the results.
- Calculate the betweenness centrality of the nodes in the graph. Store the results.
- Calculate the closeness centrality of the nodes in the graph. Store the results.
- Create a data frame called
nodes
with five columns: Node (the number assigned to the dolphin), Name (the name of the dolphin), dCent (degree centrality), bCent (betweenness centrality), and cCent (closeness centrality).
- Print a summary of this data frame.
r
r dC <- degree(g) bC <- betweenness(g) cC <- closeness(g) centDF <- data.frame(Node = names(dC), dCent = dC, bCent = bC, cCent = cC, stringsAsFactors = FALSE) nodes <- left_join(nodes, centDF, by=‘Node’) summary(nodes)
Node Name dCent bCent cCent
Length:62 Length:62 Min. : 1.000 Min. : 0.000 Min. :0.002924
Class :character Class :character 1st Qu.: 3.000 1st Qu.: 5.641 1st Qu.:0.004288
Mode :character Mode :character Median : 5.000 Median : 39.583 Median :0.005181
Mean : 5.129 Mean : 71.887 Mean :0.005037
3rd Qu.: 7.000 3rd Qu.:102.638 3rd Qu.:0.005556
Max. :12.000 Max. :454.274 Max. :0.006849
Print the contents of nodes
in descending order of degree centrality.
r
r arrange(nodes, desc(dCent))
Print the contents of nodes
in descending order of betweenness centrality.
r
r arrange(nodes, desc(bCent))
Print the contents of nodes
in descending order of closeness centrality.
r
r arrange(nodes, desc(cCent))
List any names of any dolphins that appear in the top 10 for all three centrality measures.
SN4, Kringel, and Beescratch.
Visualizing Centrality
In the cell below, complete the following steps: 1. Set the seed equal to 1. 2. Create a cut of the vector dC
. Set the cuts to roughly correspond to the quartiles of the degree centrality (refer to the summary above). Set labels = FALSE
. 3. Create a RColorBrewer
palette with 4 colors. 4. Plot the graph with the size and color of the vertices each determined by degree centrality. Use the cut and palette you defined to set the color. Then set the size to be equal to 2 + the value of the cut. Do not display the labels.

In the cell below, complete the following steps: 1. Set the seed equal to 1. 2. Create a cut of the vector bC
. Use the following cut levels: -1, 25, 75, 150, 450, and 500. Set labels = FALSE
. 3. Create a RColorBrewer
palette with 5 colors. 4. Plot the graph with the size and color of the vertices each determined by betweenness centrality. Use the cut and palette you defined to set the color. Then set the size to be equal to 2 + the value of the cut. Do not display the labels.

Clique Detection
Find the largest cliques in the network. Print a list of nodes contained in each clique.
r
r lc <- largest_cliques(g) lc
[[1]]
+ 5/62 vertices, named, from d6c212d:
[1] 57 13 9 6 17
[[2]]
+ 5/62 vertices, named, from d6c212d:
[1] 51 45 18 29 24
[[3]]
+ 5/62 vertices, named, from d6c212d:
[1] 51 45 18 29 21
Print the names of the dolphins contained in each of the largest cliques. You will need a separate code chunk for each clique.
r
r c1 <- lc[[1]]$name filter(nodes, Node %in% c1)
r
r c2 <- lc[[2]]$name filter(nodes, Node %in% c2)
r
r c3 <- lc[[3]]$name filter(nodes, Node %in% c3)
A larger clique could be created by adding a single edge between two dolphins. Which two dolphins are they?
MN83 and MN105.
LS0tDQp0aXRsZTogIkhXIDA3OiBEb2xwaGluIFNvY2lhbCBOZXR3b3JrIEFuYWx5c2lzIg0Kb3V0cHV0OiANCiAgICBodG1sX25vdGVib29rOg0KICAgICAgICB0aGVtZTogZmxhdGx5DQogICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICB0b2NfZmxvYXQ6IHRydWUNCi0tLQ0KDQojIyMgRGVzY3JpcHRpb24NCg0KSW4gdGhpcyBhc3NpZ25tZW50LCB5b3Ugd2lsbCBiZSBwZXJmb3JtaW5nIGFuIGFuYWx5c2lzIG9mIGEgc29jaWFsIG5ldHdvcmsgb2YgYm90dGxlIG5vc2UgZG9scGhpbnMuIFRoZSBub2RlcyBpbiB0aGUgbmV0d29yayBlYWNoIHJlcHJlc2VudCBhIG1lbWJlciBvZiBhIGJvdHRsZSBub3NlIGRvbHBoaW4gY29tbXVuaXR5IGxpdmluZyBvZmYgRG91YnRmdWwgU291bmRzIGluIE5ldyBaZWFsYW5kLiBBbiBlZGdlIGV4aXN0cyBiZXR3ZWVuIHR3byBub2RlcyBpZiB0aGVyZSBpcyBhIGZyZXF1ZW50IGFzc29jaWF0aW9uIGJldHdlZW4gdGhlIGRvbHBoaW5zIHJlcHJlc2VudGVkIGJ5IHRob3NlIG5vZGVzLiBUaGUgb2JzZXJ2YXRpb25zIHdlcmUgZ2F0aGVyZWQgYmV0d2VlbiAxOTk0IGFuZCAyMDAxLiANCg0KIyMjIExvYWQgUGFja2FnZXMNCg0KQmVnaW4gYnkgbG9hZGluZyB0aGUgaWdyYXBoLCBkcGx5ciwgYW5kIFJDb2xvckJyZXdlciBwYWNrYWdlcy4gDQoNCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVxdWlyZShpZ3JhcGgpDQpyZXF1aXJlKGRwbHlyKQ0KcmVxdWlyZShSQ29sb3JCcmV3ZXIpDQpgYGANCg0KIyMjIExvYWQgQ29udGVudHMNCg0KVGhlIGZpbGUgYG5vZGVzLnR4dGAgY29udGFpbnMgdGhlIG5hbWVzIG9mIHRoZSBkb2xwaGlucywgYXMgd2VsbCBhcyBhIG51bWVyaWNhbCBjb2RlIHRoYXQgaGFzIGJlZW4gYXNzaWduZWQgdG8gZWFjaCBkb2xwaGluLiBUaGUgZmlsZSBgZWRnZXMudHh0YCBjb250YWlucyBhIGxpc3Qgb2YgZWRnZXMuIA0KDQpSdW4gdGhlIGNvZGUgYmVsb3cgdG8gcmVhZCBpbiBhbmQgcHJlcGFyZSB0aGUgZGF0YSBmb3Igb3VyIGFuYWx5c2lzLg0KDQpgYGB7cn0NCm5vZGVzIDwtIHJlYWQudGFibGUoIm5vZGVzLnR4dCIsIHNlcD0iXHQiLCBoZWFkZXIgPSBUUlVFLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQplZGdlcyA8LSByZWFkLnRhYmxlKCJlZGdlcy50eHQiLCBzZXA9Ilx0IiwgaGVhZGVyID0gVFJVRSkNCm5vZGVzJE5vZGUgPC0gYXMuY2hhcmFjdGVyKG5vZGVzJE5vZGUpDQpgYGANCg0KUGVyZm9ybSB0aGUgZm9sbG93aW5nIHN0ZXBzIGluIHRoZSBjZWxsIGJlbG93Og0KDQoxLiBVc2UgdGhlIGBncmFwaF9mcm9tX2RhdGFfZnJhbWUoKWAgZnVuY3Rpb24gdG8gY3JlYXRlIGFuIHVuZGlyZWN0ZWQgZ3JhcGggZnJvbSB0aGUgZWRnZXMuIA0KMi4gRm9yIHRoZSBzYWtlIG9mIHJlcHJvZHVjYWJpbGl0eSwgc2V0IHRoZSBzZWVkIHRvIDEgdXNpbmcgYHNldC5zZWVkKClgLiANCjMuIFBsb3QgdGhlIGdyYXBoIHdpdGhvdXQgdmVydGV4IGxhYmVscy4gU2VsZWN0IGFuIGFwcHJvcHJpYXRlIHZlcnRleCBzaXplIGZvciB5b3VyIGdyYXBoLiANCg0KYGBge3IsIGZpZy53aWR0aCA9IDIwfQ0KDQpnIDwtIGdyYXBoX2Zyb21fZGF0YV9mcmFtZShlZGdlcyxkaXJlY3RlZD1GQUxTRSkNCnNldC5zZWVkKDEpDQpwbG90KGcsIHZlcnRleC5zaXplID0gNCwgdmVydGV4LmxhYmVsID0gTkEpDQpgYGANCg0KIyMjIENhbGN1bGF0ZSBDZW50cmFsaXR5IE1lYXN1cmVzDQoNClBlcmZvcm0gdGhlIGZvbGxvd2luZyBzdGVwcyBpbiB0aGUgY2VsbCBiZWxvdzoNCg0KMS4gQ2FsY3VsYXRlIHRoZSBkZWdyZWUgY2VudHJhbGl0eSBvZiB0aGUgbm9kZXMgaW4gdGhlIGdyYXBoLiBTdG9yZSB0aGUgcmVzdWx0cy4gDQoyLiBDYWxjdWxhdGUgdGhlIGJldHdlZW5uZXNzIGNlbnRyYWxpdHkgb2YgdGhlIG5vZGVzIGluIHRoZSBncmFwaC4gU3RvcmUgdGhlIHJlc3VsdHMuIA0KMy4gQ2FsY3VsYXRlIHRoZSBjbG9zZW5lc3MgY2VudHJhbGl0eSBvZiB0aGUgbm9kZXMgaW4gdGhlIGdyYXBoLiBTdG9yZSB0aGUgcmVzdWx0cy4gDQo0LiBDcmVhdGUgYSBkYXRhIGZyYW1lIGNhbGxlZCBgbm9kZXNgIHdpdGggZml2ZSBjb2x1bW5zOiBOb2RlICh0aGUgbnVtYmVyIGFzc2lnbmVkIHRvIHRoZSBkb2xwaGluKSwgTmFtZSAodGhlIG5hbWUgb2YgdGhlIGRvbHBoaW4pLCBkQ2VudCAoZGVncmVlIGNlbnRyYWxpdHkpLCBiQ2VudCAoYmV0d2Vlbm5lc3MgY2VudHJhbGl0eSksIGFuZCBjQ2VudCAoY2xvc2VuZXNzIGNlbnRyYWxpdHkpLg0KNS4gUHJpbnQgYSBzdW1tYXJ5IG9mIHRoaXMgZGF0YSBmcmFtZS4gDQoNCmBgYHtyfQ0KZEMgPC0gZGVncmVlKGcpDQpiQyA8LSBiZXR3ZWVubmVzcyhnKQ0KY0MgPC0gY2xvc2VuZXNzKGcpDQoNCmNlbnRERiA8LSBkYXRhLmZyYW1lKE5vZGUgPSBuYW1lcyhkQyksIGRDZW50ID0gZEMsIGJDZW50ID0gYkMsIGNDZW50ID0gY0MsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCg0Kbm9kZXMgPC0gbGVmdF9qb2luKG5vZGVzLCBjZW50REYsIGJ5PSdOb2RlJykNCnN1bW1hcnkobm9kZXMpDQpgYGANCg0KUHJpbnQgdGhlIGNvbnRlbnRzIG9mIGBub2Rlc2AgaW4gZGVzY2VuZGluZyBvcmRlciBvZiBkZWdyZWUgY2VudHJhbGl0eS4gDQoNCmBgYHtyfQ0KYXJyYW5nZShub2RlcywgZGVzYyhkQ2VudCkpDQpgYGANCg0KUHJpbnQgdGhlIGNvbnRlbnRzIG9mIGBub2Rlc2AgaW4gZGVzY2VuZGluZyBvcmRlciBvZiBiZXR3ZWVubmVzcyBjZW50cmFsaXR5LiANCg0KYGBge3J9DQphcnJhbmdlKG5vZGVzLCBkZXNjKGJDZW50KSkNCmBgYA0KDQpQcmludCB0aGUgY29udGVudHMgb2YgYG5vZGVzYCBpbiBkZXNjZW5kaW5nIG9yZGVyIG9mIGNsb3NlbmVzcyBjZW50cmFsaXR5LiANCg0KYGBge3J9DQphcnJhbmdlKG5vZGVzLCBkZXNjKGNDZW50KSkNCmBgYA0KDQpMaXN0IGFueSBuYW1lcyBvZiBhbnkgZG9scGhpbnMgdGhhdCBhcHBlYXIgaW4gdGhlIHRvcCAxMCBmb3IgYWxsIHRocmVlIGNlbnRyYWxpdHkgbWVhc3VyZXMuIA0KDQoqKlNONCwgS3JpbmdlbCwgYW5kIEJlZXNjcmF0Y2guKioNCg0KDQojIyMgVmlzdWFsaXppbmcgQ2VudHJhbGl0eQ0KDQpJbiB0aGUgY2VsbCBiZWxvdywgY29tcGxldGUgdGhlIGZvbGxvd2luZyBzdGVwczoNCjEuIFNldCB0aGUgc2VlZCBlcXVhbCB0byAxLiANCjIuIENyZWF0ZSBhIGN1dCBvZiB0aGUgdmVjdG9yIGBkQ2AuIFNldCB0aGUgY3V0cyB0byByb3VnaGx5IGNvcnJlc3BvbmQgdG8gdGhlIHF1YXJ0aWxlcyBvZiB0aGUgZGVncmVlIGNlbnRyYWxpdHkgKHJlZmVyIHRvIHRoZSBzdW1tYXJ5IGFib3ZlKS4gU2V0IGBsYWJlbHMgPSBGQUxTRWAuIA0KMy4gQ3JlYXRlIGEgYFJDb2xvckJyZXdlcmAgcGFsZXR0ZSB3aXRoIDQgY29sb3JzLiANCjQuIFBsb3QgdGhlIGdyYXBoIHdpdGggdGhlIHNpemUgYW5kIGNvbG9yIG9mIHRoZSB2ZXJ0aWNlcyBlYWNoIGRldGVybWluZWQgYnkgZGVncmVlIGNlbnRyYWxpdHkuIFVzZSB0aGUgY3V0IGFuZCBwYWxldHRlIHlvdSBkZWZpbmVkIHRvIHNldCB0aGUgY29sb3IuIFRoZW4gc2V0IHRoZSBzaXplIHRvIGJlIGVxdWFsIHRvIDIgKyB0aGUgdmFsdWUgb2YgdGhlIGN1dC4gRG8gbm90IGRpc3BsYXkgdGhlIGxhYmVscy4gDQoNCg0KYGBge3IsIGZpZy53aWR0aCA9IDIwfQ0Kc2V0LnNlZWQoMSkNCmN0IDwtIGN1dChkQywgYygtMSwgMywgNSwgNywgMTMpLCBsYWJlbHM9RkFMU0UpDQpteVBhbCA8LSBicmV3ZXIucGFsKDQsICJSZFB1IikNCnBsb3QoZywgdmVydGV4LmxhYmVsID0gTkEsIHZlcnRleC5zaXplID0gMiArIGN0LCB2ZXJ0ZXguY29sb3IgPSBteVBhbFtjdF0pDQpgYGANCg0KSW4gdGhlIGNlbGwgYmVsb3csIGNvbXBsZXRlIHRoZSBmb2xsb3dpbmcgc3RlcHM6DQoxLiBTZXQgdGhlIHNlZWQgZXF1YWwgdG8gMS4gDQoyLiBDcmVhdGUgYSBjdXQgb2YgdGhlIHZlY3RvciBgYkNgLiBVc2UgdGhlIGZvbGxvd2luZyBjdXQgbGV2ZWxzOiAtMSwgMjUsIDc1LCAxNTAsIDQ1MCwgYW5kIDUwMC4gU2V0IGBsYWJlbHMgPSBGQUxTRWAuIA0KMy4gQ3JlYXRlIGEgYFJDb2xvckJyZXdlcmAgcGFsZXR0ZSB3aXRoIDUgY29sb3JzLiANCjQuIFBsb3QgdGhlIGdyYXBoIHdpdGggdGhlIHNpemUgYW5kIGNvbG9yIG9mIHRoZSB2ZXJ0aWNlcyBlYWNoIGRldGVybWluZWQgYnkgYmV0d2Vlbm5lc3MgY2VudHJhbGl0eS4gVXNlIHRoZSBjdXQgYW5kIHBhbGV0dGUgeW91IGRlZmluZWQgdG8gc2V0IHRoZSBjb2xvci4gVGhlbiBzZXQgdGhlIHNpemUgdG8gYmUgZXF1YWwgdG8gMiArIHRoZSB2YWx1ZSBvZiB0aGUgY3V0LiBEbyBub3QgZGlzcGxheSB0aGUgbGFiZWxzLiANCg0KYGBge3IsIGZpZy53aWR0aCA9IDIwfQ0Kc2V0LnNlZWQoMSkNCmN0IDwtIGN1dChiQywgYygtMSwgMjUsIDc1LCAxNTAsIDQ1MCwgNTAwKSwgbGFiZWxzPUZBTFNFKQ0KbXlQYWwgPC0gYnJld2VyLnBhbCg1LCAiUmRQdSIpDQpwbG90KGcsIHZlcnRleC5sYWJlbCA9IE5BLCB2ZXJ0ZXguc2l6ZSA9IDIgKyBjdCwgdmVydGV4LmNvbG9yID0gbXlQYWxbY3RdKQ0KYGBgDQoNCiMjIyBDb21tdW5pdHkgRGV0ZWN0aW9uDQoNCkluIHRoZSBjZWxsIGJlbG93LCBjb21wbGV0ZSB0aGUgZm9sbG93aW5nIHN0ZXBzOg0KDQoxLiBTZXQgdGhlIHNlZWQgZXF1YWwgdG8gMS4NCjIuIFVzZSBgY2x1c3Rlcl9lZGdlX2JldHdlZW5uZXNzKClgIHRvIGRldGVjdCBjb21tdW5pdGllcyB3aXRoaW4gdGhlIGdyYXBoLiANCjMuIFBsb3QgdGhlIGdyYXBoLCBkaXNwbGF5aW5nIHRoZSBjb21tdW5pdGllcyB0aGF0IGhhdmUgYmVlbiBkZXRlY3RlZC4gRG8gbm90IGRpc3BsYXkgdGhlIHZlcnRleCBsYWJlbHMuIA0KDQoNCg0KYGBge3IsIGZpZy53aWR0aCA9IDIwfQ0Kc2V0LnNlZWQoMSkNCmNlYiA8LSBjbHVzdGVyX2VkZ2VfYmV0d2Vlbm5lc3MoZykNCnBsb3QoY2ViLCBnLCB2ZXJ0ZXgubGFiZWwgPSBOQSwgdmVydGV4LnNpemUgPSA0KQ0KYGBgDQoNCkluIHRoZSBjZWxsIGJlbG93LCBjb21wbGV0ZSB0aGUgZm9sbG93aW5nIHN0ZXBzOg0KDQoxLiBDcmVhdGUgYSBkYXRhIGZyYW1lIGNhbGxlZCBgY29tbURGYCB3aXRoIHR3byBjb2x1bW5zOiBOb2RlIGFuZCBDb21tLiBUaGUgQ29tbSBjb2x1bW4gc2hvdWxkIGluZGljYXRlIHRoZSBjb21tdW5pdHkgdG8gZWFjaCBlYWNoIGRvbHBoaW4gaGFzIGJlZW4gYXNzaWduZWQuIA0KMi4gQWRkIHRoZSBjb21tdW5pdHkgaW5mb3JtYXRpb24gdG8gdGhlIGBub2Rlc2AgZGF0YSBmcmFtZS4gDQozLiBQcmludCBhIHRhYmxlIHdpdGggdHdvIGNvbHVtbnM6IENvbW0gYW5kIG4uIFRoZSBDb21tIGNvbHVtbiBzaG91bGQgbGlzdCB0aGUgbGFiZWxzIGZvciB0aGUgY29tbXVuaXRpZXMgdGhhdCBoYXZlIGJlZW4gZGV0ZWN0ZWQuIFRoZSBuIGNvbHVtbiBzaG91bGQgbGlzdCB0aGUgbnVtYmVyIG9mIGRvbHBoaW5zIHRoYXQgaGF2ZSBiZWVuIGFzc2lnbmVkIHRvIGVhY2ggY29tbXVuaXR5LiBUaGUgdGFibGUgc2hvdWxkIGJlIHNvcnRlZCBpbiBkZXNjZW5kaW5nIG9yZGVyIGJ5IG4uIA0KDQpgYGB7cn0NCm1lbSA8LSBtZW1iZXJzaGlwKGNlYikNCmNvbW1ERiA8LSBkYXRhLmZyYW1lKE5vZGUgPSBuYW1lcyhtZW0pLCBDb21tID0gYXMudmVjdG9yKHVubmFtZShtZW0pKSwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0KDQpub2RlcyA8LSBsZWZ0X2pvaW4obm9kZXMsIGNvbW1ERiwgYnk9J05vZGUnKQ0KDQpub2RlcyAlPiUgZ3JvdXBfYnkoQ29tbSkgJT4lIGNvdW50KCkgJT4lIGFycmFuZ2UoZGVzYyhuKSkNCg0KYGBgDQoNClVzZSBgaW5kdWNlZC5zdWJncmFwaCgpYCB0byBjcmVhdGUgYSBzdWJncmFwaCBjb25zaXN0aW5nIG9mIG5vZGVzIGFzc29jaWF0ZWQgd2l0aCBkb2xwaGlucyB0aGF0IGhhdmUgYmVlbiBhc3NpZ25lZCB0byB0aGUgbGFyZ2VzdCBvZiB0aGUgZGV0ZWN0ZWQgY29tbXVuaXRpZXMuIE5hbWUgdGhlIGdyYXBoIGBnMmAuIA0KDQpgYGB7cn0NCmNvbW0yIDwtIGZpbHRlcihub2RlcywgQ29tbSA9PSAyKQ0KZzIgPC0gaW5kdWNlZC5zdWJncmFwaChnLCB2aWRzID0gY29tbTIkTm9kZSkgDQpgYGANCg0KUnVuIHRoZSBjZWxsIGJlbG93IHRvIHBsb3QgdGhlIGdyYXBoIGZvciB0aGUgbGFyZ2VzdCBjb21tdW5pdHkgd2l0aCBlYWNoIG5vZGUgbGFiZWxlZCBieSB0aGUgbmFtZSBvZiB0aGUgYXNzb2NpYXRlZCBkb2xwaGluLiANCg0KDQpgYGB7ciwgZmlnLndpZHRoID0gMjB9DQpzZWw8LSBWKGcyKSRuYW1lDQoNCnNlbERGIDwtIGRhdGEuZnJhbWUoTm9kZSA9IHNlbCwgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQ0Kc2VsREYgPC0gbGVmdF9qb2luKHNlbERGLCBub2RlcywgYnk9J05vZGUnKQ0KDQpzZXQuc2VlZCgxKQ0KcGxvdChnMiwgdmVydGV4LmxhYmVsID0gc2VsREYkTmFtZSwgdmVydGV4LmxhYmVsLmNleCA9IDEuNSkNCg0KYGBgDQoNCiMjIyBDbGlxdWUgRGV0ZWN0aW9uDQoNCkZpbmQgdGhlIGxhcmdlc3QgY2xpcXVlcyBpbiB0aGUgbmV0d29yay4gUHJpbnQgYSBsaXN0IG9mIG5vZGVzIGNvbnRhaW5lZCBpbiBlYWNoIGNsaXF1ZS4gDQoNCmBgYHtyfQ0KbGMgPC0gbGFyZ2VzdF9jbGlxdWVzKGcpDQpsYw0KYGBgDQoNClByaW50IHRoZSBuYW1lcyBvZiB0aGUgZG9scGhpbnMgY29udGFpbmVkIGluIGVhY2ggb2YgdGhlIGxhcmdlc3QgY2xpcXVlcy4gWW91IHdpbGwgbmVlZCBhIHNlcGFyYXRlIGNvZGUgY2h1bmsgZm9yIGVhY2ggY2xpcXVlLiANCg0KYGBge3J9DQpjMSA8LSBsY1tbMV1dJG5hbWUNCmZpbHRlcihub2RlcywgTm9kZSAlaW4lIGMxKQ0KYGBgDQoNCmBgYHtyfQ0KYzIgPC0gbGNbWzJdXSRuYW1lDQpmaWx0ZXIobm9kZXMsIE5vZGUgJWluJSBjMikNCmBgYA0KDQpgYGB7cn0NCmMzIDwtIGxjW1szXV0kbmFtZQ0KZmlsdGVyKG5vZGVzLCBOb2RlICVpbiUgYzMpDQpgYGANCg0KQSBsYXJnZXIgY2xpcXVlIGNvdWxkIGJlIGNyZWF0ZWQgYnkgYWRkaW5nIGEgc2luZ2xlIGVkZ2UgYmV0d2VlbiB0d28gZG9scGhpbnMuIFdoaWNoIHR3byBkb2xwaGlucyBhcmUgdGhleT8NCg0KKipNTjgzIGFuZCBNTjEwNSoqLiANCg0KDQoNCg==