## NULL

This website converted the following original .R scripts into .rmd files.

  • Rscript01DataFormat.R
  • RScriptSNADescriptives.R
  • Rscript02SienaVariableFormat.R
  • Rscript03SienaRunModel.R
  • Rscript04SienaBehaviour.R

Please visit GitHub for the latest .R files.


Data

All files (data, scripts, etc.) can also be found on Github


Contact

Specific questions with respect to the .rmd files can be addressed to: Jochem Tolsma.

For questions on RSiena please visit the designated GitHub page.


to do: convert to rmd

################################################################################ ### ----
################################################################################ Rscript01DataFormat.R:
################################################################################ a script for the
################################################################################ introduction to
################################################################################ RSiena ---- ###
################################################################################ ### version:
################################################################################ September 8, 2020
################################################################################ ###
################################################################################ Rscript01DataFormat.R
################################################################################ is followed by
################################################################################ RScriptSNADescriptives.R,
################################################################################ code for
################################################################################ descriptive
################################################################################ analysis of the
################################################################################ data, and
################################################################################ Rscript02SienaVariableFormat.R,
################################################################################ which formats data
################################################################################ and specifies the
################################################################################ model, and
################################################################################ Rscript03SienaRunModel.R,
################################################################################ which runs the
################################################################################ model and
################################################################################ estimates
################################################################################ parameters
################################################################################ Rscript04SienaBehaviour.R,
################################################################################ which illustrates
################################################################################ an example of
################################################################################ analysing the
################################################################################ coevolution of
################################################################################ networks and
################################################################################ behaviour The
################################################################################ entire model
################################################################################ fitting is
################################################################################ summarised at the
################################################################################ end of
################################################################################ RscriptSienaRunModel.R
################################################################################ (without comments)
################################################################################ This is an R
################################################################################ script for getting
################################################################################ started with
################################################################################ RSiena, written by
################################################################################ Tom Snijders, with
################################################################################ earlier
################################################################################ contributions from
################################################################################ Robin Gauthier,
################################################################################ Ruth Ripley, Johan
################################################################################ Koskinen, Paulina
################################################################################ Preciado, and
################################################################################ Zsofia Boda, with
################################################################################ some examples
################################################################################ borrowed from
################################################################################ Christian
################################################################################ Steglich.  Lines
################################################################################ starting with #
################################################################################ are not processed
################################################################################ by R but treated
################################################################################ as comments.  The
################################################################################ script has a lot
################################################################################ of explanation of
################################################################################ R possibilities
################################################################################ that will be
################################################################################ familiar for
################################################################################ readers well
################################################################################ acquainted with R,
################################################################################ and can be skipped
################################################################################ by them.  There
################################################################################ are various really
################################################################################ easy online
################################################################################ introductions to
################################################################################ R. See, for
################################################################################ example
################################################################################ http://www.statmethods.net/
################################################################################ http://www.burns-stat.com/pages/Tutor/hints_R_begin.html
################################################################################ http://data.princeton.edu/R/gettingStarted.html
################################################################################ https://stats.idre.ucla.edu/r/
################################################################################ You can go to any
################################################################################ of these sites to
################################################################################ learn the basics
################################################################################ of R or refresh
################################################################################ your knowledge.
################################################################################ There is a lot of
################################################################################ documentation
################################################################################ available at
################################################################################ https://www.r-project.org/other-docs.html
################################################################################ including some
################################################################################ short
################################################################################ introductions,
################################################################################ handy reference
################################################################################ cards, and
################################################################################ introductions in
################################################################################ many languages
################################################################################ besides English.
################################################################################ Some general
################################################################################ points to note: R
################################################################################ is case-sensitive.
################################################################################ Be aware of
################################################################################ capitalization!
################################################################################ The left-arrow
################################################################################ '<-' is very
################################################################################ frequently used:
################################################################################ it denotes an
################################################################################ assignment, 'a <-
################################################################################ b' meaning that
################################################################################ object a gets the
################################################################################ value b.  Often b
################################################################################ is a complicated
################################################################################ expression that
################################################################################ has to be
################################################################################ evaluated by R,
################################################################################ and computes a
################################################################################ result that then
################################################################################ is stored as the
################################################################################ object a.  Help
################################################################################ within R can be
################################################################################ called by typing a
################################################################################ question mark and
################################################################################ the name of the
################################################################################ function you need
################################################################################ help for. For
################################################################################ example ?library
################################################################################ will bring up a
################################################################################ file titled
################################################################################ 'loading/attaching
################################################################################ and listing of
################################################################################ packages'.
################################################################################ Comments are made
################################################################################ at the end of
################################################################################ commands after #,
################################################################################ or in lines
################################################################################ starting with #
################################################################################ telling R to
################################################################################ ignore everything
################################################################################ beyond it.  That
################################################################################ is why everything
################################################################################ up to now in this
################################################################################ file is on lines
################################################################################ starting with #.
################################################################################ This session will
################################################################################ be using the s50
################################################################################ data which are
################################################################################ available in
################################################################################ RSiena.  You can
################################################################################ also get them from
################################################################################ http://www.stats.ox.ac.uk/~snijders/siena/siena_datasets.htm
################################################################################ Any command in R
################################################################################ is a function, and
################################################################################ ends by
################################################################################ parentheses that
################################################################################ enclose the
################################################################################ arguments of the
################################################################################ function, or
################################################################################ enclose nothing if
################################################################################ no argument is
################################################################################ needed, such as
################################################################################ for the function
################################################################################ q() In general the
################################################################################ command syntax for
################################################################################ calling R's
################################################################################ functions is
################################################################################ function(x) where
################################################################################ function is an
################################################################################ available function
################################################################################ and x the name of
################################################################################ the object
################################################################################ operated on.  -
################################################################################ CALLING THE DATA
################################################################################ AND PRELIMINARY
################################################################################ MANIPULATIONS -
################################################################################ ########

# The library command loads the packages needed during the session.

library(RSiena)

# Some additional packages are used by RSiena, the so-called required packages; these will be
# loaded automatically.

# You need to have INSTALLED all of them.

`?`(install.packages)

# Or click on the tab 'Packages', 'Install package(s)', then select a CRAN mirror close to you
# (e.g. Bristol if you are in the UK) and finally select from the list the package you wish to
# install.

# Where are you?

getwd()
#> [1] "C:/Users/Jochem/Documents/GitHub/RSiena-scripts"
# By something like setwd('C:/SienaTest') you can set the directory but note the quotes and forward
# slash.  It is also possible to set the directory using the menus if you have them.  On a windows
# machine, you can predetermine the working directory in the <Properties> of the shortcut to R;
# these are accessible by right-clicking the shortcut.

# If you want to set the working directory to for example 'C:\Documents and Settings\johan\My
# Documents\RSiena_course' simply copy and paste from windows explorer or type setwd('C:/Documents
# and Settings/johan/My Documents/RSiena_course') or setwd('C:\\Documents and Settings\\johan\\My
# Documents\\RSiena_course') but note that '\' has to be changed; both '/' and '\\' work!!!

# What is in this directory?

list.files()
#>  [1] "_site.yml"                      "docs"                          
#>  [3] "footer.html"                    "index.html"                    
#>  [5] "index.rmd"                      "index_cache"                   
#>  [7] "README.md"                      "references.bib"                
#>  [9] "rscript00.html"                 "rscript00.rmd"                 
#> [11] "rscript00_cache"                "rscript00_files"               
#> [13] "rscript01.rmd"                  "rscript01_cache"               
#> [15] "Rscript01DataFormat.R"          "rscript02.rmd"                 
#> [17] "rscript02_cache"                "Rscript02SienaVariableFormat.R"
#> [19] "rscript03.rmd"                  "rscript03_cache"               
#> [21] "Rscript03SienaRunModel.R"       "rscript04.rmd"                 
#> [23] "rscript04_cache"                "Rscript04SienaBehaviour.R"     
#> [25] "RSiena-scripts.Rproj"           "RSienaSNADescriptives.R"       
#> [27] "s50_3.txt"                      "s50_3_init.txt"                
#> [29] "site_libs"
# What is available in RSiena?

`?`(RSiena)

# (these are .htlm HELP PAGES)

# At the bottom of this page, when you click on 'Index', a list of all the available functions is
# shown in your browser.  The same list is shown in the graphical user interface for R by
# requesting

library(help = RSiena)

# An extensive manual is at the Siena website at
# http://www.stats.ox.ac.uk/~snijders/siena/RSiena_Manual.pdf ; it is updated frequently.

# Each data is named (for example below we name it friend.data.w1) so that we can call it as an
# object within R.  If you read an object straight into R, it will treat it as a dataset, or in R
# terminology a 'data frame'.  Here this is not what we want, therefore on reading we will
# immediately convert it to a matrix.  R will read in many data formats, the command to read them
# is read.table.
`?`(read.table)
# In the help page for read.table, look at the section 'Value', which is there in every help page:
# it indicates the class of the object that is produced by the function.  For read.table, the value
# is a data frame; below we see what this is.  If we wished to read a .csv file we would have used
# the read.csv command.  The pathnames must have forward slashes, or double backslashes.  If single
# backslashes are used, one of the error messages will be: 1: '\R' is an unrecognized escape in a
# character string

#-----------------------------------------------------------------------------

# Quick start (Data assignment).  Please make sure the s50 data set is in your working directory.
# The data set is on the Siena website ('Data sets' tab) and must be unzipped in your working
# directory.

# friend.data.w1 <- as.matrix(read.table('s50-network1.dat')) friend.data.w2 <-
# as.matrix(read.table('s50-network2.dat')) friend.data.w3 <-
# as.matrix(read.table('s50-network3.dat')) drink <- as.matrix(read.table('s50-alcohol.dat')) smoke
# <- as.matrix(read.table('s50-smoke.dat'))

# To make this script self-contained, you may instead run the commands:
library(RSiena)
friend.data.w1 <- s501
friend.data.w2 <- s502
friend.data.w3 <- s503
drink <- s50a
smoke <- s50s
# because s501 etc. are internal data objects of RSiena.

# Explanation of data structures and formats below

################# - DIFFERENT DATA FORMATS - ################################### The assignments
################# here involve reading in data to a 'data frame' data <- read.table('data.dat')
################# reads your text file into a 'data frame'; check the class of the object 'data' >
################# class(data) [1] 'data.frame' If your data is not a '.dat' file, alternative
################# import methods are ----- '.csv'
################# --------------------------------------------------------------- data <-
################# read.table('c:/data.csv', header=TRUE, sep=',', row.names='iden') ---- '.csv'
################# ---------------------------------------------------------------- data <-
################# read.csv('data.csv',header=T) look at ?read.csv and ?read.table to understand
################# these function calls ---- '.spss'
################# --------------------------------------------------------------- library(foreign)
################# data <- read.spss('c:/data.spss') ---- '.dta'
################# ---------------------------------------------------------------- library(foreign)
################# data <- read.dta('c:/data.dta')

