Haven
Haven contains functions that lets R import SPSS, SAS, Stata, and
other foreign files.
Documentation can be viewed here
# Check if haven is already installed and if it is, load it.
if (!require(haven)){
# If it's not intalled, then tell R to install it.
install.packages("haven", dependencies = TRUE)
# Once it's installed, tell R to load it.
library(haven)
}
Tidyverse
Tidyverse contains many functions useful to cleaning, tidying, and
manipulating data
Documentation can be viewed here
if (!require(tidyverse)){
install.packages("tidyverse", dependencies = TRUE)
library(tidyverse)
}
psych
Summarytools provide useful functions for summarizing and visualizing
data
Documentation can be viewed here
if (!require(psych)){
install.packages("psych", dependencies = TRUE)
require(psych)
}
corrr
quick and easy correlations
Documentation can be viewed here
if (!require(corrr)){
install.packages("corrr", dependencies = TRUE)
require(corrr)
}
GGally
quick and easy correlations
Documentation can be viewed here
if (!require(GGally)){
install.packages("GGally", dependencies = TRUE)
require(GGally)
}
Import an SPSS file
Use the read_sav() function from the Haven package to import an SPSS
file into R.
Documentation can be viewed here
dataset <- read_sav("https://osf.io/98mt6/download")
Clean dataset
View dataset
Use the View() function to look at your dataset like you would in
SPSS or Excel
Documentation can be viewed here
#View(dataset)
View questions or ‘labels’
This is useful if you used haven to import an SPSS file created by
Qualtrics
Documentation can be viewed here
dataset %>%
map(~ attr(., "label"))
Remove columns
Use the Select() function to de-select a column.
Put ‘-’ before the column name to remove a column (you can list more
than one column).
Just type the column name to keep only that column (you can list more
than one column).
Documentation can be viewed here
dataset %>%
select(-IPAddress) -> dataset
Remove practice runs
Use the slice() funciton to remove rows.
Put the range of rows you’d like to remove with minus signs in
front.
Documentation can be viewed here
dataset %>%
slice(-1:-3) -> dataset
Recode variables
Use the tidyverse, mutate, and case_when to recode variables
Documentation can be viewed here
Recode to a factor
dataset %>%
mutate(CoinFlipFactor = case_when(CoinFlip==1 ~ "Heads",
CoinFlip==2 ~ "Tails")) -> dataset
Recode to a dummy variable
dataset %>%
mutate(FlipHeadsDummy = case_when(CoinFlip==1 ~ 1,
CoinFlip==2 ~ 0)) -> dataset
Summarize variables
Use the describe() function of the psych package to summarize
data
Documentation can be viewed here
#First select the variables you'd like to summarize
dataset %>%
select (CoinFlip, FFM_5, Potter3) %>%
describe()
Create Composite Variable
Psych
Documentation can be viewed here
Agreeableness
#create dataframe with only relevant variables to work with
Agreeableness <- data.frame (dataset$FFM_2, dataset$FFM_7, dataset$FFM_12, dataset$FFM_17, dataset$FFM_22, dataset$FFM_27, dataset$FFM_32, dataset$FFM_37, dataset$FFM_42)
Agreeableness.keys <- make.keys(Agreeableness, list(Agreeableness=c(-1,2,-3,4,5,-6,7,-8,9)))
Agreeableness.scales <- scoreItems (Agreeableness.keys, Agreeableness)
Agreeableness.scores <- Agreeableness.scales$scores
dataset$Agreeableness <- Agreeableness.scores[,]
Agreeableness.scales$alpha
Conscientiousness
#create dataframe with only relevant variables to work with
Conscientiousness <- data.frame (dataset$FFM_3, dataset$FFM_8, dataset$FFM_13, dataset$FFM_18, dataset$FFM_23, dataset$FFM_28, dataset$FFM_33, dataset$FFM_38, dataset$FFM_43)
my.keys <- make.keys(Conscientiousness, list(Conscientiousness=c(1,-2,3,-4,-5,6,7,8,-9)))
my.scales <- scoreItems (my.keys, Conscientiousness)
my.scores <- my.scales$scores
dataset$Conscientiousness <- my.scores[,]
my.scales$alpha
Neuroticism
#create dataframe with only relevant variables to work with
Neuroticism <- data.frame (dataset$FFM_4, dataset$FFM_9, dataset$FFM_14, dataset$FFM_19, dataset$FFM_24, dataset$FFM_29, dataset$FFM_34, dataset$FFM_39)
my.keys <- make.keys(Neuroticism, list(Neuroticism=c(1,-2,3,4,-5,6,-7,8)))
my.scales <- scoreItems (my.keys, Neuroticism)
my.scores <- my.scales$scores
dataset$Neuroticism <- my.scores[,]
my.scales$alpha
Openness
#create dataframe with only relevant variables to work with
Openness <- data.frame (dataset$FFM_5, dataset$FFM_10, dataset$FFM_15, dataset$FFM_20, dataset$FFM_25, dataset$FFM_30, dataset$FFM_35, dataset$FFM_40, dataset$FFM_41, dataset$FFM_44)
my.keys <- make.keys(Openness, list(Openness=c(1,2,3,4,5,6,-7,8,-9,10)))
my.scales <- scoreItems (my.keys, Openness)
my.scores <- my.scales$scores
dataset$Openness <- my.scores[,]
my.scales$alpha
Tidyverse
Documentation can be viewed here
and here
dataset %>%
rowwise() %>%
mutate(extraversionTidy = mean(c(FFM_1, 6-FFM_6, FFM_11, FFM_16, 6-FFM_21, FFM_26, 6-FFM_31, FFM_36))) -> dataset
Correlations
Calculate correlations
Explore correlations
Documentation can be viewed here
dataset %>%
select(Openness, Conscientiousness, Extraversion, Agreeableness, Neuroticism) %>%
correlate() %>%
shave() %>%
fashion()
Calculate p-values
Documentation can be viewed here
dataset %>%
select(Openness, Conscientiousness, Extraversion, Agreeableness, Neuroticism) -> Big5df
corr.test(x = Big5df,
y = NULL,
use = "pairwise",
method = "pearson",
adjust = "holm",
alpha = .05,
ci = TRUE)
Deciding between Pearson and Spearman correlations
Documentation can be viewed here
dataset %>%
select(Openness, Conscientiousness, Extraversion, Agreeableness, Neuroticism) %>%
ggpairs()
t-tests
Documentation can be viewed here
independent samples t-tests
dataset %>%
with(t.test(Agreeableness ~ CoinFlipFactor))
paired samples t-tests
dataset %>%
with(t.test(Agreeableness, Neuroticism, paired = TRUE))
LS0tCnRpdGxlOiAiUiBNYW51YWwiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRoZW1lOiBwYXBlcgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCi0tLQoKCiMjIEhhdmVuCkhhdmVuIGNvbnRhaW5zIGZ1bmN0aW9ucyB0aGF0IGxldHMgUiBpbXBvcnQgU1BTUywgU0FTLCBTdGF0YSwgYW5kIG90aGVyIGZvcmVpZ24gZmlsZXMuCgpEb2N1bWVudGF0aW9uIGNhbiBiZSB2aWV3ZWQgW2hlcmVdKGh0dHBzOi8vaGF2ZW4udGlkeXZlcnNlLm9yZykKYGBge3J9CiMgQ2hlY2sgaWYgaGF2ZW4gaXMgYWxyZWFkeSBpbnN0YWxsZWQgYW5kIGlmIGl0IGlzLCBsb2FkIGl0LgppZiAoIXJlcXVpcmUoaGF2ZW4pKXsKICAjIElmIGl0J3Mgbm90IGludGFsbGVkLCB0aGVuIHRlbGwgUiB0byBpbnN0YWxsIGl0LgogIGluc3RhbGwucGFja2FnZXMoImhhdmVuIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKICAjIE9uY2UgaXQncyBpbnN0YWxsZWQsIHRlbGwgUiB0byBsb2FkIGl0LgogIGxpYnJhcnkoaGF2ZW4pCn0KYGBgCiMjIFRpZHl2ZXJzZQpUaWR5dmVyc2UgY29udGFpbnMgbWFueSBmdW5jdGlvbnMgdXNlZnVsIHRvIGNsZWFuaW5nLCB0aWR5aW5nLCBhbmQgbWFuaXB1bGF0aW5nIGRhdGEKCkRvY3VtZW50YXRpb24gY2FuIGJlIHZpZXdlZCBbaGVyZV0oaHR0cHM6Ly93d3cudGlkeXZlcnNlLm9yZykKCmBgYHtyfQppZiAoIXJlcXVpcmUodGlkeXZlcnNlKSl7CiAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKICBsaWJyYXJ5KHRpZHl2ZXJzZSkKfQpgYGAKCiMjIHN1bW1hcnl0b29scwoKU3VtbWFyeXRvb2xzIHByb3ZpZGUgdXNlZnVsIGZ1bmN0aW9ucyBmb3Igc3VtbWFyaXppbmcgYW5kIHZpc3VhbGl6aW5nIGRhdGEKCkRvY3VtZW50YXRpb24gY2FuIGJlIHZpZXdlZCBbaGVyZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL3N1bW1hcnl0b29scy92ZXJzaW9ucy8wLjguNSkKYGBge3J9CmlmICghcmVxdWlyZShzdW1tYXJ5dG9vbHMpKXsKICBpbnN0YWxsLnBhY2thZ2VzKCJzdW1tYXJ5dG9vbHMiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQogIHJlcXVpcmUoc3VtbWFyeXRvb2xzKQp9CmBgYAojIyBwc3ljaAoKU3VtbWFyeXRvb2xzIHByb3ZpZGUgdXNlZnVsIGZ1bmN0aW9ucyBmb3Igc3VtbWFyaXppbmcgYW5kIHZpc3VhbGl6aW5nIGRhdGEKCkRvY3VtZW50YXRpb24gY2FuIGJlIHZpZXdlZCBbaGVyZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL3N1bW1hcnl0b29scy92ZXJzaW9ucy8wLjguNSkKYGBge3J9CmlmICghcmVxdWlyZShwc3ljaCkpewogIGluc3RhbGwucGFja2FnZXMoInBzeWNoIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKICByZXF1aXJlKHBzeWNoKQp9CmBgYAojIyBjb3JycgoKcXVpY2sgYW5kIGVhc3kgY29ycmVsYXRpb25zCgpEb2N1bWVudGF0aW9uIGNhbiBiZSB2aWV3ZWQgW2hlcmVdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9jb3Jyci92ZXJzaW9ucy8wLjMuMCkKYGBge3J9CmlmICghcmVxdWlyZShjb3JycikpewogIGluc3RhbGwucGFja2FnZXMoImNvcnJyIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKICByZXF1aXJlKGNvcnJyKQp9CmBgYAojIyBHR2FsbHkKCnF1aWNrIGFuZCBlYXN5IGNvcnJlbGF0aW9ucwoKRG9jdW1lbnRhdGlvbiBjYW4gYmUgdmlld2VkIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvR0dhbGx5L3ZlcnNpb25zLzEuNC4wKQpgYGB7cn0KaWYgKCFyZXF1aXJlKEdHYWxseSkpewogIGluc3RhbGwucGFja2FnZXMoIkdHYWxseSIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCiAgcmVxdWlyZShHR2FsbHkpCn0KYGBgCiMgSW1wb3J0IGFuIFNQU1MgZmlsZQoKPGlmcmFtZSB3aWR0aD0iNTYwIiBoZWlnaHQ9IjMxNSIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC84enBIYzlVOEhJWSIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhdXRvcGxheTsgZW5jcnlwdGVkLW1lZGlhIiBhbGxvd2Z1bGxzY3JlZW4+PC9pZnJhbWU+CgpVc2UgdGhlIHJlYWRfc2F2KCkgZnVuY3Rpb24gZnJvbSB0aGUgSGF2ZW4gcGFja2FnZSB0byBpbXBvcnQgYW4gU1BTUyBmaWxlIGludG8gUi4KCkRvY3VtZW50YXRpb24gY2FuIGJlIHZpZXdlZCBbaGVyZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL2hhdmVuL3ZlcnNpb25zLzEuMS4yL3RvcGljcy9yZWFkX3Nwc3MpCmBgYHtyfQpkYXRhc2V0IDwtIHJlYWRfc2F2KCJodHRwczovL29zZi5pby85OG10Ni9kb3dubG9hZCIpCmBgYAoKIyBDbGVhbiBkYXRhc2V0IHsudGFic2V0fQoKPGlmcmFtZSB3aWR0aD0iNTYwIiBoZWlnaHQ9IjMxNSIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9nRkFMeGtHZlBRUSIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhdXRvcGxheTsgZW5jcnlwdGVkLW1lZGlhIiBhbGxvd2Z1bGxzY3JlZW4+PC9pZnJhbWU+CgojIyBWaWV3IGRhdGFzZXQKVXNlIHRoZSBWaWV3KCkgZnVuY3Rpb24gdG8gbG9vayBhdCB5b3VyIGRhdGFzZXQgbGlrZSB5b3Ugd291bGQgaW4gU1BTUyBvciBFeGNlbAoKRG9jdW1lbnRhdGlvbiBjYW4gYmUgdmlld2VkIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvdXRpbHMvdmVyc2lvbnMvMy41LjEvdG9waWNzL1ZpZXcpCgpgYGB7cn0KI1ZpZXcoZGF0YXNldCkKYGBgCgojIyBWaWV3IHF1ZXN0aW9ucyBvciAnbGFiZWxzJwpUaGlzIGlzIHVzZWZ1bCBpZiB5b3UgdXNlZCBoYXZlbiB0byBpbXBvcnQgYW4gU1BTUyBmaWxlIGNyZWF0ZWQgYnkgUXVhbHRyaWNzCgpEb2N1bWVudGF0aW9uIGNhbiBiZSB2aWV3ZWQgW2hlcmVdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9wdXJyci92ZXJzaW9ucy8wLjIuMi4yKQpgYGB7cn0KZGF0YXNldCAlPiUKICBtYXAofiBhdHRyKC4sICJsYWJlbCIpKQpgYGAKCiMjIFJlbW92ZSBjb2x1bW5zClVzZSB0aGUgU2VsZWN0KCkgZnVuY3Rpb24gdG8gZGUtc2VsZWN0IGEgY29sdW1uLgoKUHV0ICctJyBiZWZvcmUgdGhlIGNvbHVtbiBuYW1lIHRvIHJlbW92ZSBhIGNvbHVtbiAoeW91IGNhbiBsaXN0IG1vcmUgdGhhbiBvbmUgY29sdW1uKS4KCkp1c3QgdHlwZSB0aGUgY29sdW1uIG5hbWUgdG8ga2VlcCBvbmx5IHRoYXQgY29sdW1uICh5b3UgY2FuIGxpc3QgbW9yZSB0aGFuIG9uZSBjb2x1bW4pLgoKRG9jdW1lbnRhdGlvbiBjYW4gYmUgdmlld2VkIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvZHBseXIvdmVyc2lvbnMvMC43LjYvdG9waWNzL3NlbGVjdCkKCmBgYHtyfQpkYXRhc2V0ICU+JQogIHNlbGVjdCgtSVBBZGRyZXNzKSAtPiBkYXRhc2V0CmBgYAoKIyMgUmVtb3ZlIHByYWN0aWNlIHJ1bnMKVXNlIHRoZSBzbGljZSgpIGZ1bmNpdG9uIHRvIHJlbW92ZSByb3dzLgoKUHV0IHRoZSByYW5nZSBvZiByb3dzIHlvdSdkIGxpa2UgdG8gcmVtb3ZlIHdpdGggbWludXMgc2lnbnMgaW4gZnJvbnQuCgpEb2N1bWVudGF0aW9uIGNhbiBiZSB2aWV3ZWQgW2hlcmVdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9kcGx5ci92ZXJzaW9ucy8wLjcuNi90b3BpY3Mvc2xpY2UpCgpgYGB7cn0KZGF0YXNldCAlPiUgCiAgc2xpY2UoLTE6LTMpIC0+IGRhdGFzZXQKYGBgCiMjIFJlY29kZSB2YXJpYWJsZXMgey50YWJzZXR9CgpVc2UgdGhlIHRpZHl2ZXJzZSwgbXV0YXRlLCBhbmQgY2FzZV93aGVuIHRvIHJlY29kZSB2YXJpYWJsZXMKRG9jdW1lbnRhdGlvbiBjYW4gYmUgdmlld2VkIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvZHBseXIvdmVyc2lvbnMvMC43LjYvdG9waWNzL2Nhc2Vfd2hlbikKCiMjIyBSZWNvZGUgdG8gYSBmYWN0b3IKYGBge3J9CmRhdGFzZXQgJT4lCiAgbXV0YXRlKENvaW5GbGlwRmFjdG9yID0gY2FzZV93aGVuKENvaW5GbGlwPT0xIH4gIkhlYWRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29pbkZsaXA9PTIgfiAiVGFpbHMiKSkgLT4gZGF0YXNldApgYGAKIyMjIFJlY29kZSB0byBhIGR1bW15IHZhcmlhYmxlCmBgYHtyfQpkYXRhc2V0ICU+JQogIG11dGF0ZShGbGlwSGVhZHNEdW1teSA9IGNhc2Vfd2hlbihDb2luRmxpcD09MSB+IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ29pbkZsaXA9PTIgfiAwKSkgLT4gZGF0YXNldApgYGAKIyBTdW1tYXJpemUgdmFyaWFibGVzIHsudGFic2V0fQoKIyMgVXNlIGRmU3VtbWFyeSBmdW5jdGlvbiBmcm9tIHN1bW1hcnl0b29scyBwYWNrYWdlIHRvIHN1bW1hcml6ZSBhbmQgdmlzdWFsaXplIGRhdGEKCjxpZnJhbWUgd2lkdGg9IjU2MCIgaGVpZ2h0PSIzMTUiIHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vZW1iZWQvTDhJd1M3c2hpcGciIGZyYW1lYm9yZGVyPSIwIiBhbGxvdz0iYXV0b3BsYXk7IGVuY3J5cHRlZC1tZWRpYSIgYWxsb3dmdWxsc2NyZWVuPjwvaWZyYW1lPgoKRG9jdW1lbnRhdGlvbiBjYW4gYmUgdmlld2VkIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvc3VtbWFyeXRvb2xzL3ZlcnNpb25zLzAuOC41L3RvcGljcy9kZlN1bW1hcnkpCgpgYGB7cn0KI0ZpcnN0IHNlbGVjdCB0aGUgdmFyaWFibGVzIHlvdSdkIGxpa2UgdG8gc3VtbWFyaXplCmRhdGFzZXQgJT4lCiAgc2VsZWN0IChDb2luRmxpcCwgRkZNXzUsIFBvdHRlcjMpIC0+IGV4YW1wbGVERgoKI1RoZW4gcHJpbnQgdGhlbSB3aXRoIHRoaXMgY29tbWFuZApwcmludChkZlN1bW1hcnkoZXhhbXBsZURGLCBncmFwaC5tYWduaWYgPSAuNzUpLCBtZXRob2QgPSAncmVuZGVyJykKYGBgCiMjIFVzZSB0aGUgZGVzY3JpYmUoKSBmdW5jdGlvbiBvZiB0aGUgcHN5Y2ggcGFja2FnZSB0byBzdW1tYXJpemUgZGF0YQoKPGlmcmFtZSB3aWR0aD0iNTYwIiBoZWlnaHQ9IjMxNSIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9LODNfdFlYcUZWbyIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhdXRvcGxheTsgZW5jcnlwdGVkLW1lZGlhIiBhbGxvd2Z1bGxzY3JlZW4+PC9pZnJhbWU+CgpEb2N1bWVudGF0aW9uIGNhbiBiZSB2aWV3ZWQgW2hlcmVdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9wc3ljaC92ZXJzaW9ucy8xLjguNC90b3BpY3MvZGVzY3JpYmUpCgpgYGB7cn0KI0ZpcnN0IHNlbGVjdCB0aGUgdmFyaWFibGVzIHlvdSdkIGxpa2UgdG8gc3VtbWFyaXplCmRhdGFzZXQgJT4lCiAgc2VsZWN0IChDb2luRmxpcCwgRkZNXzUsIFBvdHRlcjMpICU+JQogIGRlc2NyaWJlKCkKYGBgCiMgQ3JlYXRlIENvbXBvc2l0ZSBWYXJpYWJsZSB7LnRhYnNldH0KCiMjIFBzeWNoIHsudGFic2V0fQoKPGlmcmFtZSB3aWR0aD0iNTYwIiBoZWlnaHQ9IjMxNSIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9fLU1ISDVIRVMwOCIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhdXRvcGxheTsgZW5jcnlwdGVkLW1lZGlhIiBhbGxvd2Z1bGxzY3JlZW4+PC9pZnJhbWU+CgpEb2N1bWVudGF0aW9uIGNhbiBiZSB2aWV3ZWQgW2hlcmVdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9wc3ljaC92ZXJzaW9ucy8xLjguNC90b3BpY3Mvc2NvcmVJdGVtcykKCiMjIyBFeHRyYXZlcnNpb24KYGBge3J9CiNjcmVhdGUgZGF0YWZyYW1lIHdpdGggb25seSByZWxldmFudCB2YXJpYWJsZXMgdG8gd29yayB3aXRoCkV4dHJhdmVyc2lvbiA8LSBkYXRhLmZyYW1lIChkYXRhc2V0JEZGTV8xLCBkYXRhc2V0JEZGTV82LCBkYXRhc2V0JEZGTV8xMSwgZGF0YXNldCRGRk1fMTYsIGRhdGFzZXQkRkZNXzIxLCBkYXRhc2V0JEZGTV8yNiwgZGF0YXNldCRGRk1fMzEsIGRhdGFzZXQkRkZNXzM2KQojY3JlYXRlIGxpc3Qgb2YgJ2tleXMnLiBUaGUgIG51bWJlcnMganVzdCByZWZlciB0byB0aGUgb3JkZXIgb2YgdGhlIHF1ZXN0aW9uIGluIHRoZSBkYXRhLmZyYW1lKCkgeW91IGp1c3QgbWFkZS4gVGhlIG1vc3QgaW1wb3J0YW50IHRoaW5nIGlzIHRvIG1hcmsgdGhlIHF1ZXN0aW9ucyB0aGF0IHNob3VsZCBiZSByZXZlcnNlZCBzY29yZWQgd2l0aCBhICctJy4gCkV4dHJhdmVyc2lvbi5rZXlzIDwtIG1ha2Uua2V5cyhFeHRyYXZlcnNpb24sIGxpc3QoRXh0cmF2ZXJzaW9uPWMoMSwtMiwzLDQsLTUsNiwtNyw4KSkpCiNzY29yZSB0aGUgc2NhbGUKRXh0cmF2ZXJzaW9uLnNjYWxlcyA8LSBzY29yZUl0ZW1zIChFeHRyYXZlcnNpb24ua2V5cywgRXh0cmF2ZXJzaW9uKQojc2F2ZSB0aGUgc2NvcmVzCkV4dHJhdmVyc2lvbi5zY29yZXMgPC0gRXh0cmF2ZXJzaW9uLnNjYWxlcyRzY29yZXMKI3NhdmUgdGhlIHNjb3JlcyBiYWNrIGluICdkYXRhc2V0JwpkYXRhc2V0JEV4dHJhdmVyc2lvbiA8LSBFeHRyYXZlcnNpb24uc2NvcmVzWyxdCiNwcmludCB0aGUgY3JvbmJhY2ggYWxwaGEKRXh0cmF2ZXJzaW9uLnNjYWxlcyRhbHBoYQpgYGAKIyMjIEFncmVlYWJsZW5lc3MKYGBge3J9CiNjcmVhdGUgZGF0YWZyYW1lIHdpdGggb25seSByZWxldmFudCB2YXJpYWJsZXMgdG8gd29yayB3aXRoCkFncmVlYWJsZW5lc3MgPC0gZGF0YS5mcmFtZSAoZGF0YXNldCRGRk1fMiwgZGF0YXNldCRGRk1fNywgZGF0YXNldCRGRk1fMTIsIGRhdGFzZXQkRkZNXzE3LCBkYXRhc2V0JEZGTV8yMiwgZGF0YXNldCRGRk1fMjcsIGRhdGFzZXQkRkZNXzMyLCBkYXRhc2V0JEZGTV8zNywgZGF0YXNldCRGRk1fNDIpCkFncmVlYWJsZW5lc3Mua2V5cyA8LSBtYWtlLmtleXMoQWdyZWVhYmxlbmVzcywgbGlzdChBZ3JlZWFibGVuZXNzPWMoLTEsMiwtMyw0LDUsLTYsNywtOCw5KSkpCkFncmVlYWJsZW5lc3Muc2NhbGVzIDwtIHNjb3JlSXRlbXMgKEFncmVlYWJsZW5lc3Mua2V5cywgQWdyZWVhYmxlbmVzcykKQWdyZWVhYmxlbmVzcy5zY29yZXMgPC0gQWdyZWVhYmxlbmVzcy5zY2FsZXMkc2NvcmVzCmRhdGFzZXQkQWdyZWVhYmxlbmVzcyA8LSBBZ3JlZWFibGVuZXNzLnNjb3Jlc1ssXQpBZ3JlZWFibGVuZXNzLnNjYWxlcyRhbHBoYQpgYGAKIyMjIENvbnNjaWVudGlvdXNuZXNzCmBgYHtyfQojY3JlYXRlIGRhdGFmcmFtZSB3aXRoIG9ubHkgcmVsZXZhbnQgdmFyaWFibGVzIHRvIHdvcmsgd2l0aApDb25zY2llbnRpb3VzbmVzcyA8LSBkYXRhLmZyYW1lIChkYXRhc2V0JEZGTV8zLCBkYXRhc2V0JEZGTV84LCBkYXRhc2V0JEZGTV8xMywgZGF0YXNldCRGRk1fMTgsIGRhdGFzZXQkRkZNXzIzLCBkYXRhc2V0JEZGTV8yOCwgZGF0YXNldCRGRk1fMzMsIGRhdGFzZXQkRkZNXzM4LCBkYXRhc2V0JEZGTV80MykKbXkua2V5cyA8LSBtYWtlLmtleXMoQ29uc2NpZW50aW91c25lc3MsIGxpc3QoQ29uc2NpZW50aW91c25lc3M9YygxLC0yLDMsLTQsLTUsNiw3LDgsLTkpKSkKbXkuc2NhbGVzIDwtIHNjb3JlSXRlbXMgKG15LmtleXMsIENvbnNjaWVudGlvdXNuZXNzKQpteS5zY29yZXMgPC0gbXkuc2NhbGVzJHNjb3JlcwpkYXRhc2V0JENvbnNjaWVudGlvdXNuZXNzIDwtIG15LnNjb3Jlc1ssXQpteS5zY2FsZXMkYWxwaGEKYGBgCiMjIyBOZXVyb3RpY2lzbQpgYGB7cn0KI2NyZWF0ZSBkYXRhZnJhbWUgd2l0aCBvbmx5IHJlbGV2YW50IHZhcmlhYmxlcyB0byB3b3JrIHdpdGgKTmV1cm90aWNpc20gPC0gZGF0YS5mcmFtZSAoZGF0YXNldCRGRk1fNCwgZGF0YXNldCRGRk1fOSwgZGF0YXNldCRGRk1fMTQsIGRhdGFzZXQkRkZNXzE5LCBkYXRhc2V0JEZGTV8yNCwgZGF0YXNldCRGRk1fMjksIGRhdGFzZXQkRkZNXzM0LCBkYXRhc2V0JEZGTV8zOSkKbXkua2V5cyA8LSBtYWtlLmtleXMoTmV1cm90aWNpc20sIGxpc3QoTmV1cm90aWNpc209YygxLC0yLDMsNCwtNSw2LC03LDgpKSkKbXkuc2NhbGVzIDwtIHNjb3JlSXRlbXMgKG15LmtleXMsIE5ldXJvdGljaXNtKQpteS5zY29yZXMgPC0gbXkuc2NhbGVzJHNjb3JlcwpkYXRhc2V0JE5ldXJvdGljaXNtIDwtIG15LnNjb3Jlc1ssXQpteS5zY2FsZXMkYWxwaGEKYGBgCiMjIyBPcGVubmVzcwpgYGB7cn0KI2NyZWF0ZSBkYXRhZnJhbWUgd2l0aCBvbmx5IHJlbGV2YW50IHZhcmlhYmxlcyB0byB3b3JrIHdpdGgKT3Blbm5lc3MgPC0gZGF0YS5mcmFtZSAoZGF0YXNldCRGRk1fNSwgZGF0YXNldCRGRk1fMTAsIGRhdGFzZXQkRkZNXzE1LCBkYXRhc2V0JEZGTV8yMCwgZGF0YXNldCRGRk1fMjUsIGRhdGFzZXQkRkZNXzMwLCBkYXRhc2V0JEZGTV8zNSwgZGF0YXNldCRGRk1fNDAsIGRhdGFzZXQkRkZNXzQxLCBkYXRhc2V0JEZGTV80NCkKbXkua2V5cyA8LSBtYWtlLmtleXMoT3Blbm5lc3MsIGxpc3QoT3Blbm5lc3M9YygxLDIsMyw0LDUsNiwtNyw4LC05LDEwKSkpCm15LnNjYWxlcyA8LSBzY29yZUl0ZW1zIChteS5rZXlzLCBPcGVubmVzcykKbXkuc2NvcmVzIDwtIG15LnNjYWxlcyRzY29yZXMKZGF0YXNldCRPcGVubmVzcyA8LSBteS5zY29yZXNbLF0KbXkuc2NhbGVzJGFscGhhCmBgYAojIyBUaWR5dmVyc2UKCjxpZnJhbWUgd2lkdGg9IjU2MCIgaGVpZ2h0PSIzMTUiIHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vZW1iZWQvNXdndnc4VlUxakUiIGZyYW1lYm9yZGVyPSIwIiBhbGxvdz0iYXV0b3BsYXk7IGVuY3J5cHRlZC1tZWRpYSIgYWxsb3dmdWxsc2NyZWVuPjwvaWZyYW1lPgoKRG9jdW1lbnRhdGlvbiBjYW4gYmUgdmlld2VkIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvZHBseXIvdmVyc2lvbnMvMC43LjYvdG9waWNzL3Jvd3dpc2UpIGFuZCBbaGVyZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL3BseXIvdmVyc2lvbnMvMS44LjQvdG9waWNzL211dGF0ZSkKCmBgYHtyfQpkYXRhc2V0ICU+JQogIHJvd3dpc2UoKSAlPiUKICBtdXRhdGUoZXh0cmF2ZXJzaW9uVGlkeSA9IG1lYW4oYyhGRk1fMSwgNi1GRk1fNiwgRkZNXzExLCBGRk1fMTYsIDYtRkZNXzIxLCBGRk1fMjYsIDYtRkZNXzMxLCBGRk1fMzYpKSkgLT4gZGF0YXNldApgYGAKIyBDb3JyZWxhdGlvbnMgey50YWJzZXR9CgojIyBDYWxjdWxhdGUgY29ycmVsYXRpb25zIHsudGFic2V0fQo8aWZyYW1lIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkL1lOdkdhYjRnTXZNIiBmcmFtZWJvcmRlcj0iMCIgYWxsb3c9ImF1dG9wbGF5OyBlbmNyeXB0ZWQtbWVkaWEiIGFsbG93ZnVsbHNjcmVlbj48L2lmcmFtZT4KIyMjIEV4cGxvcmUgY29ycmVsYXRpb25zCkRvY3VtZW50YXRpb24gY2FuIGJlIHZpZXdlZCBbaGVyZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL2NvcnJyL3ZlcnNpb25zLzAuMy4wL3ZpZ25ldHRlcy91c2luZy1jb3Jyci5SbWQpIAoKYGBge3J9CmRhdGFzZXQgJT4lCiAgc2VsZWN0KE9wZW5uZXNzLCBDb25zY2llbnRpb3VzbmVzcywgRXh0cmF2ZXJzaW9uLCBBZ3JlZWFibGVuZXNzLCBOZXVyb3RpY2lzbSkgJT4lCiAgY29ycmVsYXRlKCkgJT4lCiAgc2hhdmUoKSAlPiUKICBmYXNoaW9uKCkKYGBgCiMjIyBDYWxjdWxhdGUgcC12YWx1ZXMKRG9jdW1lbnRhdGlvbiBjYW4gYmUgdmlld2VkIFtoZXJlXShodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvcHN5Y2gvdmVyc2lvbnMvMS44LjQvdG9waWNzL2NvcnIudGVzdCkgCgpgYGB7cn0KZGF0YXNldCAlPiUKICBzZWxlY3QoT3Blbm5lc3MsIENvbnNjaWVudGlvdXNuZXNzLCBFeHRyYXZlcnNpb24sIEFncmVlYWJsZW5lc3MsIE5ldXJvdGljaXNtKSAtPiBCaWc1ZGYKCmNvcnIudGVzdCh4ID0gQmlnNWRmLCAKICAgICAgICAgIHkgPSBOVUxMLAogICAgICAgICAgdXNlID0gInBhaXJ3aXNlIiwKICAgICAgICAgIG1ldGhvZCA9ICJwZWFyc29uIiwKICAgICAgICAgIGFkanVzdCA9ICJob2xtIiwgCiAgICAgICAgICBhbHBoYSA9IC4wNSwKICAgICAgICAgIGNpID0gVFJVRSkKCmBgYAojIyBEZWNpZGluZyBiZXR3ZWVuIFBlYXJzb24gYW5kIFNwZWFybWFuIGNvcnJlbGF0aW9ucwoKPGlmcmFtZSB3aWR0aD0iNTYwIiBoZWlnaHQ9IjMxNSIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9zRnNvWGJKODVsdyIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhdXRvcGxheTsgZW5jcnlwdGVkLW1lZGlhIiBhbGxvd2Z1bGxzY3JlZW4+PC9pZnJhbWU+CkRvY3VtZW50YXRpb24gY2FuIGJlIHZpZXdlZCBbaGVyZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL0dHYWxseS92ZXJzaW9ucy8xLjQuMC90b3BpY3MvZ2dwYWlycykgCgpgYGB7cn0KZGF0YXNldCAlPiUKICBzZWxlY3QoT3Blbm5lc3MsIENvbnNjaWVudGlvdXNuZXNzLCBFeHRyYXZlcnNpb24sIEFncmVlYWJsZW5lc3MsIE5ldXJvdGljaXNtKSAlPiUKICBnZ3BhaXJzKCkKYGBgCiMgKnQqLXRlc3RzIHsudGFic2V0fQpEb2N1bWVudGF0aW9uIGNhbiBiZSB2aWV3ZWQgW2hlcmVdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9zdGF0cy92ZXJzaW9ucy8zLjUuMS90b3BpY3MvdC50ZXN0KSAKCiMjIGluZGVwZW5kZW50IHNhbXBsZXMgKnQqLXRlc3RzCgo8aWZyYW1lIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkL01mRU9hdE0zZGhjIiBmcmFtZWJvcmRlcj0iMCIgYWxsb3c9ImF1dG9wbGF5OyBlbmNyeXB0ZWQtbWVkaWEiIGFsbG93ZnVsbHNjcmVlbj48L2lmcmFtZT4KYGBge3J9CmRhdGFzZXQgJT4lCiAgd2l0aCh0LnRlc3QoQWdyZWVhYmxlbmVzcyB+IENvaW5GbGlwRmFjdG9yKSkKYGBgCgojIyBwYWlyZWQgc2FtcGxlcyAqdCotdGVzdHMKCjxpZnJhbWUgd2lkdGg9IjU2MCIgaGVpZ2h0PSIzMTUiIHNyYz0iaHR0cHM6Ly93d3cueW91dHViZS5jb20vZW1iZWQvbkk2eGdkUC1tTFUiIGZyYW1lYm9yZGVyPSIwIiBhbGxvdz0iYXV0b3BsYXk7IGVuY3J5cHRlZC1tZWRpYSIgYWxsb3dmdWxsc2NyZWVuPjwvaWZyYW1lPgpgYGB7cn0KZGF0YXNldCAlPiUKICB3aXRoKHQudGVzdChBZ3JlZWFibGVuZXNzLCBOZXVyb3RpY2lzbSwgcGFpcmVkID0gVFJVRSkpCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg==