2: R中数据类型

向量,矩阵,数组,数据框,Factor,列表,字符串

2.1 向量

在R中向量可以通过多种方式生成,并且向量也可以包含多种模式,如一个向量的每个元素都可以是字符串,向量也可以是一个因子。

## 向量的生成
## 1:通过":"产生
A <- 1:5
A
## 1:通过c()函数产生
A <- c(1,3,5,7,9)
A
## 2:通过seq()函数指定步长生成
B = seq(from=2,to=10,by=2)
B
## 2:通过seq()函数指定数目生成
B = seq(from=2,to=10,length.out=5)
B
## 4: 通过rep()函数生成具有重复元素的向量
C <- rep(1:2,5)
C
## 4: 也可以分别指定每个元素的重复次数
C <- rep(1:2,c(2,3))
C

向量中的元素,不仅可以为数字,也可以是字符串、TRUE或者FALISE等,同时向量也可以是一个因子向量

## 字符串向量
v_char<- c("A","B","C","D","E")
class(v_char)

## 逻辑向量
v_log <- rep(c(T,F),c(2,3))
v_log
class(v_log)

##因子形式的向量
v_fac <- factor(x=c("A","B","C","A","C"),levels = c("A","B","C"),labels = c("A","B","C"))
v_fac
levels(v_fac)

## 因子向量重新排序
v_fac<-ordered(v_fac,c("C","B","A"))
v_fac
levels(v_fac)
                

向量的简单计算和获取指定位置的元素


## 向量如果进行四则运算,竟会使用整个向量进行运算
vec <- seq(1,7)
vec
## 进行除法运算
vec/2
## 如果两个向量长度相等,则对应位置的元素进行运算
vec / (2*vec)
## 计算向量的累乘
cumprod(1:5)
## 计算向量的累加
cumsum(vec)

## 计算向量的长度
length(vec)

## 从向量中获取需要的元素,可以使用在中括号指定位置
vec[c(1,3,5,7,9)]

## 从向量中获取需要的元素,可以使用等长的逻辑向量
## 获取vec中能被3整除的元素
vec %% 3 == 0
vec[vec %% 3 == 0]


## 在 [] 中使用一号可以删除指定位置的元素
vec[c(-1,-5)]
## 给出向量的倒序
rev(vec)
## 给出符合条件元素所在的位置
which(vec %% 2 ==1)

## 数字向量转化为字符串向量
vec_num <- seq(from=2,to=10,by=2)
str(vec_num)
vec_char <- as.character(vec_num)
str(vec_char)
## 字符串向量转化为numeric
vec_num<-as.numeric(vec_char)
is.numeric(vec_num)

## 因子向量转化为字符串向量
vec_fac <- factor(c("A","B","C","A","C"))
str(vec_fac)
vec_fac2char <- as.character(vec_fac)
str(vec_fac2char)

## 查看向量的取值
unique(vec_fac2char)

## 查看每种取值的个数
table(vec_fac2char)

## 计算两个向量的并集
union(c(1:5),seq(2,10,2))

## 计算两个向量的差集
setdiff(c(1:5),seq(2,10,2))

##计算两个向量的交集
intersect(c(1:5),seq(2,10,2))

## 序列1是否是序列2中的元素
is.element(c(1:5),seq(2,10,2))

## 也可以使 %in%
c(1:5) %in% seq(2,10,2)

2.2 矩阵

向量属于一维数组,在R中矩阵二维数组可以使用matrix()函数生成

## 1 矩阵的生成
## 使用向量生成矩阵
vec <- seq(1,12)
mat <- matrix(vec,nrow = 2)
mat

mat <- matrix(vec,ncol = 4)
mat

## 生成矩阵时优先排列行
mat <- matrix(vec,nrow = 2,ncol = 4,byrow = TRUE)
mat

## 2 使用cbind()按照列连接多个向量
mat <- cbind(c(1,3,5,7),c(2,4,6,8),c(1:4))
mat

## 使用rbind()按照行连接多个向量
mat <- rbind(c(1,3,5,7),c(2,4,6,8),c(1:4))
mat

## 使用diag生成单位矩阵
diag(4)

## 也可以指定对角元素的内容
diag(c(1:4))

## 为矩阵添加列名和行名
colnames(mat) <- c("A","B","C","D")
rownames(mat) <- c("a","b","c")
mat

## 查看矩阵的维度
dim(mat)

## 计算矩阵有多少行
nrow(mat)

## 计算矩阵有多少列
ncol(mat)

## 计算矩阵的长度,即所有元素的个数
length(mat)

获取矩阵中的元素


## 可以使用 [行,列] 来获取元素
mat <- rbind(c(1,3,5,7),c(2,4,6,8),c(1:4))
colnames(mat) <- c("A","B","C","D")
rownames(mat) <- c("a","b","c")
mat

## 获取矩阵第2行第3列的元素
mat[2,3]

## 获取矩阵第2列的元素
mat[,2]

## 获取矩阵第1行的元素
mat[1,]

## 获取矩阵第"A","C"列的元素
mat[,c("A","C")]

## 通过逻辑值获取需要的元素,获取矩阵中的偶数
mat %% 2 == 0
mat[mat %% 2 ==0]

矩阵的运算

mat <- matrix(c(1:12),nrow = 3)
mat

## 矩阵的转置
t(mat)

## 矩阵的行和
rowSums(mat)
apply(mat,1,sum)

## 矩阵的列和
colSums(mat)
apply(mat,2,sum)
## 矩阵的行均值
rowMeans(mat)
## 矩阵的列均值
colMeans(mat)

## 矩阵与矩阵相乘
## 1 :对应位置相乘
mat * mat

## 2 : 矩阵乘法
mat %*% t(mat)
mat2<- mat %*% t(mat)
mat2

## 得到上三角矩阵
mat2[lower.tri(mat2)]<-0
mat2

## 计算矩阵的行列式
mat3 <- cbind(1,2:4,c(2,4,1))
mat3
det(mat3)

## 计算矩阵的对角线元素
diag(mat3)

## 矩阵的逆矩阵,求解ax=b,默认b=I(单位矩阵)
set.seed(123)
solve(matrix(runif(16),4,4))

高维数组

## 使用array生成3维数组
arr <- array(1:24,dim = c(3,4,2))
arr

## 获取数组中的元素
## 第2层数据中的第二行的内容
arr[2,,2]

arr[which(arr %% 5 == 0)]

dim(arr)
## 对数据的每层计算均值
apply(arr,3,mean)
## 对数据的第二维度,列数据求和
apply(arr,2,sum)

数据框


## 生成数据框
df <- data.frame(id=c("A","B","C","D"),
                 age=c(10,15,9,12),
                 sex=c("F","M","M","F"),
                 score=c(17:20),
                 stringsAsFactors = FALSE
                 )
head(df)

## 查看数据的汇总
summary(df)

## 将sex转化为因子
df$sex<-factor(df$sex)

## 查看数据的汇总
str(df)

## 通过矩阵生成数据框
mat <- rbind(c(1,3,5,7),c(2,4,6,8),c(1:4))
mat2df <- as.data.frame(mat)
colnames(mat2df)<- c("A","B","C","D")
mat2df

选取数据框中的元素

## 通过[] 选择
df[,2]
## 通过$选择
df$id
## 获取id下的第3个元素
df$id[3]
## 通过变量的名称选择
df[c("id","age")]
## 通过行索引来选择指定的行
df[df$age>10,]
## 可以通过with函数取消$的使用
with(df,age>10)
## 使用逻辑值进行索引
df[df$id %in% c("B","D","F"),1:3]
## 为数据框添加新的变量
df$newvar<-df$score*2

列表

列表可以容纳任何类型和结构的数据


## 生成list

A <- factor(c("A","B","C","C","B"))
B <- matrix(seq(1:8),nrow=2)
C <- "Type"
D <- data.frame(id=c("A","B","C","D"),
                age=c(10,15,9,12))

## 使用A,B,C,D生成一个列表
mylist<- list(A,B,C,D)

mylist

str(mylist)

## 获取列表中的内容
## 1 使用 []
mylist[1]
mylist[[1]]
mylist[[2]][2,1:3]
mylist[[4]]$age[1:3]