################# - FROM DATA FRAME TO MATRIX - ################################ ---- Data frame
################# ------------------------------------------------------------ The data frame is
################# like a spreadsheet of cases by variables, where the variables are the columns,
################# and these have the names names( data ) a spreadsheet view of a data frame is
################# given by the fix() command fix( data ) All changes you make in this spreadsheet
################# will be saved automatically, so beware.  As an example create two vectors:
height <- c(120, 150, 180, 200, 190, 177, 170, 125, 141, 157)
weight <- c(11, 14, 17, 18, 17, 18, 11, 12, 10, 15)
### The function c() combines its argument into a vector (or into a list, but we are not concerned
### with that possibility now.).  These two vectors can be collected as variables in a data frame
mydata <- data.frame(height, weight)
### and look at the results
mydata
#>    height weight
#> 1     120     11
#> 2     150     14
#> 3     180     17
#> 4     200     18
#> 5     190     17
#> 6     177     18
#> 7     170     11
#> 8     125     12
#> 9     141     10
#> 10    157     15
### The columns of a data frame may be extracted using a '$' sign and their names.  For example:
names(mydata)
#> [1] "height" "weight"
mydata$height
#>  [1] 120 150 180 200 190 177 170 125 141 157
### Or by '[]' and column number, e.g.
mydata[1]
#>    height
#> 1     120
#> 2     150
#> 3     180
#> 4     200
#> 5     190
#> 6     177
#> 7     170
#> 8     125
#> 9     141
#> 10    157
mydata[, 1]
#>  [1] 120 150 180 200 190 177 170 125 141 157
mydata[1, ]
#>   height weight
#> 1    120     11
### If you wish to see the structure of an object, such as mydata, then request
str(mydata)
#> 'data.frame':    10 obs. of  2 variables:
#>  $ height: num  120 150 180 200 190 177 170 125 141 157
#>  $ weight: num  11 14 17 18 17 18 11 12 10 15
### Objects often have attributes:
attributes(mydata)
#> $names
#> [1] "height" "weight"
#> 
#> $class
#> [1] "data.frame"
#> 
#> $row.names
#>  [1]  1  2  3  4  5  6  7  8  9 10
### ---- Matrix ---------------------------------------------------------------- A 'matrix' is a
### numeric object ordered like a matrix with dimensions ( dim() ) given by the number of rows and
### columns, e.g.
dim(friend.data.w1)
#> [1] 50 50
### If you wish to play around with a copy of the matrix, e.g. having the name 'mydata', you can
### make the copy by the command
mydata <- friend.data.w1
### The earlier object that we created with the name 'mydata' now has been lost.  Elements if
### matrices can be accessed by using square brackets.  For example, the element of 'mydata' in row
### 2 and column 3 is given by
mydata[2, 3]
#> [1] 0
### the first three rows of a matrix called mydata are given by
mydata[1:3, ]
#>   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 V21 V22 V23 V24 V25 V26
#> 1  0  0  0  0  0  0  0  0  0   0   1   0   0   1   0   0   0   0   0   0   0   0   0   0   0   0
#> 2  0  0  0  0  0  0  1  0  0   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
#> 3  0  0  0  1  0  0  0  0  1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
#>   V27 V28 V29 V30 V31 V32 V33 V34 V35 V36 V37 V38 V39 V40 V41 V42 V43 V44 V45 V46 V47 V48 V49 V50
#> 1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
#> 2   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
#> 3   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
### columns 2, 5, and 6 are given by
mydata[, c(2, 5, 6)]
#>    V2 V5 V6
#> 1   0  0  0
#> 2   0  0  0
#> 3   0  0  0
#> 4   0  0  0
#> 5   0  0  0
#> 6   0  0  0
#> 7   1  0  0
#> 8   0  0  1
#> 9   0  0  0
#> 10  0  0  0
#> 11  1  0  0
#> 12  0  0  0
#> 13  0  0  0
#> 14  0  0  0
#> 15  0  0  0
#> 16  0  0  0
#> 17  0  0  0
#> 18  0  0  0
#> 19  0  0  0
#> 20  0  0  0
#> 21  0  0  0
#> 22  0  0  0
#> 23  0  0  0
#> 24  0  0  0
#> 25  0  0  0
#> 26  0  0  0
#> 27  0  0  0
#> 28  0  0  0
#> 29  0  0  0
#> 30  0  0  0
#> 31  0  0  0
#> 32  0  1  0
#> 33  0  0  0
#> 34  0  0  0
#> 35  0  0  0
#> 36  0  0  0
#> 37  0  0  0
#> 38  0  0  0
#> 39  0  0  0
#> 40  0  0  0
#> 41  0  0  0
#> 42  0  0  0
#> 43  0  0  0
#> 44  0  0  0
#> 45  0  0  0
#> 46  0  0  0
#> 47  0  0  0
#> 48  0  0  0
#> 49  0  0  0
#> 50  0  0  0
### Indeed there are a lot of zeros - networks tend to be sparse.

### ---- Converting data frame to matrix --------------------------------------- Most classes can
### be converted to other classes through 'as.typeofclass ()', e.g., if 'mydata' would be an object
### with a matrix-like structure, then it could be converted to the class 'matrix' by the command
mydata <- as.matrix(mydata)

################################################################################


################## - EXAMPLE FOR ARC LIST - #################################### From the Siena
################## website you can download the data set arclistdata.dat.  The function read.table
################## can be used with the internet location:
ArcList <- read.table("https://www.stats.ox.ac.uk/~snijders/siena/arclistdata.dat", header = FALSE)
### Note the capitalization.  Now ArcList is a data.frame (we saw this above in the help page for
### read.table).  What are its dimensions?
dim(ArcList)
#> [1] 351   4
### You can get an impression of it by looking at the start of the object:
head(ArcList)
#>   V1 V2 V3 V4
#> 1 14  1  1  1
#> 2  7  2  1  1
#> 3 11  2  1  1
#> 4  4  3  1  1
#> 5  9  3  1  1
#> 6  3  4  1  1
### This is a data file in arclist format, with columns: sender id, receiver id, value of tie,
### wave.  Add names to the columns:
names(ArcList) <- c("sid", "recid", "bff", "wid")
### and again request
head(ArcList)
#>   sid recid bff wid
#> 1  14     1   1   1
#> 2   7     2   1   1
#> 3  11     2   1   1
#> 4   4     3   1   1
#> 5   9     3   1   1
#> 6   3     4   1   1
### The bff ('best friend') variable does not have much variability:
table(ArcList$bff)
#> 
#>   1 
#> 351
### This tells us that non-ties are not included (they would have the value 0), and that there are
### no tie values other than 1.  It may be nice to order the rows by sender, then by receiver, then
### by wave.  The tedious way to do this is
ArcList <- ArcList[order(ArcList$sid, ArcList$recid, ArcList$wid), ]
### To understand this, you may look at the help page for function order() The rows of Arclist are
### ordered first by ArcList$sid, then by ArcList$recid, and then by ArcList$wid; these reordered
### rows then are put into the object ArcList, thus overwriting the earlier contents of this
### object.  This way is tedious because it is repeated all the time that the names sid, recid, wid
### refer to the ArcList object.  The less tedious way uses the function 'with'.  The with(a, b)
### function tells R that b must be calculated, while the otherwise unknown names refer to data set
### a:
ArcList <- with(ArcList, ArcList[order(sid, recid, wid), ])
### An arc list does not give information about the number of nodes, because isolates are not
### recorded.  The set of non-isolates is
union(unique(ArcList$sid), unique(ArcList$recid))
#>  [1]  1  2  3  4  5  6  7  8  9 10 11 12 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#> [33] 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
### and, given that we have the information that there are 50 nodes labeled 1 to 50, the isolates
### are the following two nodes:
setdiff(1:50, union(unique(ArcList$sid), unique(ArcList$recid)))
#> [1] 13 20
### Now suppose we want to create a separate set of records for each wave.  Select by wave:

SAff.1 <- with(ArcList, ArcList[wid == 1, ])  #extracts edges in wave 1
SAff.2 <- with(ArcList, ArcList[wid == 2, ])  #extracts edges in wave 2
SAff.3 <- with(ArcList, ArcList[wid == 3, ])  #extracts edges in wave 3

### This can be arranged more efficiently as
SAff <- lapply(1:3, function(m) {
    with(ArcList, ArcList[wid == m, ])
})
### with the correspondence that SAff.1 is SAff[[1]], etc.

### For transforming an adjacency matrix, e.g., friend.data.w1, into an arclist, create indicator
### matrix of the non-zero entries:
ones <- !friend.data.w1 %in% 0
### create empty edge list of desired length
edges <- matrix(0, sum(ones), 3)
### fill the columns of the edge list
edges[, 1] <- row(friend.data.w1)[ones]
edges[, 2] <- col(friend.data.w1)[ones]
edges[, 3] <- friend.data.w1[ones]
### if desired, order edge list by senders and then receivers
edges <- edges[order(edges[, 1], edges[, 2]), ]
### What did we make:
edges
#>        [,1] [,2] [,3]
#>   [1,]    1   11    1
#>   [2,]    1   14    1
#>   [3,]    2    7    1
#>   [4,]    2   11    1
#>   [5,]    3    4    1
#>   [6,]    3    9    1
#>   [7,]    4    3    1
#>   [8,]    4    9    1
#>   [9,]    5   32    1
#>  [10,]    6    8    1
#>  [11,]    7    2    1
#>  [12,]    7   42    1
#>  [13,]    7   44    1
#>  [14,]    8    6    1
#>  [15,]    9    3    1
#>  [16,]    9    4    1
#>  [17,]   10   11    1
#>  [18,]   10   15    1
#>  [19,]   10   33    1
#>  [20,]   11    2    1
#>  [21,]   11   15    1
#>  [22,]   11   16    1
#>  [23,]   12    7    1
#>  [24,]   12   42    1
#>  [25,]   12   44    1
#>  [26,]   14    1    1
#>  [27,]   14   10    1
#>  [28,]   14   11    1
#>  [29,]   15   10    1
#>  [30,]   15   11    1
#>  [31,]   15   16    1
#>  [32,]   16   11    1
#>  [33,]   16   15    1
#>  [34,]   17   18    1
#>  [35,]   17   19    1
#>  [36,]   17   21    1
#>  [37,]   17   22    1
#>  [38,]   17   24    1
#>  [39,]   18   19    1
#>  [40,]   18   35    1
#>  [41,]   19   11    1
#>  [42,]   19   24    1
#>  [43,]   19   26    1
#>  [44,]   19   30    1
#>  [45,]   21   22    1
#>  [46,]   22   17    1
#>  [47,]   22   21    1
#>  [48,]   22   31    1
#>  [49,]   22   34    1
#>  [50,]   23   24    1
#>  [51,]   24   17    1
#>  [52,]   24   19    1
#>  [53,]   24   21    1
#>  [54,]   24   22    1
#>  [55,]   24   23    1
#>  [56,]   25   22    1
#>  [57,]   25   31    1
#>  [58,]   25   32    1
#>  [59,]   26    7    1
#>  [60,]   26   29    1
#>  [61,]   26   44    1
#>  [62,]   27   28    1
#>  [63,]   27   29    1
#>  [64,]   27   30    1
#>  [65,]   28   27    1
#>  [66,]   29   26    1
#>  [67,]   29   30    1
#>  [68,]   29   33    1
#>  [69,]   30   11    1
#>  [70,]   30   26    1
#>  [71,]   30   29    1
#>  [72,]   30   33    1
#>  [73,]   31   21    1
#>  [74,]   31   25    1
#>  [75,]   31   32    1
#>  [76,]   32    5    1
#>  [77,]   32   21    1
#>  [78,]   32   31    1
#>  [79,]   32   37    1
#>  [80,]   33   10    1
#>  [81,]   33   30    1
#>  [82,]   34   31    1
#>  [83,]   34   37    1
#>  [84,]   35   18    1
#>  [85,]   36   38    1
#>  [86,]   36   41    1
#>  [87,]   37   31    1
#>  [88,]   37   32    1
#>  [89,]   37   34    1
#>  [90,]   38   36    1
#>  [91,]   38   41    1
#>  [92,]   39   43    1
#>  [93,]   40   45    1
#>  [94,]   40   46    1
#>  [95,]   40   47    1
#>  [96,]   41   36    1
#>  [97,]   41   38    1
#>  [98,]   42    7    1
#>  [99,]   42   44    1
#> [100,]   43   22    1
#> [101,]   43   39    1
#> [102,]   44    7    1
#> [103,]   44   42    1
#> [104,]   45   40    1
#> [105,]   45   46    1
#> [106,]   45   47    1
#> [107,]   46   40    1
#> [108,]   46   45    1
#> [109,]   46   49    1
#> [110,]   48   46    1
#> [111,]   48   49    1
#> [112,]   49   46    1
#> [113,]   49   48    1
### For transforming an arclist into a matrix, first remove the fourth column indicating the wave,
### so that we are left with sender, receiver and value of the tie, and transform it into matrix
### format (at first it is a data.frame)
SAff.1.copy <- SAff.1[, 1:3]
SAff.1.copy <- as.matrix(SAff.1.copy)
### create empty adjacency matrix
adj <- matrix(0, 50, 50)
### put edge values in desired places
adj[SAff.1.copy[, 1:2]] <- SAff.1.copy[, 3]
### Now adj is the adjacency matrix.  Also see Section 4.1 of the Siena manual and the help page
### for sienaDependent.

################################################################################ - READING IN PAJEK
################################################################################ DATA -
################################################################################ #####################################
################################################################################ Skip this section
################################################################################ if handling Pajek
################################################################################ data is of no
################################################################################ concern to you.
################################################################################ If you have data
################################################################################ in Pajek format
################################################################################ you can use the
################################################################################ package 'network'
################################################################################ in order to
################################################################################ convert it to a
################################################################################ network object.
################################################################################ This example is
################################################################################ from ?read.paj
################################################################################ require( network )
################################################################################ par( mfrow = c( 2,
################################################################################ 2 ) ) test.net.1
################################################################################ <-
################################################################################ read.paj('http://vlado.fmf.uni-lj.si/pub/networks/data/GD/gd98/A98.net'
################################################################################ ) plot(
################################################################################ test.net.1,main =
################################################################################ test.net.1$gal$title
################################################################################ ) test.net.2 <-
################################################################################ read.paj('http://vlado.fmf.uni-lj.si/pub/networks/data/mix/USAir97.net'
################################################################################ ) plot(
################################################################################ test.net.2,main =
################################################################################ test.net.2$gal$title
################################################################################ )

# Before we work with the data, we want to be sure it is correct. A simple way to check that our
# data is a matrix is the command class()

class(friend.data.w1)
#> [1] "matrix" "array"
# to list the properties of an object attributes( friend.data.w1 ) (different classes have
# different attributes)

# To check that all the data has been read in, we can use the dim() command.  The adjacency matrix
# should have the same dimensions as the original data (here, 50 by 50).

dim(friend.data.w1)
#> [1] 50 50
dim(drink)
#> [1] 50  3
# To check the values are correct, including missing values, we can use the following commands to
# tabulate the variables.

table(friend.data.w1, useNA = "always")
#> friend.data.w1
#>    0    1 <NA> 
#> 2387  113    0
table(friend.data.w2, useNA = "always")
#> friend.data.w2
#>    0    1 <NA> 
#> 2384  116    0
table(friend.data.w3, useNA = "always")
#> friend.data.w3
#>    0    1 <NA> 
#> 2378  122    0
table(drink, useNA = "always")
#> drink
#>    1    2    3    4    5 <NA> 
#>    9   41   41   42   17    0
table(smoke, useNA = "always")
#> smoke
#>    1    2    3 <NA> 
#>  102   15   33    0
# NA is the R code for missing data (Not Available).  This data set happens to have no missings
# (see the data description on the Siena website).  If there are any missings, it is necessary to
# tell R about the missing data codes.  Let us do as if the missing codes for the friendship
# network were 6 and 9.  This leads to the following commands.  (For new R users: the c() function
# used here as 'c(6,9)' constructs a vector [c for column] consisting of the numbers 6 and 9.  This
# function is used a lot in basic R.)

friend.data.w1[friend.data.w1 %in% c(6, 9)] <- NA
friend.data.w2[friend.data.w2 %in% c(6, 9)] <- NA
friend.data.w3[friend.data.w3 %in% c(6, 9)] <- NA

# Commands for descriptive analysis are in the script: RscriptSNADescriptives.R

############## - SELECTING SUBSETS OF DATA - ###################################

# To select a subset of the data based on an actor variable, say, those who have the value 2 or 3
# on drinking at time 1 (the possibilities are endless, but hopefully this will serve as a pattern)

use <- drink[, 1] %in% c(2, 3)

# This creates a logical vector which is TRUE for the cases where the condition is satisfied. To
# view or check, display the vectors next to each other:

cbind(drink[, 1], use)
#>      use
#> 1  3   1
#> 2  2   1
#> 3  2   1
#> 4  2   1
#> 5  3   1
#> 6  4   0
#> 7  4   0
#> 8  4   0
#> 9  2   1
#> 10 4   0
#> 11 5   0
#> 12 5   0
#> 13 3   1
#> 14 3   1
#> 15 4   0
#> 16 4   0
#> 17 2   1
#> 18 4   0
#> 19 3   1
#> 20 2   1
#> 21 1   0
#> 22 3   1
#> 23 4   0
#> 24 3   1
#> 25 3   1
#> 26 4   0
#> 27 2   1
#> 28 2   1
#> 29 3   1
#> 30 1   0
#> 31 4   0
#> 32 4   0
#> 33 3   1
#> 34 2   1
#> 35 3   1
#> 36 4   0
#> 37 2   1
#> 38 3   1
#> 39 2   1
#> 40 1   0
#> 41 4   0
#> 42 4   0
#> 43 2   1
#> 44 5   0
#> 45 2   1
#> 46 2   1
#> 47 2   1
#> 48 2   1
#> 49 1   0
#> 50 1   0
data.frame(drink[, 1], use)
#>    drink...1.   use
#> 1           3  TRUE
#> 2           2  TRUE
#> 3           2  TRUE
#> 4           2  TRUE
#> 5           3  TRUE
#> 6           4 FALSE
#> 7           4 FALSE
#> 8           4 FALSE
#> 9           2  TRUE
#> 10          4 FALSE
#> 11          5 FALSE
#> 12          5 FALSE
#> 13          3  TRUE
#> 14          3  TRUE
#> 15          4 FALSE
#> 16          4 FALSE
#> 17          2  TRUE
#> 18          4 FALSE
#> 19          3  TRUE
#> 20          2  TRUE
#> 21          1 FALSE
#> 22          3  TRUE
#> 23          4 FALSE
#> 24          3  TRUE
#> 25          3  TRUE
#> 26          4 FALSE
#> 27          2  TRUE
#> 28          2  TRUE
#> 29          3  TRUE
#> 30          1 FALSE
#> 31          4 FALSE
#> 32          4 FALSE
#> 33          3  TRUE
#> 34          2  TRUE
#> 35          3  TRUE
#> 36          4 FALSE
#> 37          2  TRUE
#> 38          3  TRUE
#> 39          2  TRUE
#> 40          1 FALSE
#> 41          4 FALSE
#> 42          4 FALSE
#> 43          2  TRUE
#> 44          5 FALSE
#> 45          2  TRUE
#> 46          2  TRUE
#> 47          2  TRUE
#> 48          2  TRUE
#> 49          1 FALSE
#> 50          1 FALSE
# and the number of selected cases is displayed by

sum(use)
#> [1] 28
# or

table(use)
#> use
#> FALSE  TRUE 
#>    22    28
# Given this selection, submatrices can be formed in case the analyses are to be done for this
# subset only:

friend1.data.w1 <- friend.data.w1[use, use]
friend1.data.w2 <- friend.data.w2[use, use]
drink1 <- drink[use, ]

# A useful option in R that allows you to save your workspace:
save.image("WorkspaceRscript01.RData")
# Later you can load this in a new session by load('WorkspaceRscript01.RData')

# If next time you would like to continue from here, you will not need to open and run this script
# again, since you will be able to load this current state of your workspace. But packages will
# have to be attached again.