##给列表中的内容添加名字
names(mylist)<-c("one","two","three","four")
names(mylist)
## 通过$来提取数据
mylist$one
LS0tDQp0aXRsZTogIlLor63oqIDlhaXpl6giDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KICANCiMjIDI6IFLkuK3mlbDmja7nsbvlnosNCiAgDQojIyMg5ZCR6YeP77yM55+p6Zi177yM5pWw57uE77yM5pWw5o2u5qGG77yMRmFjdG9y77yM5YiX6KGo77yM5a2X56ym5LiyDQogIA0KIyMjIDIuMSDlkJHph48NCg0K5ZyoUuS4reWQkemHj+WPr+S7pemAmui/h+WkmuenjeaWueW8j+eUn+aIkO+8jOW5tuS4lOWQkemHj+S5n+WPr+S7peWMheWQq+WkmuenjeaooeW8j++8jOWmguS4gOS4quWQkemHj+eahOavj+S4quWFg+e0oOmDveWPr+S7peaYr+Wtl+espuS4su+8jOWQkemHj+S5n+WPr+S7peaYr+S4gOS4quWboOWtkOOAgg0KDQpgYGB7cn0NCiMjIOWQkemHj+eahOeUn+aIkA0KIyMgMTrpgJrov4ciOiLkuqfnlJ8NCkEgPC0gMTo1DQpBDQojIyAxOumAmui/h2MoKeWHveaVsOS6p+eUnw0KQSA8LSBjKDEsMyw1LDcsOSkNCkENCiMjIDI66YCa6L+Hc2VxKCnlh73mlbDmjIflrprmraXplb/nlJ/miJANCkIgPSBzZXEoZnJvbT0yLHRvPTEwLGJ5PTIpDQpCDQojIyAyOumAmui/h3NlcSgp5Ye95pWw5oyH5a6a5pWw55uu55Sf5oiQDQpCID0gc2VxKGZyb209Mix0bz0xMCxsZW5ndGgub3V0PTUpDQpCDQojIyA0OiDpgJrov4dyZXAoKeWHveaVsOeUn+aIkOWFt+aciemHjeWkjeWFg+e0oOeahOWQkemHjw0KQyA8LSByZXAoMToyLDUpDQpDDQojIyA0OiDkuZ/lj6/ku6XliIbliKvmjIflrprmr4/kuKrlhYPntKDnmoTph43lpI3mrKHmlbANCkMgPC0gcmVwKDE6MixjKDIsMykpDQpDDQpgYGANCg0K5ZCR6YeP5Lit55qE5YWD57Sg77yM5LiN5LuF5Y+v5Lul5Li65pWw5a2X77yM5Lmf5Y+v5Lul5piv5a2X56ym5Liy44CBVFJVReaIluiAhUZBTElTReetie+8jOWQjOaXtuWQkemHj+S5n+WPr+S7peaYr+S4gOS4quWboOWtkOWQkemHjw0KDQpgYGB7cn0NCiMjIOWtl+espuS4suWQkemHjw0Kdl9jaGFyPC0gYygiQSIsIkIiLCJDIiwiRCIsIkUiKQ0KY2xhc3Modl9jaGFyKQ0KDQojIyDpgLvovpHlkJHph48NCnZfbG9nIDwtIHJlcChjKFQsRiksYygyLDMpKQ0Kdl9sb2cNCmNsYXNzKHZfbG9nKQ0KDQojI+WboOWtkOW9ouW8j+eahOWQkemHjw0Kdl9mYWMgPC0gZmFjdG9yKHg9YygiQSIsIkIiLCJDIiwiQSIsIkMiKSxsZXZlbHMgPSBjKCJBIiwiQiIsIkMiKSxsYWJlbHMgPSBjKCJBIiwiQiIsIkMiKSkNCnZfZmFjDQpsZXZlbHModl9mYWMpDQoNCiMjIOWboOWtkOWQkemHj+mHjeaWsOaOkuW6jw0Kdl9mYWM8LW9yZGVyZWQodl9mYWMsYygiQyIsIkIiLCJBIikpDQp2X2ZhYw0KbGV2ZWxzKHZfZmFjKQ0KICAgICAgICAgICAgICAgIA0KYGBgDQoNCuWQkemHj+eahOeugOWNleiuoeeul+WSjOiOt+WPluaMh+WumuS9jee9rueahOWFg+e0oA0KDQpgYGB7cn0NCg0KIyMg5ZCR6YeP5aaC5p6c6L+b6KGM5Zub5YiZ6L+Q566X77yM56uf5Lya5L2/55So5pW05Liq5ZCR6YeP6L+b6KGM6L+Q566XDQp2ZWMgPC0gc2VxKDEsNykNCnZlYw0KIyMg6L+b6KGM6Zmk5rOV6L+Q566XDQp2ZWMvMg0KIyMg5aaC5p6c5Lik5Liq5ZCR6YeP6ZW/5bqm55u4562J77yM5YiZ5a+55bqU5L2N572u55qE5YWD57Sg6L+b6KGM6L+Q566XDQp2ZWMgLyAoMip2ZWMpDQojIyDorqHnrpflkJHph4/nmoTntK/kuZgNCmN1bXByb2QoMTo1KQ0KIyMg6K6h566X5ZCR6YeP55qE57Sv5YqgDQpjdW1zdW0odmVjKQ0KDQojIyDorqHnrpflkJHph4/nmoTplb/luqYNCmxlbmd0aCh2ZWMpDQoNCiMjIOS7juWQkemHj+S4reiOt+WPlumcgOimgeeahOWFg+e0oO+8jOWPr+S7peS9v+eUqOWcqOS4reaLrOWPt+aMh+WumuS9jee9rg0KdmVjW2MoMSwzLDUsNyw5KV0NCg0KIyMg5LuO5ZCR6YeP5Lit6I635Y+W6ZyA6KaB55qE5YWD57Sg77yM5Y+v5Lul5L2/55So562J6ZW/55qE6YC76L6R5ZCR6YePDQojIyDojrflj5Z2ZWPkuK3og73ooqsz5pW06Zmk55qE5YWD57SgDQp2ZWMgJSUgMyA9PSAwDQp2ZWNbdmVjICUlIDMgPT0gMF0NCg0KDQojIyDlnKggW10g5Lit5L2/55So5LiA5Y+35Y+v5Lul5Yig6Zmk5oyH5a6a5L2N572u55qE5YWD57SgDQp2ZWNbYygtMSwtNSldDQojIyDnu5nlh7rlkJHph4/nmoTlgJLluo8NCnJldih2ZWMpDQojIyDnu5nlh7rnrKblkIjmnaHku7blhYPntKDmiYDlnKjnmoTkvY3nva4NCndoaWNoKHZlYyAlJSAyID09MSkNCg0KIyMg5pWw5a2X5ZCR6YeP6L2s5YyW5Li65a2X56ym5Liy5ZCR6YePDQp2ZWNfbnVtIDwtIHNlcShmcm9tPTIsdG89MTAsYnk9MikNCnN0cih2ZWNfbnVtKQ0KdmVjX2NoYXIgPC0gYXMuY2hhcmFjdGVyKHZlY19udW0pDQpzdHIodmVjX2NoYXIpDQojIyDlrZfnrKbkuLLlkJHph4/ovazljJbkuLpudW1lcmljDQp2ZWNfbnVtPC1hcy5udW1lcmljKHZlY19jaGFyKQ0KaXMubnVtZXJpYyh2ZWNfbnVtKQ0KDQojIyDlm6DlrZDlkJHph4/ovazljJbkuLrlrZfnrKbkuLLlkJHph48NCnZlY19mYWMgPC0gZmFjdG9yKGMoIkEiLCJCIiwiQyIsIkEiLCJDIikpDQpzdHIodmVjX2ZhYykNCnZlY19mYWMyY2hhciA8LSBhcy5jaGFyYWN0ZXIodmVjX2ZhYykNCnN0cih2ZWNfZmFjMmNoYXIpDQoNCiMjIOafpeeci+WQkemHj+eahOWPluWAvA0KdW5pcXVlKHZlY19mYWMyY2hhcikNCg0KIyMg5p+l55yL5q+P56eN5Y+W5YC855qE5Liq5pWwDQp0YWJsZSh2ZWNfZmFjMmNoYXIpDQoNCiMjIOiuoeeul+S4pOS4quWQkemHj+eahOW5tumbhg0KdW5pb24oYygxOjUpLHNlcSgyLDEwLDIpKQ0KDQojIyDorqHnrpfkuKTkuKrlkJHph4/nmoTlt67pm4YNCnNldGRpZmYoYygxOjUpLHNlcSgyLDEwLDIpKQ0KDQojI+iuoeeul+S4pOS4quWQkemHj+eahOS6pOmbhg0KaW50ZXJzZWN0KGMoMTo1KSxzZXEoMiwxMCwyKSkNCg0KIyMg5bqP5YiXMeaYr+WQpuaYr+W6j+WIlzLkuK3nmoTlhYPntKANCmlzLmVsZW1lbnQoYygxOjUpLHNlcSgyLDEwLDIpKQ0KDQojIyDkuZ/lj6/ku6Xkvb8gJWluJQ0KYygxOjUpICVpbiUgc2VxKDIsMTAsMikNCg0KYGBgDQoNCiMjIyAyLjIg55+p6Zi1DQoNCuWQkemHj+WxnuS6juS4gOe7tOaVsOe7hO+8jOWcqFLkuK3nn6npmLXkuoznu7TmlbDnu4Tlj6/ku6Xkvb/nlKhtYXRyaXgoKeWHveaVsOeUn+aIkA0KDQpgYGB7cn0NCiMjIDEg55+p6Zi155qE55Sf5oiQDQojIyDkvb/nlKjlkJHph4/nlJ/miJDnn6npmLUNCnZlYyA8LSBzZXEoMSwxMikNCm1hdCA8LSBtYXRyaXgodmVjLG5yb3cgPSAyKQ0KbWF0DQoNCm1hdCA8LSBtYXRyaXgodmVjLG5jb2wgPSA0KQ0KbWF0DQoNCiMjIOeUn+aIkOefqemYteaXtuS8mOWFiOaOkuWIl+ihjA0KbWF0IDwtIG1hdHJpeCh2ZWMsbnJvdyA9IDIsbmNvbCA9IDQsYnlyb3cgPSBUUlVFKQ0KbWF0DQoNCiMjIDIg5L2/55SoY2JpbmQoKeaMieeFp+WIl+i/nuaOpeWkmuS4quWQkemHjw0KbWF0IDwtIGNiaW5kKGMoMSwzLDUsNyksYygyLDQsNiw4KSxjKDE6NCkpDQptYXQNCg0KIyMg5L2/55SocmJpbmQoKeaMieeFp+ihjOi/nuaOpeWkmuS4quWQkemHjw0KbWF0IDwtIHJiaW5kKGMoMSwzLDUsNyksYygyLDQsNiw4KSxjKDE6NCkpDQptYXQNCg0KIyMg5L2/55SoZGlhZ+eUn+aIkOWNleS9jeefqemYtQ0KZGlhZyg0KQ0KDQojIyDkuZ/lj6/ku6XmjIflrprlr7nop5LlhYPntKDnmoTlhoXlrrkNCmRpYWcoYygxOjQpKQ0KDQojIyDkuLrnn6npmLXmt7vliqDliJflkI3lkozooYzlkI0NCmNvbG5hbWVzKG1hdCkgPC0gYygiQSIsIkIiLCJDIiwiRCIpDQpyb3duYW1lcyhtYXQpIDwtIGMoImEiLCJiIiwiYyIpDQptYXQNCg0KIyMg5p+l55yL55+p6Zi155qE57u05bqmDQpkaW0obWF0KQ0KDQojIyDorqHnrpfnn6npmLXmnInlpJrlsJHooYwNCm5yb3cobWF0KQ0KDQojIyDorqHnrpfnn6npmLXmnInlpJrlsJHliJcNCm5jb2wobWF0KQ0KDQojIyDorqHnrpfnn6npmLXnmoTplb/luqbvvIzljbPmiYDmnInlhYPntKDnmoTkuKrmlbANCmxlbmd0aChtYXQpDQoNCmBgYA0KDQrojrflj5bnn6npmLXkuK3nmoTlhYPntKANCg0KYGBge3J9DQoNCiMjIOWPr+S7peS9v+eUqCBb6KGMLOWIl10g5p2l6I635Y+W5YWD57SgDQptYXQgPC0gcmJpbmQoYygxLDMsNSw3KSxjKDIsNCw2LDgpLGMoMTo0KSkNCmNvbG5hbWVzKG1hdCkgPC0gYygiQSIsIkIiLCJDIiwiRCIpDQpyb3duYW1lcyhtYXQpIDwtIGMoImEiLCJiIiwiYyIpDQptYXQNCg0KIyMg6I635Y+W55+p6Zi156ysMuihjOesrDPliJfnmoTlhYPntKANCm1hdFsyLDNdDQoNCiMjIOiOt+WPluefqemYteesrDLliJfnmoTlhYPntKANCm1hdFssMl0NCg0KIyMg6I635Y+W55+p6Zi156ysMeihjOeahOWFg+e0oA0KbWF0WzEsXQ0KDQojIyDojrflj5bnn6npmLXnrKwiQSIsIkMi5YiX55qE5YWD57SgDQptYXRbLGMoIkEiLCJDIildDQoNCiMjIOmAmui/h+mAu+i+keWAvOiOt+WPlumcgOimgeeahOWFg+e0oO+8jOiOt+WPluefqemYteS4reeahOWBtuaVsA0KbWF0ICUlIDIgPT0gMA0KbWF0W21hdCAlJSAyID09MF0NCg0KDQpgYGANCg0K55+p6Zi155qE6L+Q566XDQoNCmBgYHtyfQ0KbWF0IDwtIG1hdHJpeChjKDE6MTIpLG5yb3cgPSAzKQ0KbWF0DQoNCiMjIOefqemYteeahOi9rOe9rg0KdChtYXQpDQoNCiMjIOefqemYteeahOihjOWSjA0Kcm93U3VtcyhtYXQpDQphcHBseShtYXQsMSxzdW0pDQoNCiMjIOefqemYteeahOWIl+WSjA0KY29sU3VtcyhtYXQpDQphcHBseShtYXQsMixzdW0pDQojIyDnn6npmLXnmoTooYzlnYflgLwNCnJvd01lYW5zKG1hdCkNCiMjIOefqemYteeahOWIl+Wdh+WAvA0KY29sTWVhbnMobWF0KQ0KDQojIyDnn6npmLXkuI7nn6npmLXnm7jkuZgNCiMjIDEg77ya5a+55bqU5L2N572u55u45LmYDQptYXQgKiBtYXQNCg0KIyMgMiA6IOefqemYteS5mOazlQ0KbWF0ICUqJSB0KG1hdCkNCm1hdDI8LSBtYXQgJSolIHQobWF0KQ0KbWF0Mg0KDQojIyDlvpfliLDkuIrkuInop5Lnn6npmLUNCm1hdDJbbG93ZXIudHJpKG1hdDIpXTwtMA0KbWF0Mg0KDQojIyDorqHnrpfnn6npmLXnmoTooYzliJflvI8NCm1hdDMgPC0gY2JpbmQoMSwyOjQsYygyLDQsMSkpDQptYXQzDQpkZXQobWF0MykNCg0KIyMg6K6h566X55+p6Zi155qE5a+56KeS57q/5YWD57SgDQpkaWFnKG1hdDMpDQoNCiMjIOefqemYteeahOmAhuefqemYte+8jOaxguino2F4PWIs6buY6K6kYj1JKOWNleS9jeefqemYtSkNCnNldC5zZWVkKDEyMykNCnNvbHZlKG1hdHJpeChydW5pZigxNiksNCw0KSkNCg0KYGBgDQoNCiMjIyDpq5jnu7TmlbDnu4QNCg0KYGBge3J9DQojIyDkvb/nlKhhcnJheeeUn+aIkDPnu7TmlbDnu4QNCmFyciA8LSBhcnJheSgxOjI0LGRpbSA9IGMoMyw0LDIpKQ0KYXJyDQoNCiMjIOiOt+WPluaVsOe7hOS4reeahOWFg+e0oA0KIyMg56ysMuWxguaVsOaNruS4reeahOesrOS6jOihjOeahOWGheWuuQ0KYXJyWzIsLDJdDQoNCmFyclt3aGljaChhcnIgJSUgNSA9PSAwKV0NCg0KZGltKGFycikNCiMjIOWvueaVsOaNrueahOavj+Wxguiuoeeul+Wdh+WAvA0KYXBwbHkoYXJyLDMsbWVhbikNCiMjIOWvueaVsOaNrueahOesrOS6jOe7tOW6pu+8jOWIl+aVsOaNruaxguWSjA0KYXBwbHkoYXJyLDIsc3VtKQ0KDQpgYGANCg0KIyMjIOaVsOaNruahhg0KDQpgYGB7cn0NCg0KIyMg55Sf5oiQ5pWw5o2u5qGGDQpkZiA8LSBkYXRhLmZyYW1lKGlkPWMoIkEiLCJCIiwiQyIsIkQiKSwNCiAgICAgICAgICAgICAgICAgYWdlPWMoMTAsMTUsOSwxMiksDQogICAgICAgICAgICAgICAgIHNleD1jKCJGIiwiTSIsIk0iLCJGIiksDQogICAgICAgICAgICAgICAgIHNjb3JlPWMoMTc6MjApLA0KICAgICAgICAgICAgICAgICBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UNCiAgICAgICAgICAgICAgICAgKQ0KaGVhZChkZikNCg0KIyMg5p+l55yL5pWw5o2u55qE5rGH5oC7DQpzdW1tYXJ5KGRmKQ0KDQojIyDlsIZzZXjovazljJbkuLrlm6DlrZANCmRmJHNleDwtZmFjdG9yKGRmJHNleCkNCg0KIyMg5p+l55yL5pWw5o2u55qE5rGH5oC7DQpzdHIoZGYpDQoNCiMjIOmAmui/h+efqemYteeUn+aIkOaVsOaNruahhg0KbWF0IDwtIHJiaW5kKGMoMSwzLDUsNyksYygyLDQsNiw4KSxjKDE6NCkpDQptYXQyZGYgPC0gYXMuZGF0YS5mcmFtZShtYXQpDQpjb2xuYW1lcyhtYXQyZGYpPC0gYygiQSIsIkIiLCJDIiwiRCIpDQptYXQyZGYNCg0KYGBgDQoNCumAieWPluaVsOaNruahhuS4reeahOWFg+e0oA0KYGBge3J9DQojIyDpgJrov4dbXSDpgInmi6kNCmRmWywyXQ0KIyMg6YCa6L+HJOmAieaLqQ0KZGYkaWQNCiMjIOiOt+WPlmlk5LiL55qE56ysM+S4quWFg+e0oA0KZGYkaWRbM10NCiMjIOmAmui/h+WPmOmHj+eahOWQjeensOmAieaLqQ0KZGZbYygiaWQiLCJhZ2UiKV0NCiMjIOmAmui/h+ihjOe0ouW8leadpemAieaLqeaMh+WumueahOihjA0KZGZbZGYkYWdlPjEwLF0NCiMjIOWPr+S7pemAmui/h3dpdGjlh73mlbDlj5bmtogk55qE5L2/55SoDQp3aXRoKGRmLGFnZT4xMCkNCiMjIOS9v+eUqOmAu+i+keWAvOi/m+ihjOe0ouW8lQ0KZGZbZGYkaWQgJWluJSBjKCJCIiwiRCIsIkYiKSwxOjNdDQojIyDkuLrmlbDmja7moYbmt7vliqDmlrDnmoTlj5jph48NCmRmJG5ld3ZhcjwtZGYkc2NvcmUqMg0KDQoNCmBgYA0KDQojIyMg5YiX6KGoDQoNCuWIl+ihqOWPr+S7peWuuee6s+S7u+S9leexu+Wei+WSjOe7k+aehOeahOaVsOaNrg0KDQpgYGB7cn0NCg0KIyMg55Sf5oiQbGlzdA0KDQpBIDwtIGZhY3RvcihjKCJBIiwiQiIsIkMiLCJDIiwiQiIpKQ0KQiA8LSBtYXRyaXgoc2VxKDE6OCksbnJvdz0yKQ0KQyA8LSAiVHlwZSINCkQgPC0gZGF0YS5mcmFtZShpZD1jKCJBIiwiQiIsIkMiLCJEIiksDQogICAgICAgICAgICAgICAgYWdlPWMoMTAsMTUsOSwxMikpDQoNCiMjIOS9v+eUqEEsQixDLETnlJ/miJDkuIDkuKrliJfooagNCm15bGlzdDwtIGxpc3QoQSxCLEMsRCkNCg0KbXlsaXN0DQoNCnN0cihteWxpc3QpDQoNCiMjIOiOt+WPluWIl+ihqOS4reeahOWGheWuuQ0KIyMgMSDkvb/nlKggW10NCm15bGlzdFsxXQ0KbXlsaXN0W1sxXV0NCm15bGlzdFtbMl1dWzIsMTozXQ0KbXlsaXN0W1s0XV0kYWdlWzE6M10NCg0KIyPnu5nliJfooajkuK3nmoTlhoXlrrnmt7vliqDlkI3lrZcNCm5hbWVzKG15bGlzdCk8LWMoIm9uZSIsInR3byIsInRocmVlIiwiZm91ciIpDQpuYW1lcyhteWxpc3QpDQojIyDpgJrov4ck5p2l5o+Q5Y+W5pWw5o2uDQpteWxpc3Qkb25lDQoNCmBgYA0KDQoNCg0KDQoNCg0KDQoNCg==