################################################################################ ---- PROCEED TO
################################################################################ RscriptSNADescriptives.R
################################################################################ FOR DESCRIPTIVE
################################################################################ ANALYSIS
################################################################################ ----------
LS0tDQp0aXRsZTogIkRhdGEgRm9ybWF0Ig0KYXV0aG9yOiAnW0pvY2hlbSBUb2xzbWFdKGh0dHBzOi8vd3d3LmpvY2hlbXRvbHNtYS5ubCkgLSBSYWRib3VkIFVuaXZlcnNpdHksIHRoZSBOZXRoZXJsYW5kcycNCmJpYmxpb2dyYXBoeTogcmVmZXJlbmNlcy5iaWINCmRhdGU6ICJMYXN0IGNvbXBpbGVkIG9uIGByIGZvcm1hdChTeXMudGltZSgpLCAnJUIsICVZJylgIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6ICB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQ0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KLS0tDQoNCmBgYHtyLCBnbG9iYWxzZXR0aW5ncywgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoa25pdHIpDQpvcHRzX2NodW5rJHNldCh0aWR5Lm9wdHM9bGlzdCh3aWR0aC5jdXRvZmY9MTAwKSx0aWR5PVRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLGNvbW1lbnQgPSAiIz4iLCBjYWNoZT1UUlVFLCBjbGFzcy5zb3VyY2U9YygidGVzdCIpLCBjbGFzcy5vdXRwdXQ9YygidGVzdDIiKSkNCm9wdGlvbnMod2lkdGggPSAxMDApDQpyZ2w6OnNldHVwS25pdHIoKQ0KDQoNCmNvbG9yaXplIDwtIGZ1bmN0aW9uKHgsIGNvbG9yKSB7DQogIGlmIChrbml0cjo6aXNfbGF0ZXhfb3V0cHV0KCkpIHsNCiAgICBzcHJpbnRmKCJcXHRleHRjb2xvcnslc317JXN9IiwgY29sb3IsIHgpDQogIH0gZWxzZSBpZiAoa25pdHI6OmlzX2h0bWxfb3V0cHV0KCkpIHsNCiAgICBzcHJpbnRmKCI8c3BhbiBzdHlsZT0nY29sb3I6ICVzOyc+JXM8L3NwYW4+IiwgY29sb3IsIA0KICAgICAgeCkNCiAgfSBlbHNlIHgNCn0NCg0KYGBgDQoNCmBgYHtyIGtsaXBweSwgZWNobz1GQUxTRSwgaW5jbHVkZT1UUlVFfQ0Ka2xpcHB5OjprbGlwcHkocG9zaXRpb24gPSBjKCd0b3AnLCAncmlnaHQnKSkNCiNrbGlwcHk6OmtsaXBweShjb2xvciA9ICdkYXJrcmVkJykNCiNrbGlwcHk6OmtsaXBweSh0b29sdGlwX21lc3NhZ2UgPSAnQ2xpY2sgdG8gY29weScsIHRvb2x0aXBfc3VjY2VzcyA9ICdEb25lJykNCmBgYA0KDQpgYGB7Y3NzLCBlY2hvPUZBTFNFfQ0KcHJlLnRlc3Qgew0KICBtYXgtaGVpZ2h0OiAzMDBweDsNCiAgb3ZlcmZsb3cteTogYXV0bzsNCiAgb3ZlcmZsb3cteDogYXV0bzsNCiAgbWFyZ2luOiAxMHB4Ow0KfQ0KDQpwcmUudGVzdDIgew0KICBtYXgtaGVpZ2h0OiAzMDBweDsNCiAgb3ZlcmZsb3cteTogYXV0bzsNCiAgb3ZlcmZsb3cteDogYXV0bzsNCiAgbWFyZ2luOiAxMHB4Ow0KICBiYWNrZ3JvdW5kLWNvbG9yOiB3aGl0ZQ0KfQ0KDQoNCmgxLCAuaDEsIGgyLCAuaDIsIGgzLCAuaDMgew0KICAgIG1hcmdpbi10b3A6IDI0cHg7DQp9DQoNCg0KYGBgDQoNCi0tLS0NCg0KVGhpcyB3ZWJzaXRlIGNvbnZlcnRlZCB0aGUgZm9sbG93aW5nIG9yaWdpbmFsIC5SIHNjcmlwdHMgaW50byAucm1kIGZpbGVzLiANCg0KLSBSc2NyaXB0MDFEYXRhRm9ybWF0LlIgIA0KLSBSU2NyaXB0U05BRGVzY3JpcHRpdmVzLlIgIA0KLSBSc2NyaXB0MDJTaWVuYVZhcmlhYmxlRm9ybWF0LlIgIA0KLSBSc2NyaXB0MDNTaWVuYVJ1bk1vZGVsLlIgIA0KLSBSc2NyaXB0MDRTaWVuYUJlaGF2aW91ci5SDQoNClBsZWFzZSB2aXNpdCBbR2l0SHViXShodHRwczovL2dpdGh1Yi5jb20vc25sYWItbmwvcnNpZW5hL3RyZWUvbWFpbi9pbnN0L3NjcmlwdHMpIGZvciB0aGUgbGF0ZXN0IC5SIGZpbGVzLiANCg0KLS0tLQ0KDQojIyBEYXRhDQpBbGwgZmlsZXMgKGRhdGEsIHNjcmlwdHMsIGV0Yy4pIGNhbiBhbHNvIGJlIGZvdW5kIG9uIFtHaXRodWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9Kb2NoZW1Ub2xzbWEvUnNpZW5hLXNjcmlwdHMpDQoNCi0tLS0NCg0KIyMgQ29udGFjdA0KU3BlY2lmaWMgcXVlc3Rpb25zIHdpdGggcmVzcGVjdCB0byB0aGUgLnJtZCBmaWxlcyBjYW4gYmUgYWRkcmVzc2VkIHRvOiBbSm9jaGVtIFRvbHNtYV0obWFpbHRvOmoudG9sc21hQHJ1Lm5sKS4gIA0KDQpGb3IgcXVlc3Rpb25zIG9uIFJTaWVuYSBwbGVhc2UgdmlzaXQgdGhlIGRlc2lnbmF0ZWQgW0dpdEh1Yl0oaHR0cHM6Ly9naXRodWIuY29tL3NubGFiLW5sL3JzaWVuYSkgcGFnZS4gDQoNCi0tLS0gIA0KDQoNCnRvIGRvOiBjb252ZXJ0IHRvIHJtZA0KDQpgYGB7cn0NCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIw0KIyMjIC0tLS0gUnNjcmlwdDAxRGF0YUZvcm1hdC5SOiBhIHNjcmlwdCBmb3IgdGhlIGludHJvZHVjdGlvbiB0byBSU2llbmEgLS0tLSAjIyMNCiMjIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjDQojIyMgICAgICAgICAgICAgICAgdmVyc2lvbjogU2VwdGVtYmVyIDgsIDIwMjAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIw0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMNCiMgUnNjcmlwdDAxRGF0YUZvcm1hdC5SIGlzIGZvbGxvd2VkIGJ5DQojIFJTY3JpcHRTTkFEZXNjcmlwdGl2ZXMuUiwgY29kZSBmb3IgZGVzY3JpcHRpdmUgYW5hbHlzaXMgb2YgdGhlIGRhdGEsIGFuZA0KIyBSc2NyaXB0MDJTaWVuYVZhcmlhYmxlRm9ybWF0LlIsIHdoaWNoIGZvcm1hdHMgZGF0YSBhbmQgc3BlY2lmaWVzIHRoZSBtb2RlbCwNCiMgYW5kIFJzY3JpcHQwM1NpZW5hUnVuTW9kZWwuUiwgd2hpY2ggcnVucyB0aGUgbW9kZWwgYW5kIGVzdGltYXRlcyBwYXJhbWV0ZXJzDQojIFJzY3JpcHQwNFNpZW5hQmVoYXZpb3VyLlIsIHdoaWNoIGlsbHVzdHJhdGVzIGFuIGV4YW1wbGUgb2YgYW5hbHlzaW5nIHRoZQ0KIyBjb2V2b2x1dGlvbiBvZiBuZXR3b3JrcyBhbmQgYmVoYXZpb3VyDQojDQojIFRoZSBlbnRpcmUgbW9kZWwgZml0dGluZyBpcyBzdW1tYXJpc2VkIGF0IHRoZSBlbmQgb2YgUnNjcmlwdFNpZW5hUnVuTW9kZWwuUg0KIyAod2l0aG91dCBjb21tZW50cykNCiMNCiMgVGhpcyBpcyBhbiBSIHNjcmlwdCBmb3IgZ2V0dGluZyBzdGFydGVkIHdpdGggUlNpZW5hLCB3cml0dGVuIGJ5DQojIFRvbSBTbmlqZGVycywgd2l0aCBlYXJsaWVyIGNvbnRyaWJ1dGlvbnMgZnJvbSBSb2JpbiBHYXV0aGllciwNCiMgUnV0aCBSaXBsZXksIEpvaGFuIEtvc2tpbmVuLCBQYXVsaW5hIFByZWNpYWRvLCBhbmQgWnNvZmlhIEJvZGEsDQojIHdpdGggc29tZSBleGFtcGxlcyBib3Jyb3dlZCBmcm9tIENocmlzdGlhbiBTdGVnbGljaC4NCiMgTGluZXMgc3RhcnRpbmcgd2l0aCAjIGFyZSBub3QgcHJvY2Vzc2VkIGJ5IFIgYnV0IHRyZWF0ZWQgYXMgY29tbWVudHMuDQojIFRoZSBzY3JpcHQgaGFzIGEgbG90IG9mIGV4cGxhbmF0aW9uIG9mIFIgcG9zc2liaWxpdGllcyB0aGF0IHdpbGwgYmUNCiMgZmFtaWxpYXIgZm9yIHJlYWRlcnMgd2VsbCBhY3F1YWludGVkIHdpdGggUiwgYW5kIGNhbiBiZSBza2lwcGVkIGJ5IHRoZW0uDQojDQojIFRoZXJlIGFyZSB2YXJpb3VzIHJlYWxseSBlYXN5IG9ubGluZSBpbnRyb2R1Y3Rpb25zIHRvIFIuIFNlZSwgZm9yIGV4YW1wbGUNCiMNCiMgICAgaHR0cDovL3d3dy5zdGF0bWV0aG9kcy5uZXQvDQojICAgIGh0dHA6Ly93d3cuYnVybnMtc3RhdC5jb20vcGFnZXMvVHV0b3IvaGludHNfUl9iZWdpbi5odG1sDQojICAgIGh0dHA6Ly9kYXRhLnByaW5jZXRvbi5lZHUvUi9nZXR0aW5nU3RhcnRlZC5odG1sDQojICAgIGh0dHBzOi8vc3RhdHMuaWRyZS51Y2xhLmVkdS9yLw0KIw0KIyBZb3UgY2FuIGdvIHRvIGFueSBvZiB0aGVzZSBzaXRlcyB0byBsZWFybiB0aGUgYmFzaWNzIG9mIFINCiMgb3IgcmVmcmVzaCB5b3VyIGtub3dsZWRnZS4NCiMgVGhlcmUgaXMgYSBsb3Qgb2YgZG9jdW1lbnRhdGlvbiBhdmFpbGFibGUgYXQNCiMgICAgaHR0cHM6Ly93d3cuci1wcm9qZWN0Lm9yZy9vdGhlci1kb2NzLmh0bWwNCiMgaW5jbHVkaW5nIHNvbWUgc2hvcnQgaW50cm9kdWN0aW9ucywgaGFuZHkgcmVmZXJlbmNlIGNhcmRzLA0KIyBhbmQgaW50cm9kdWN0aW9ucyBpbiBtYW55IGxhbmd1YWdlcyBiZXNpZGVzIEVuZ2xpc2guDQojDQojDQojIFNvbWUgZ2VuZXJhbCBwb2ludHMgdG8gbm90ZToNCiMNCiMgUiBpcyBjYXNlLXNlbnNpdGl2ZS4gQmUgYXdhcmUgb2YgY2FwaXRhbGl6YXRpb24hDQojDQojIFRoZSBsZWZ0LWFycm93ICI8LSIgaXMgdmVyeSBmcmVxdWVudGx5IHVzZWQ6IGl0IGRlbm90ZXMgYW4gYXNzaWdubWVudCwNCiMgImEgPC0gYiIgbWVhbmluZyB0aGF0IG9iamVjdCBhIGdldHMgdGhlIHZhbHVlIGIuDQojIE9mdGVuIGIgaXMgYSBjb21wbGljYXRlZCBleHByZXNzaW9uIHRoYXQgaGFzIHRvIGJlIGV2YWx1YXRlZCBieSBSLA0KIyBhbmQgY29tcHV0ZXMgYSByZXN1bHQgdGhhdCB0aGVuIGlzIHN0b3JlZCBhcyB0aGUgb2JqZWN0IGEuDQojDQojIEhlbHAgd2l0aGluIFIgY2FuIGJlIGNhbGxlZCBieSB0eXBpbmcgYSBxdWVzdGlvbiBtYXJrIGFuZCB0aGUgbmFtZSBvZiB0aGUNCiMgZnVuY3Rpb24geW91IG5lZWQgaGVscCBmb3IuIEZvciBleGFtcGxlDQojID9saWJyYXJ5DQojIHdpbGwgYnJpbmcgdXAgYSBmaWxlIHRpdGxlZCAibG9hZGluZy9hdHRhY2hpbmcgYW5kIGxpc3Rpbmcgb2YgcGFja2FnZXMiLg0KIyBDb21tZW50cyBhcmUgbWFkZSBhdCB0aGUgZW5kIG9mIGNvbW1hbmRzIGFmdGVyICMsDQojIG9yIGluIGxpbmVzIHN0YXJ0aW5nIHdpdGggIyB0ZWxsaW5nIFIgdG8gaWdub3JlIGV2ZXJ5dGhpbmcgYmV5b25kIGl0Lg0KIyBUaGF0IGlzIHdoeSBldmVyeXRoaW5nIHVwIHRvIG5vdyBpbiB0aGlzIGZpbGUgaXMgb24gbGluZXMgc3RhcnRpbmcgd2l0aCAjLg0KIw0KIyBUaGlzIHNlc3Npb24gd2lsbCBiZSB1c2luZyB0aGUgczUwIGRhdGEgd2hpY2ggYXJlIGF2YWlsYWJsZSBpbiBSU2llbmEuDQojIFlvdSBjYW4gYWxzbyBnZXQgdGhlbSBmcm9tDQojICAgIGh0dHA6Ly93d3cuc3RhdHMub3guYWMudWsvfnNuaWpkZXJzL3NpZW5hL3NpZW5hX2RhdGFzZXRzLmh0bQ0KIw0KIyBBbnkgY29tbWFuZCBpbiBSIGlzIGEgZnVuY3Rpb24sIGFuZCBlbmRzIGJ5IHBhcmVudGhlc2VzDQojIHRoYXQgZW5jbG9zZSB0aGUgYXJndW1lbnRzIG9mIHRoZSBmdW5jdGlvbiwNCiMgb3IgZW5jbG9zZSBub3RoaW5nIGlmIG5vIGFyZ3VtZW50IGlzIG5lZWRlZCwgc3VjaCBhcyBmb3IgdGhlIGZ1bmN0aW9uIHEoKQ0KIyBJbiBnZW5lcmFsIHRoZSBjb21tYW5kIHN5bnRheCBmb3IgY2FsbGluZyBSJ3MgZnVuY3Rpb25zIGlzIGZ1bmN0aW9uKHgpIHdoZXJlDQojIGZ1bmN0aW9uIGlzIGFuIGF2YWlsYWJsZSBmdW5jdGlvbiBhbmQgeCB0aGUgbmFtZSBvZiB0aGUgb2JqZWN0IG9wZXJhdGVkIG9uLg0KIw0KIyMjIyMjIyMjIyMjIyMjIyMjIyMgLSBDQUxMSU5HIFRIRSBEQVRBIEFORCBQUkVMSU1JTkFSWSBNQU5JUFVMQVRJT05TIC0gIyMjIyMjIyMNCg0KIyBUaGUgbGlicmFyeSBjb21tYW5kIGxvYWRzIHRoZSBwYWNrYWdlcyBuZWVkZWQgZHVyaW5nIHRoZSBzZXNzaW9uLg0KDQpsaWJyYXJ5KFJTaWVuYSkNCg0KIyBTb21lIGFkZGl0aW9uYWwgcGFja2FnZXMgYXJlIHVzZWQgYnkgUlNpZW5hLA0KIyB0aGUgc28tY2FsbGVkIHJlcXVpcmVkIHBhY2thZ2VzOyB0aGVzZSB3aWxsIGJlIGxvYWRlZCBhdXRvbWF0aWNhbGx5Lg0KDQojIFlvdSBuZWVkIHRvIGhhdmUgSU5TVEFMTEVEIGFsbCBvZiB0aGVtLg0KDQo/aW5zdGFsbC5wYWNrYWdlcw0KDQojIE9yIGNsaWNrIG9uIHRoZSB0YWIgIlBhY2thZ2VzIiwgIkluc3RhbGwgcGFja2FnZShzKSIsIHRoZW4gc2VsZWN0IGENCiMgQ1JBTiBtaXJyb3IgY2xvc2UgdG8geW91IChlLmcuIEJyaXN0b2wgaWYgeW91IGFyZSBpbiB0aGUgVUspIGFuZCBmaW5hbGx5DQojIHNlbGVjdCBmcm9tIHRoZSBsaXN0IHRoZSBwYWNrYWdlIHlvdSB3aXNoIHRvIGluc3RhbGwuDQoNCiMgV2hlcmUgYXJlIHlvdT8NCg0KZ2V0d2QoKQ0KDQojIEJ5IHNvbWV0aGluZyBsaWtlDQojIHNldHdkKCdDOi9TaWVuYVRlc3QnKQ0KIyB5b3UgY2FuIHNldCB0aGUgZGlyZWN0b3J5IGJ1dCBub3RlIHRoZSBxdW90ZXMgYW5kIGZvcndhcmQgc2xhc2guDQojIEl0IGlzIGFsc28gcG9zc2libGUgdG8gc2V0IHRoZSBkaXJlY3RvcnkgdXNpbmcgdGhlIG1lbnVzIGlmIHlvdSBoYXZlIHRoZW0uDQojIE9uIGEgd2luZG93cyBtYWNoaW5lLCB5b3UgY2FuIHByZWRldGVybWluZSB0aGUgd29ya2luZyBkaXJlY3RvcnkNCiMgaW4gdGhlIDxQcm9wZXJ0aWVzPiBvZiB0aGUgc2hvcnRjdXQgdG8gUjsNCiMgdGhlc2UgYXJlIGFjY2Vzc2libGUgYnkgcmlnaHQtY2xpY2tpbmcgdGhlIHNob3J0Y3V0Lg0KDQojIElmIHlvdSB3YW50IHRvIHNldCB0aGUgd29ya2luZyBkaXJlY3RvcnkgdG8gZm9yIGV4YW1wbGUNCiMgIkM6XERvY3VtZW50cyBhbmQgU2V0dGluZ3Ncam9oYW5cTXkgRG9jdW1lbnRzXFJTaWVuYV9jb3Vyc2UiDQojIHNpbXBseSBjb3B5IGFuZCBwYXN0ZSBmcm9tIHdpbmRvd3MgZXhwbG9yZXIgb3IgdHlwZQ0KIyAgICBzZXR3ZCgnQzovRG9jdW1lbnRzIGFuZCBTZXR0aW5ncy9qb2hhbi9NeSBEb2N1bWVudHMvUlNpZW5hX2NvdXJzZScpDQojIG9yDQojICAgIHNldHdkKCdDOlxcRG9jdW1lbnRzIGFuZCBTZXR0aW5nc1xcam9oYW5cXE15IERvY3VtZW50c1xcUlNpZW5hX2NvdXJzZScpDQojDQojIGJ1dCBub3RlIHRoYXQgIlwiIGhhcyB0byBiZSBjaGFuZ2VkOyBib3RoICcvJyBhbmQgJ1xcJyB3b3JrISEhDQoNCiMgV2hhdCBpcyBpbiB0aGlzIGRpcmVjdG9yeT8NCg0KbGlzdC5maWxlcygpDQoNCiMgV2hhdCBpcyBhdmFpbGFibGUgaW4gUlNpZW5hPw0KDQo/UlNpZW5hDQoNCiMgKHRoZXNlIGFyZSAuaHRsbSBIRUxQIFBBR0VTKQ0KDQojIEF0IHRoZSBib3R0b20gb2YgdGhpcyBwYWdlLCB3aGVuIHlvdSBjbGljayBvbiAiSW5kZXgiLA0KIyBhIGxpc3Qgb2YgYWxsIHRoZSBhdmFpbGFibGUgZnVuY3Rpb25zIGlzIHNob3duIGluIHlvdXIgYnJvd3Nlci4NCiMgVGhlIHNhbWUgbGlzdCBpcyBzaG93biBpbiB0aGUgZ3JhcGhpY2FsIHVzZXIgaW50ZXJmYWNlIGZvciBSIGJ5IHJlcXVlc3RpbmcNCg0KbGlicmFyeShoZWxwPVJTaWVuYSkNCg0KIyBBbiBleHRlbnNpdmUgbWFudWFsIGlzIGF0IHRoZSBTaWVuYSB3ZWJzaXRlDQojIGF0IGh0dHA6Ly93d3cuc3RhdHMub3guYWMudWsvfnNuaWpkZXJzL3NpZW5hL1JTaWVuYV9NYW51YWwucGRmIDsNCiMgaXQgaXMgdXBkYXRlZCBmcmVxdWVudGx5Lg0KDQojIEVhY2ggZGF0YSBpcyBuYW1lZCAoZm9yIGV4YW1wbGUgYmVsb3cgd2UgbmFtZSBpdCBmcmllbmQuZGF0YS53MSkNCiMgc28gdGhhdCB3ZSBjYW4gY2FsbCBpdCBhcyBhbiBvYmplY3Qgd2l0aGluIFIuDQojIElmIHlvdSByZWFkIGFuIG9iamVjdCBzdHJhaWdodCBpbnRvIFIsIGl0IHdpbGwgdHJlYXQgaXQgYXMgYQ0KIyBkYXRhc2V0LCBvciBpbiBSIHRlcm1pbm9sb2d5IGEgImRhdGEgZnJhbWUiLg0KIyBIZXJlIHRoaXMgaXMgbm90IHdoYXQgd2Ugd2FudCwgdGhlcmVmb3JlIG9uIHJlYWRpbmcNCiMgd2Ugd2lsbCBpbW1lZGlhdGVseSBjb252ZXJ0IGl0IHRvIGEgbWF0cml4Lg0KIyBSIHdpbGwgcmVhZCBpbiBtYW55IGRhdGEgZm9ybWF0cywgdGhlIGNvbW1hbmQgdG8gcmVhZCB0aGVtIGlzIHJlYWQudGFibGUuDQo/cmVhZC50YWJsZQ0KIyBJbiB0aGUgaGVscCBwYWdlIGZvciByZWFkLnRhYmxlLCBsb29rIGF0IHRoZSBzZWN0aW9uICJWYWx1ZSIsDQojIHdoaWNoIGlzIHRoZXJlIGluIGV2ZXJ5IGhlbHAgcGFnZToNCiMgaXQgaW5kaWNhdGVzIHRoZSBjbGFzcyBvZiB0aGUgb2JqZWN0IHRoYXQgaXMgcHJvZHVjZWQgYnkgdGhlIGZ1bmN0aW9uLg0KIyBGb3IgcmVhZC50YWJsZSwgdGhlIHZhbHVlIGlzIGEgZGF0YSBmcmFtZTsgYmVsb3cgd2Ugc2VlIHdoYXQgdGhpcyBpcy4NCiMNCiMgSWYgd2Ugd2lzaGVkIHRvIHJlYWQgYSAuY3N2IGZpbGUgd2Ugd291bGQgaGF2ZQ0KIyB1c2VkIHRoZSByZWFkLmNzdiBjb21tYW5kLg0KIyBUaGUgcGF0aG5hbWVzIG11c3QgaGF2ZSBmb3J3YXJkIHNsYXNoZXMsIG9yIGRvdWJsZSBiYWNrc2xhc2hlcy4NCiMgSWYgc2luZ2xlIGJhY2tzbGFzaGVzIGFyZSB1c2VkLCBvbmUgb2YgdGhlIGVycm9yIG1lc3NhZ2VzIHdpbGwgYmU6DQojICAgMTogJ1xSJyBpcyBhbiB1bnJlY29nbml6ZWQgZXNjYXBlIGluIGEgY2hhcmFjdGVyIHN0cmluZw0KDQojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KIyBRdWljayBzdGFydCAoRGF0YSBhc3NpZ25tZW50KS4NCiMgUGxlYXNlIG1ha2Ugc3VyZSB0aGUgczUwIGRhdGEgc2V0IGlzIGluIHlvdXIgd29ya2luZyBkaXJlY3RvcnkuDQojIFRoZSBkYXRhIHNldCBpcyBvbiB0aGUgU2llbmEgd2Vic2l0ZSAoIkRhdGEgc2V0cyIgdGFiKSBhbmQgbXVzdCBiZQ0KIyB1bnppcHBlZCBpbiB5b3VyIHdvcmtpbmcgZGlyZWN0b3J5Lg0KDQojICAgIGZyaWVuZC5kYXRhLncxIDwtIGFzLm1hdHJpeChyZWFkLnRhYmxlKCJzNTAtbmV0d29yazEuZGF0IikpDQojICAgIGZyaWVuZC5kYXRhLncyIDwtIGFzLm1hdHJpeChyZWFkLnRhYmxlKCJzNTAtbmV0d29yazIuZGF0IikpDQojICAgIGZyaWVuZC5kYXRhLnczIDwtIGFzLm1hdHJpeChyZWFkLnRhYmxlKCJzNTAtbmV0d29yazMuZGF0IikpDQojICAgIGRyaW5rIDwtIGFzLm1hdHJpeChyZWFkLnRhYmxlKCJzNTAtYWxjb2hvbC5kYXQiKSkNCiMgICAgc21va2UgPC0gYXMubWF0cml4KHJlYWQudGFibGUoInM1MC1zbW9rZS5kYXQiKSkNCg0KIyBUbyBtYWtlIHRoaXMgc2NyaXB0IHNlbGYtY29udGFpbmVkLCB5b3UgbWF5IGluc3RlYWQgcnVuIHRoZSBjb21tYW5kczoNCmxpYnJhcnkoUlNpZW5hKQ0KZnJpZW5kLmRhdGEudzEgPC0gczUwMQ0KZnJpZW5kLmRhdGEudzIgPC0gczUwMg0KZnJpZW5kLmRhdGEudzMgPC0gczUwMw0KZHJpbmsgPC0gczUwYQ0Kc21va2UgPC0gczUwcw0KIyBiZWNhdXNlIHM1MDEgZXRjLiBhcmUgaW50ZXJuYWwgZGF0YSBvYmplY3RzIG9mIFJTaWVuYS4NCg0KIyBFeHBsYW5hdGlvbiBvZiBkYXRhIHN0cnVjdHVyZXMgYW5kIGZvcm1hdHMgYmVsb3cNCg0KIyMjIyMjIyMjIyMjIyMjIyMgLSBESUZGRVJFTlQgREFUQSBGT1JNQVRTIC0gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIw0KIyMjIFRoZSBhc3NpZ25tZW50cyBoZXJlIGludm9sdmUgcmVhZGluZyBpbiBkYXRhIHRvIGEgImRhdGEgZnJhbWUiDQojIyMgICAgZGF0YSA8LSByZWFkLnRhYmxlKCJkYXRhLmRhdCIpDQojIyMgcmVhZHMgeW91ciB0ZXh0IGZpbGUgaW50byBhICJkYXRhIGZyYW1lIjsNCiMjIyBjaGVjayB0aGUgY2xhc3Mgb2YgdGhlIG9iamVjdCAiZGF0YSINCiMjIyAgICA+ICBjbGFzcyhkYXRhKQ0KIyMjICAgIFsxXSAiZGF0YS5mcmFtZSINCiMjIyBJZiB5b3VyIGRhdGEgaXMgbm90IGEgIi5kYXQiIGZpbGUsIGFsdGVybmF0aXZlIGltcG9ydCBtZXRob2RzIGFyZQ0KIyMjIC0tLS0tICIuY3N2IiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMjIyAgICBkYXRhIDwtIHJlYWQudGFibGUoImM6L2RhdGEuY3N2IiwgaGVhZGVyPVRSVUUsDQojIyMgICAgICAgICAgICAgICAgc2VwPSIsIiwgcm93Lm5hbWVzPSJpZGVuIikNCiMjIyAtLS0tICIuY3N2IiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIyMgICAgZGF0YSA8LSByZWFkLmNzdigiZGF0YS5jc3YiLGhlYWRlcj1UKQ0KIyMjIGxvb2sgYXQgP3JlYWQuY3N2IGFuZCA/cmVhZC50YWJsZSB0byB1bmRlcnN0YW5kIHRoZXNlIGZ1bmN0aW9uIGNhbGxzDQojIyMgLS0tLSAiLnNwc3MiIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyMjICAgIGxpYnJhcnkoZm9yZWlnbikNCiMjIyAgICBkYXRhIDwtIHJlYWQuc3BzcygiYzovZGF0YS5zcHNzIikNCiMjIyAtLS0tICIuZHRhIiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIyMgICAgbGlicmFyeShmb3JlaWduKQ0KIyMjICAgIGRhdGEgPC0gcmVhZC5kdGEoImM6L2RhdGEuZHRhIikNCiMjIw0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KIyMjIyMjIyMjIyMjIyMjIyMgLSBGUk9NIERBVEEgRlJBTUUgVE8gTUFUUklYIC0gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIw0KIyMjIC0tLS0gRGF0YSBmcmFtZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCiMjIyBUaGUgZGF0YSBmcmFtZSBpcyBsaWtlIGEgc3ByZWFkc2hlZXQgb2YgY2FzZXMgYnkgdmFyaWFibGVzLA0KIyMjIHdoZXJlIHRoZSB2YXJpYWJsZXMgYXJlIHRoZSBjb2x1bW5zLCBhbmQgdGhlc2UgaGF2ZSB0aGUgbmFtZXMNCiMjIyAgICBuYW1lcyggZGF0YSApDQojIyMgYSBzcHJlYWRzaGVldCB2aWV3IG9mIGEgZGF0YSBmcmFtZSBpcyBnaXZlbiBieSB0aGUgZml4KCkgY29tbWFuZA0KIyMjICAgIGZpeCggZGF0YSApDQojIyMNCiMjIyBBbGwgY2hhbmdlcyB5b3UgbWFrZSBpbiB0aGlzIHNwcmVhZHNoZWV0IHdpbGwgYmUgc2F2ZWQgYXV0b21hdGljYWxseSwNCiMjIyBzbyBiZXdhcmUuDQojIyMNCiMjIyBBcyBhbiBleGFtcGxlIGNyZWF0ZSB0d28gdmVjdG9yczoNCmhlaWdodCA8LSBjKCAxMjAsIDE1MCwgMTgwLCAyMDAsIDE5MCwgMTc3LCAxNzAsIDEyNSwgMTQxLCAxNTcgKQ0Kd2VpZ2h0IDwtIGMoIDExLCAxNCwgMTcsIDE4LCAxNywgMTgsIDExLCAxMiwgMTAsIDE1ICkNCiMjIyBUaGUgZnVuY3Rpb24gYygpIGNvbWJpbmVzIGl0cyBhcmd1bWVudCBpbnRvIGEgdmVjdG9yDQojIyMgKG9yIGludG8gYSBsaXN0LCBidXQgd2UgYXJlIG5vdCBjb25jZXJuZWQgd2l0aCB0aGF0IHBvc3NpYmlsaXR5IG5vdy4pLg0KIyMjIFRoZXNlIHR3byB2ZWN0b3JzIGNhbiBiZSBjb2xsZWN0ZWQgYXMgdmFyaWFibGVzIGluIGEgZGF0YSBmcmFtZQ0KbXlkYXRhIDwtIGRhdGEuZnJhbWUoIGhlaWdodCwgd2VpZ2h0ICkNCiMjIyBhbmQgbG9vayBhdCB0aGUgcmVzdWx0cw0KbXlkYXRhDQojIyMgVGhlIGNvbHVtbnMgb2YgYSBkYXRhIGZyYW1lIG1heSBiZSBleHRyYWN0ZWQNCiMjIyB1c2luZyBhICIkIiBzaWduIGFuZCB0aGVpciBuYW1lcy4NCiMjIyBGb3IgZXhhbXBsZToNCm5hbWVzKCBteWRhdGEgKQ0KbXlkYXRhJGhlaWdodA0KIyMjIE9yIGJ5ICJbXSIgYW5kIGNvbHVtbiBudW1iZXIsIGUuZy4NCm15ZGF0YVsxXQ0KbXlkYXRhWyAgLCAxXQ0KbXlkYXRhWyAxLCAgXQ0KIyMjIElmIHlvdSB3aXNoIHRvIHNlZSB0aGUgc3RydWN0dXJlIG9mIGFuIG9iamVjdCwgc3VjaCBhcyBteWRhdGEsIHRoZW4gcmVxdWVzdA0Kc3RyKG15ZGF0YSkNCiMjIyBPYmplY3RzIG9mdGVuIGhhdmUgYXR0cmlidXRlczoNCmF0dHJpYnV0ZXMobXlkYXRhKQ0KDQojIyMgLS0tLSBNYXRyaXggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KIyMjIEEgIm1hdHJpeCIgaXMgYSBudW1lcmljIG9iamVjdCBvcmRlcmVkIGxpa2UgYSBtYXRyaXggd2l0aCBkaW1lbnNpb25zDQojIyMgKCBkaW0oKSApIGdpdmVuIGJ5IHRoZSBudW1iZXIgb2Ygcm93cyBhbmQgY29sdW1ucywgZS5nLg0KZGltKCBmcmllbmQuZGF0YS53MSApDQoNCiMjIyBJZiB5b3Ugd2lzaCB0byBwbGF5IGFyb3VuZCB3aXRoIGEgY29weSBvZiB0aGUgbWF0cml4LA0KIyMjZS5nLiBoYXZpbmcgdGhlIG5hbWUgIm15ZGF0YSIsIHlvdSBjYW4gbWFrZSB0aGUgY29weSBieSB0aGUgY29tbWFuZA0KbXlkYXRhIDwtIGZyaWVuZC5kYXRhLncxDQojIyMgVGhlIGVhcmxpZXIgb2JqZWN0IHRoYXQgd2UgY3JlYXRlZCB3aXRoIHRoZSBuYW1lICJteWRhdGEiIG5vdyBoYXMgYmVlbiBsb3N0Lg0KIyMjIEVsZW1lbnRzIGlmIG1hdHJpY2VzIGNhbiBiZSBhY2Nlc3NlZCBieSB1c2luZyBzcXVhcmUgYnJhY2tldHMuDQojIyMgRm9yIGV4YW1wbGUsIHRoZSBlbGVtZW50IG9mICJteWRhdGEiIGluIHJvdyAyIGFuZCBjb2x1bW4gMyBpcyBnaXZlbiBieQ0KbXlkYXRhWyAyLCAzIF0NCiMjIyB0aGUgZmlyc3QgdGhyZWUgcm93cyBvZiBhIG1hdHJpeCBjYWxsZWQgbXlkYXRhIGFyZSBnaXZlbiBieQ0KbXlkYXRhWyAxOjMsIF0NCiMjIyBjb2x1bW5zIDIsIDUsIGFuZCA2IGFyZSBnaXZlbiBieQ0KbXlkYXRhWyAsIGMoIDIsIDUsIDYpIF0NCiMjIyBJbmRlZWQgdGhlcmUgYXJlIGEgbG90IG9mIHplcm9zIC0gbmV0d29ya3MgdGVuZCB0byBiZSBzcGFyc2UuDQoNCiMjIyAtLS0tIENvbnZlcnRpbmcgZGF0YSBmcmFtZSB0byBtYXRyaXggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQojIyMNCiMjIyBNb3N0IGNsYXNzZXMgY2FuIGJlIGNvbnZlcnRlZCB0byBvdGhlciBjbGFzc2VzIHRocm91Z2ggImFzLnR5cGVvZmNsYXNzICgpIiwNCiMjIyBlLmcuLCBpZiAibXlkYXRhIiB3b3VsZCBiZSBhbiBvYmplY3Qgd2l0aCBhIG1hdHJpeC1saWtlIHN0cnVjdHVyZSwNCiMjIyB0aGVuIGl0IGNvdWxkIGJlIGNvbnZlcnRlZCB0byB0aGUgY2xhc3MgIm1hdHJpeCIgYnkgdGhlIGNvbW1hbmQNCm15ZGF0YSA8LSBhcy5tYXRyaXgoIG15ZGF0YSApDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQoNCg0KIyMjIyMjIyMjIyMjIyMjIyMjIC0gRVhBTVBMRSBGT1IgQVJDIExJU1QgLSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIw0KIyMjIEZyb20gdGhlIFNpZW5hIHdlYnNpdGUgeW91IGNhbiBkb3dubG9hZCB0aGUgZGF0YSBzZXQgYXJjbGlzdGRhdGEuZGF0Lg0KIyMjIFRoZSBmdW5jdGlvbiByZWFkLnRhYmxlIGNhbiBiZSB1c2VkIHdpdGggdGhlIGludGVybmV0IGxvY2F0aW9uOg0KQXJjTGlzdCA8LQ0KICByZWFkLnRhYmxlKCAiaHR0cHM6Ly93d3cuc3RhdHMub3guYWMudWsvfnNuaWpkZXJzL3NpZW5hL2FyY2xpc3RkYXRhLmRhdCIsDQogICAgICAgICAgICAgIGhlYWRlcj1GQUxTRSApDQojIyMgTm90ZSB0aGUgY2FwaXRhbGl6YXRpb24uDQojIyMgTm93IEFyY0xpc3QgaXMgYSBkYXRhLmZyYW1lDQojIyMgKHdlIHNhdyB0aGlzIGFib3ZlIGluIHRoZSBoZWxwIHBhZ2UgZm9yIHJlYWQudGFibGUpLg0KIyMjIFdoYXQgYXJlIGl0cyBkaW1lbnNpb25zPw0KZGltKEFyY0xpc3QpDQojIyMgWW91IGNhbiBnZXQgYW4gaW1wcmVzc2lvbiBvZiBpdCBieSBsb29raW5nIGF0IHRoZSBzdGFydCBvZiB0aGUgb2JqZWN0Og0KaGVhZChBcmNMaXN0KQ0KIyMjIFRoaXMgaXMgYSBkYXRhIGZpbGUgaW4gYXJjbGlzdCBmb3JtYXQsIHdpdGggY29sdW1uczoNCiMjIyBzZW5kZXIgaWQsIHJlY2VpdmVyIGlkLCB2YWx1ZSBvZiB0aWUsIHdhdmUuDQojIyMgQWRkIG5hbWVzIHRvIHRoZSBjb2x1bW5zOg0KbmFtZXMoQXJjTGlzdCkgPC0gYyggInNpZCIsICJyZWNpZCIsICJiZmYiLCAid2lkIiApDQojIyMgYW5kIGFnYWluIHJlcXVlc3QNCmhlYWQoQXJjTGlzdCkNCiMjIyBUaGUgYmZmICgiYmVzdCBmcmllbmQiKSB2YXJpYWJsZSBkb2VzIG5vdCBoYXZlIG11Y2ggdmFyaWFiaWxpdHk6DQp0YWJsZShBcmNMaXN0JGJmZikNCiMjIyBUaGlzIHRlbGxzIHVzIHRoYXQgbm9uLXRpZXMgYXJlIG5vdCBpbmNsdWRlZCAodGhleSB3b3VsZCBoYXZlIHRoZSB2YWx1ZSAwKSwNCiMjIyBhbmQgdGhhdCB0aGVyZSBhcmUgbm8gdGllIHZhbHVlcyBvdGhlciB0aGFuIDEuDQojIyMgSXQgbWF5IGJlIG5pY2UgdG8gb3JkZXIgdGhlIHJvd3MgYnkgc2VuZGVyLCB0aGVuIGJ5IHJlY2VpdmVyLCB0aGVuIGJ5IHdhdmUuDQojIyMgVGhlIHRlZGlvdXMgd2F5IHRvIGRvIHRoaXMgaXMNCkFyY0xpc3QgPC0gQXJjTGlzdFsgb3JkZXIoIEFyY0xpc3Qkc2lkLCBBcmNMaXN0JHJlY2lkLCBBcmNMaXN0JHdpZCksIF0NCiMjIyBUbyB1bmRlcnN0YW5kIHRoaXMsIHlvdSBtYXkgbG9vayBhdCB0aGUgaGVscCBwYWdlIGZvciBmdW5jdGlvbiBvcmRlcigpDQojIyMgVGhlIHJvd3Mgb2YgQXJjbGlzdCBhcmUgb3JkZXJlZCBmaXJzdCBieSBBcmNMaXN0JHNpZCwgdGhlbiBieSBBcmNMaXN0JHJlY2lkLA0KIyMjIGFuZCB0aGVuIGJ5IEFyY0xpc3Qkd2lkOw0KIyMjIHRoZXNlIHJlb3JkZXJlZCByb3dzIHRoZW4gYXJlIHB1dCBpbnRvIHRoZSBvYmplY3QgQXJjTGlzdCwNCiMjIyB0aHVzIG92ZXJ3cml0aW5nIHRoZSBlYXJsaWVyIGNvbnRlbnRzIG9mIHRoaXMgb2JqZWN0Lg0KIyMjIFRoaXMgd2F5IGlzIHRlZGlvdXMgYmVjYXVzZSBpdCBpcyByZXBlYXRlZCBhbGwgdGhlIHRpbWUgdGhhdCB0aGUgbmFtZXMNCiMjIyBzaWQsIHJlY2lkLCB3aWQgcmVmZXIgdG8gdGhlIEFyY0xpc3Qgb2JqZWN0Lg0KIyMjIFRoZSBsZXNzIHRlZGlvdXMgd2F5IHVzZXMgdGhlIGZ1bmN0aW9uICJ3aXRoIi4NCiMjIyBUaGUgd2l0aChhLCBiKSBmdW5jdGlvbiB0ZWxscyBSIHRoYXQgYiBtdXN0IGJlIGNhbGN1bGF0ZWQsDQojIyMgd2hpbGUgdGhlIG90aGVyd2lzZSB1bmtub3duIG5hbWVzIHJlZmVyIHRvIGRhdGEgc2V0IGE6DQpBcmNMaXN0IDwtIHdpdGgoIEFyY0xpc3QsIEFyY0xpc3RbIG9yZGVyKCBzaWQsIHJlY2lkLCB3aWQpLCBdICkNCiMjIyBBbiBhcmMgbGlzdCBkb2VzIG5vdCBnaXZlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBudW1iZXIgb2Ygbm9kZXMsDQojIyMgYmVjYXVzZSBpc29sYXRlcyBhcmUgbm90IHJlY29yZGVkLg0KIyMjIFRoZSBzZXQgb2Ygbm9uLWlzb2xhdGVzIGlzDQp1bmlvbih1bmlxdWUoQXJjTGlzdCRzaWQpLCB1bmlxdWUoQXJjTGlzdCRyZWNpZCkpDQojIyMgYW5kLCBnaXZlbiB0aGF0IHdlIGhhdmUgdGhlIGluZm9ybWF0aW9uIHRoYXQgdGhlcmUgYXJlIDUwIG5vZGVzDQojIyMgbGFiZWxlZCAxIHRvIDUwLCB0aGUgaXNvbGF0ZXMgYXJlIHRoZSBmb2xsb3dpbmcgdHdvIG5vZGVzOg0Kc2V0ZGlmZigxOjUwLCB1bmlvbih1bmlxdWUoQXJjTGlzdCRzaWQpLCB1bmlxdWUoQXJjTGlzdCRyZWNpZCkpKQ0KIyMjIE5vdyBzdXBwb3NlIHdlIHdhbnQgdG8gY3JlYXRlIGEgc2VwYXJhdGUgc2V0IG9mIHJlY29yZHMgZm9yIGVhY2ggd2F2ZS4NCiMjIyBTZWxlY3QgYnkgd2F2ZToNCg0KU0FmZi4xIDwtIHdpdGgoQXJjTGlzdCwgQXJjTGlzdFsgd2lkID09IDEsIF0gKSAjZXh0cmFjdHMgZWRnZXMgaW4gd2F2ZSAxDQpTQWZmLjIgPC0gd2l0aChBcmNMaXN0LCBBcmNMaXN0WyB3aWQgPT0gMiwgXSApICNleHRyYWN0cyBlZGdlcyBpbiB3YXZlIDINClNBZmYuMyA8LSB3aXRoKEFyY0xpc3QsIEFyY0xpc3RbIHdpZCA9PSAzLCBdICkgI2V4dHJhY3RzIGVkZ2VzIGluIHdhdmUgMw0KDQojIyMgVGhpcyBjYW4gYmUgYXJyYW5nZWQgbW9yZSBlZmZpY2llbnRseSBhcw0KU0FmZiA8LSBsYXBwbHkoMTozLCBmdW5jdGlvbihtKXsgd2l0aChBcmNMaXN0LCBBcmNMaXN0WyB3aWQgPT0gbSwgXSApIH0gKQ0KIyMjIHdpdGggdGhlIGNvcnJlc3BvbmRlbmNlIHRoYXQgU0FmZi4xIGlzIFNBZmZbWzFdXSwgZXRjLg0KDQojIyMgRm9yIHRyYW5zZm9ybWluZyBhbiBhZGphY2VuY3kgbWF0cml4LCBlLmcuLCBmcmllbmQuZGF0YS53MSwgaW50byBhbiBhcmNsaXN0LA0KIyMjIGNyZWF0ZSBpbmRpY2F0b3IgbWF0cml4IG9mIHRoZSBub24temVybyBlbnRyaWVzOg0Kb25lcyA8LSAhZnJpZW5kLmRhdGEudzEgJWluJSAwDQojIyMgY3JlYXRlIGVtcHR5IGVkZ2UgbGlzdCBvZiBkZXNpcmVkIGxlbmd0aA0KZWRnZXMgPC0gbWF0cml4KDAsIHN1bShvbmVzKSwgMykNCiMjIyBmaWxsIHRoZSBjb2x1bW5zIG9mIHRoZSBlZGdlIGxpc3QNCmVkZ2VzWywgMV0gPC0gcm93KGZyaWVuZC5kYXRhLncxKVtvbmVzXQ0KZWRnZXNbLCAyXSA8LSBjb2woZnJpZW5kLmRhdGEudzEpW29uZXNdDQplZGdlc1ssIDNdIDwtIGZyaWVuZC5kYXRhLncxW29uZXNdDQojIyMgaWYgZGVzaXJlZCwgb3JkZXIgZWRnZSBsaXN0IGJ5IHNlbmRlcnMgYW5kIHRoZW4gcmVjZWl2ZXJzDQplZGdlcyA8LSBlZGdlc1tvcmRlcihlZGdlc1ssIDFdLCBlZGdlc1ssIDJdKSwgXQ0KIyMjIFdoYXQgZGlkIHdlIG1ha2U6DQplZGdlcw0KDQojIyMgRm9yIHRyYW5zZm9ybWluZyBhbiBhcmNsaXN0IGludG8gYSBtYXRyaXgsDQojIyMgZmlyc3QgcmVtb3ZlIHRoZSBmb3VydGggY29sdW1uIGluZGljYXRpbmcgdGhlIHdhdmUsIHNvIHRoYXQgd2UgYXJlIGxlZnQNCiMjIyB3aXRoIHNlbmRlciwgcmVjZWl2ZXIgYW5kIHZhbHVlIG9mIHRoZSB0aWUsDQojIyMgYW5kIHRyYW5zZm9ybSBpdCBpbnRvIG1hdHJpeCBmb3JtYXQgKGF0IGZpcnN0IGl0IGlzIGEgZGF0YS5mcmFtZSkNClNBZmYuMS5jb3B5IDwtIFNBZmYuMVssIDE6M10NClNBZmYuMS5jb3B5IDwtIGFzLm1hdHJpeChTQWZmLjEuY29weSkNCiMjIyBjcmVhdGUgZW1wdHkgYWRqYWNlbmN5IG1hdHJpeA0KYWRqIDwtIG1hdHJpeCgwLCA1MCwgNTApDQojIyMgcHV0IGVkZ2UgdmFsdWVzIGluIGRlc2lyZWQgcGxhY2VzDQphZGpbU0FmZi4xLmNvcHlbLDE6Ml1dIDwtIFNBZmYuMS5jb3B5WywgM10NCiMjIyBOb3cgYWRqIGlzIHRoZSBhZGphY2VuY3kgbWF0cml4Lg0KIyMjIEFsc28gc2VlIFNlY3Rpb24gNC4xIG9mIHRoZSBTaWVuYSBtYW51YWwNCiMjIyBhbmQgdGhlIGhlbHAgcGFnZSBmb3Igc2llbmFEZXBlbmRlbnQuDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIyMjIyMjIyMjIyMjIyMjIC0gUkVBRElORyBJTiBQQUpFSyBEQVRBIC0gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyMjDQojIyMgU2tpcCB0aGlzIHNlY3Rpb24gaWYgaGFuZGxpbmcgUGFqZWsgZGF0YSBpcyBvZiBubyBjb25jZXJuIHRvIHlvdS4NCiMjIyBJZiB5b3UgaGF2ZSBkYXRhIGluIFBhamVrIGZvcm1hdCB5b3UgY2FuIHVzZSB0aGUgcGFja2FnZSAibmV0d29yayIgaW4gb3JkZXINCiMjIyB0byBjb252ZXJ0IGl0IHRvIGEgbmV0d29yayBvYmplY3QuIFRoaXMgZXhhbXBsZSBpcyBmcm9tID9yZWFkLnBhag0KIyMjICAgcmVxdWlyZSggbmV0d29yayApDQojIyMNCiMjIyAgIHBhciggbWZyb3cgPSBjKCAyLCAyICkgKQ0KIyMjDQojIyMgICB0ZXN0Lm5ldC4xIDwtDQojIyMgICAgcmVhZC5wYWooImh0dHA6Ly92bGFkby5mbWYudW5pLWxqLnNpL3B1Yi9uZXR3b3Jrcy9kYXRhL0dEL2dkOTgvQTk4Lm5ldCIgKQ0KIyMjICAgcGxvdCggdGVzdC5uZXQuMSxtYWluID0gdGVzdC5uZXQuMSRnYWwkdGl0bGUgKQ0KIyMjICAgdGVzdC5uZXQuMiA8LQ0KIyMjICAgIHJlYWQucGFqKCJodHRwOi8vdmxhZG8uZm1mLnVuaS1sai5zaS9wdWIvbmV0d29ya3MvZGF0YS9taXgvVVNBaXI5Ny5uZXQiICkNCiMjIyAgIHBsb3QoIHRlc3QubmV0LjIsbWFpbiA9IHRlc3QubmV0LjIkZ2FsJHRpdGxlICkNCiMjIw0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KIyBCZWZvcmUgd2Ugd29yayB3aXRoIHRoZSBkYXRhLCB3ZSB3YW50IHRvIGJlIHN1cmUgaXQgaXMgY29ycmVjdC4gQSBzaW1wbGUgd2F5DQojIHRvIGNoZWNrIHRoYXQgb3VyIGRhdGEgaXMgYSBtYXRyaXggaXMgdGhlIGNvbW1hbmQgY2xhc3MoKQ0KDQpjbGFzcyggZnJpZW5kLmRhdGEudzEgKQ0KDQojIHRvIGxpc3QgdGhlIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0IGF0dHJpYnV0ZXMoIGZyaWVuZC5kYXRhLncxICkNCiMgKGRpZmZlcmVudCBjbGFzc2VzIGhhdmUgZGlmZmVyZW50IGF0dHJpYnV0ZXMpDQoNCiMgVG8gY2hlY2sgdGhhdCBhbGwgdGhlIGRhdGEgaGFzIGJlZW4gcmVhZCBpbiwgd2UgY2FuIHVzZSB0aGUgZGltKCkgY29tbWFuZC4NCiMgVGhlIGFkamFjZW5jeSBtYXRyaXggc2hvdWxkIGhhdmUgdGhlIHNhbWUgZGltZW5zaW9ucyBhcyB0aGUgb3JpZ2luYWwgZGF0YQ0KIyAoaGVyZSwgNTAgYnkgNTApLg0KDQpkaW0oZnJpZW5kLmRhdGEudzEpDQpkaW0oZHJpbmspDQoNCiMgVG8gY2hlY2sgdGhlIHZhbHVlcyBhcmUgY29ycmVjdCwgaW5jbHVkaW5nIG1pc3NpbmcgdmFsdWVzLCB3ZSBjYW4gdXNlDQojIHRoZSBmb2xsb3dpbmcgY29tbWFuZHMgdG8gdGFidWxhdGUgdGhlIHZhcmlhYmxlcy4NCg0KdGFibGUoIGZyaWVuZC5kYXRhLncxLCB1c2VOQSA9ICdhbHdheXMnICkNCnRhYmxlKCBmcmllbmQuZGF0YS53MiwgdXNlTkEgPSAnYWx3YXlzJyApDQp0YWJsZSggZnJpZW5kLmRhdGEudzMsIHVzZU5BID0gJ2Fsd2F5cycgKQ0KdGFibGUoIGRyaW5rLCB1c2VOQSA9ICdhbHdheXMnICkNCnRhYmxlKCBzbW9rZSwgdXNlTkEgPSAnYWx3YXlzJyApDQoNCiMgTkEgaXMgdGhlIFIgY29kZSBmb3IgbWlzc2luZyBkYXRhIChOb3QgQXZhaWxhYmxlKS4NCiMgVGhpcyBkYXRhIHNldCBoYXBwZW5zIHRvIGhhdmUgbm8gbWlzc2luZ3MNCiMgKHNlZSB0aGUgZGF0YSBkZXNjcmlwdGlvbiBvbiB0aGUgU2llbmEgd2Vic2l0ZSkuDQojIElmIHRoZXJlIGFyZSBhbnkgbWlzc2luZ3MsDQojIGl0IGlzIG5lY2Vzc2FyeSB0byB0ZWxsIFIgYWJvdXQgdGhlIG1pc3NpbmcgZGF0YSBjb2Rlcy4NCiMgTGV0IHVzIGRvIGFzIGlmIHRoZSBtaXNzaW5nIGNvZGVzIGZvciB0aGUgZnJpZW5kc2hpcCBuZXR3b3JrIHdlcmUgNiBhbmQgOS4NCiMgVGhpcyBsZWFkcyB0byB0aGUgZm9sbG93aW5nIGNvbW1hbmRzLg0KIyAoRm9yIG5ldyBSIHVzZXJzOiB0aGUgYygpIGZ1bmN0aW9uIHVzZWQgaGVyZSBhcyAiYyg2LDkpIiBjb25zdHJ1Y3RzDQojICBhIHZlY3RvciBbYyBmb3IgY29sdW1uXSBjb25zaXN0aW5nIG9mIHRoZSBudW1iZXJzIDYgYW5kIDkuDQojICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgYSBsb3QgaW4gYmFzaWMgUi4pDQoNCmZyaWVuZC5kYXRhLncxWyBmcmllbmQuZGF0YS53MSAlaW4lIGMoNiw5KSBdIDwtIE5BDQpmcmllbmQuZGF0YS53MlsgZnJpZW5kLmRhdGEudzIgJWluJSBjKDYsOSkgXSA8LSBOQQ0KZnJpZW5kLmRhdGEudzNbIGZyaWVuZC5kYXRhLnczICVpbiUgYyg2LDkpIF0gPC0gTkENCg0KIyBDb21tYW5kcyBmb3IgZGVzY3JpcHRpdmUgYW5hbHlzaXMgYXJlIGluIHRoZSBzY3JpcHQ6IFJzY3JpcHRTTkFEZXNjcmlwdGl2ZXMuUg0KDQojIyMjIyMjIyMjIyMjIyAtIFNFTEVDVElORyBTVUJTRVRTIE9GIERBVEEgLSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KDQojIFRvIHNlbGVjdCBhIHN1YnNldCBvZiB0aGUgZGF0YSBiYXNlZCBvbiBhbiBhY3RvciB2YXJpYWJsZSwgc2F5LA0KIyB0aG9zZSB3aG8gaGF2ZSB0aGUgdmFsdWUgMiBvciAzIG9uIGRyaW5raW5nIGF0IHRpbWUgMQ0KIyAodGhlIHBvc3NpYmlsaXRpZXMgYXJlIGVuZGxlc3MsIGJ1dCBob3BlZnVsbHkgdGhpcyB3aWxsIHNlcnZlIGFzIGEgcGF0dGVybikNCg0KdXNlIDwtIGRyaW5rWywgMV0gJWluJSBjKDIsIDMpDQoNCiMgVGhpcyBjcmVhdGVzIGEgbG9naWNhbCB2ZWN0b3Igd2hpY2ggaXMgVFJVRSBmb3IgdGhlIGNhc2VzIHdoZXJlIHRoZSBjb25kaXRpb24NCiMgaXMgc2F0aXNmaWVkLiBUbyB2aWV3IG9yIGNoZWNrLCBkaXNwbGF5IHRoZSB2ZWN0b3JzIG5leHQgdG8gZWFjaCBvdGhlcjoNCg0KY2JpbmQoZHJpbmtbICwgMSBdLCB1c2UpDQpkYXRhLmZyYW1lKGRyaW5rWyAsIDEgXSwgdXNlKQ0KDQojIGFuZCB0aGUgbnVtYmVyIG9mIHNlbGVjdGVkIGNhc2VzIGlzIGRpc3BsYXllZCBieQ0KDQpzdW0oIHVzZSApDQoNCiMgb3INCg0KdGFibGUoIHVzZSApDQoNCiMgR2l2ZW4gdGhpcyBzZWxlY3Rpb24sIHN1Ym1hdHJpY2VzIGNhbiBiZSBmb3JtZWQgaW4gY2FzZSB0aGUgYW5hbHlzZXMNCiMgYXJlIHRvIGJlIGRvbmUgZm9yIHRoaXMgc3Vic2V0IG9ubHk6DQoNCmZyaWVuZDEuZGF0YS53MSA8LSBmcmllbmQuZGF0YS53MVsgdXNlLCB1c2UgXQ0KZnJpZW5kMS5kYXRhLncyIDwtIGZyaWVuZC5kYXRhLncyWyB1c2UsIHVzZSBdDQpkcmluazEgPC0gZHJpbmtbIHVzZSwgXQ0KDQojIEEgdXNlZnVsIG9wdGlvbiBpbiBSIHRoYXQgYWxsb3dzIHlvdSB0byBzYXZlIHlvdXIgd29ya3NwYWNlOg0Kc2F2ZS5pbWFnZSgiV29ya3NwYWNlUnNjcmlwdDAxLlJEYXRhIikNCiMgTGF0ZXIgeW91IGNhbiBsb2FkIHRoaXMgaW4gYSBuZXcgc2Vzc2lvbiBieQ0KIyBsb2FkKCJXb3Jrc3BhY2VSc2NyaXB0MDEuUkRhdGEiKQ0KDQojIElmIG5leHQgdGltZSB5b3Ugd291bGQgbGlrZSB0byBjb250aW51ZSBmcm9tIGhlcmUsIHlvdSB3aWxsIG5vdCBuZWVkIHRvIG9wZW4NCiMgYW5kIHJ1biB0aGlzIHNjcmlwdCBhZ2Fpbiwgc2luY2UgeW91IHdpbGwgYmUgYWJsZSB0byBsb2FkIHRoaXMgY3VycmVudCBzdGF0ZQ0KIyBvZiB5b3VyIHdvcmtzcGFjZS4gQnV0IHBhY2thZ2VzIHdpbGwgaGF2ZSB0byBiZSBhdHRhY2hlZCBhZ2Fpbi4NCg0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCiMjIw0KIyMjIC0tLS0gUFJPQ0VFRCBUTyBSc2NyaXB0U05BRGVzY3JpcHRpdmVzLlIgRk9SIERFU0NSSVBUSVZFIEFOQUxZU0lTIC0tLS0tLS0tLS0NCiMjIw0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCg0KYGBgDQoNCg0K

Copyright © 2020 Jochem Tolsma