1 基本的网络分析原理与代码
本部分是网络分析的基础部分,入门和基本概念等。基于的资料和代码参考有几下几个。
网络分析(1):横断面网络分析及代码实例;给出了公开的代码和数据库,便于复现和理解;参考文献
网络分析(2):桥梁分析、网络比较分析及代码实例与纵向网络分析;作为第1部分的拓展,也有相应的代码和教程复现;这个公众号关于网络分析的介绍就是这两个文章;参考文献
真的有写的这么详细的网络分析教程嘛?;原理的讲解非常清楚,但是数据和代码复现要收费,作为补充材料;
你见过有调节的网络分析吗?保姆级教程!!!,3的拓展,原理清楚,无法代码复现。补充一个有调节的网络分析——另一种方法;包括论文全文和数据代码复现材料:Effects
of an MPPI on mental health文件夹。
1.1 基本复现例子一
首先基于1的代码复现进行操作。网络分析(Network
Analysis),原本较常见于社会学领域,名为“社会网络分析”(Social Network
Analysis),又被称作“结构分析方法”。起初,是由社会学家根据图论等方法发展起来的定量分析方法。近些年来,社会网络分析方法经过心理学科研工作者的调整和引入,在心理学科研领域占据了越来越重要的位置。本文将从心理学科研领域视角介绍该方法,而非社会学领域的视角,因此不会过多讨论社会学视角中的“社会网络”等成分
rm(list = ls()) #痕迹清除
#安装必要的包
library(bootnet) # Bootstrap Methods for Various Network Estimation Routines
library(qgraph) # Graph Plotting Methods, Psychometric Data Visualization and Graphical Model Estimation
data('attitude') #自带的数据库
dataw22=as.data.frame(attitude[,c(1:7)]) #选择你的待分析数据
###把数据变成矩阵形式
data222.cor=cor_auto(dataw22,detectOrdinal =FALSE) #得到一个偏相关系数矩阵
###命名节点和变量
names=c("RA","CO","PR","LE","RS","CR","AD")
longnames = c("Rating","Complaints","Privileges","Learning","Raises","Critical","Advance")
### A. Figure 1 留意长短标签的用法
graph_ptsd.g=qgraph(data222.cor, labels=names, graph="pcor", layout="spring", vsize=6, cut=0, maximum=.99, sampleSize = nrow(dataw22), border.width=1.5, border.color="black", minimum=.1, nodeNames =longnames,legend.cex=.4)
# dev.off()
### B. Figure 2
centralityPlot(graph_ptsd.g,include = c('Strength','Closeness','Betweenness',"ExpectedInfluence"))
# dev.off()
centralityTable(graph_ptsd.g) #the details of centrality
### 稳健性检验
network1=estimateNetwork(dataw22, default = "pcor") #连续变量
#network1=estimateNetwork(dataw22, default = "EBICglasso") #顺序变量
boot1 = bootnet(network1, nBoots = 100, nCores = 4) # 边估计检验
boot3 = bootnet(network1, nBoots = 100, type = 'case', nCores = 4) # 中心性估计检验
plot(boot1, labels = F, order = "sample" )
# dev.off()
plot(boot3)
#dev.off()
corStability(boot3) #输出CS系数,必须针对type = 'person'才行
1.2 分组复现例子二
在一些情况中,研究者可能想要将比较不同组变量间的关系,此时就可以将所纳入的变量进行分组(如同一心理疾病的不同症状组),以此更直观地比较不同组变量间的联系。为了在定量基础上更好地探究不同组变量间的关联大小,常使用的一种分析方式是桥梁分析。
桥梁分析由Jones等人在中心性指标的基础上提出,包括桥强度(bridge
strength)、桥中介度(bridge betweenness)、桥亲近度(bridge
closeness)和桥预期影响度(bridge expected influence)(Jones et al.,
2021)。各指标定义类似与各中心性指标,不同之处在于,中心性指标衡量的是某节点与所有其他节点的关系,而桥梁中心性是基于节点分组,分析某一组(A组)内某一节点N1与另一组(B组)内所有节点的关系,而不计算N1与同组内其他节点的关联。因此,某一节点的桥中心性越高(如N1),表示它可能是在网络中起到连接它所在组与其他组关联的作用,即A组的其他节点通过N1与其他组的节点产生联系,这样的节点被称作“桥梁节点”。类似地,在桥梁分析中,桥中心性和桥EI表现出更好的稳定(Jones
et al.,
2021)。在心理领域中,桥梁分析可以用来分析两组心理学变量间的关联。以抑郁症状和焦虑症状的共患病研究为例,桥梁分析可以标记出能够解释两者共患病的症状(Kaiser
et al.,
2021),为理解两病共患病的潜在机理起到了提示作用的同时,也能起到揭示潜在干预方式的作用。
研究者们可能会好奇不同网络结构是否有明显差异,以此探究某些变量在两个不同群体间的差异。限于篇幅,此处不针对纵向数据的网络分析进行过多的阐释和举例,感兴趣的读者也可以自行阅读这一参考文献(Borsboom
et al., 2021),获得更全面的介绍。代码和例题可以见下方。
rm(list = ls()) #痕迹清除
#安装必要的包
library(qgraph) # Graph Plotting Methods, Psychometric Data Visualization and Graphical Model Estimation
library(NetworkComparisonTest) # Statistical Comparison of Two Networks Based on Several Invariance Measures
library(networktools) # Tools for Identifying Important Nodes in Networks
data('attitude')
#分组比较,首先创造两个组;obs做成两个组;变量也分了两个组
dataw22=as.data.frame(attitude[c(1:29),]) #选择你的待分析数据
dataw33=as.data.frame(attitude[c(2:30),]) #选择你的待分析数据
###把数据变成矩阵形式
data222.cor=cor_auto(dataw22,detectOrdinal =FALSE)
data333.cor=cor_auto(dataw33,detectOrdinal =FALSE)
###命名节点/变量
names=c("RA","CO","PR","LE","RS","CR","AD")
longnames = c("Rating","Complaints","Privileges","Learning","Raises","Critical","Advance")
gr=list("TYPEA"=c(1:3), "TYEPB"=c(4:7)) #变量做成两个组
### A. Figure 1##
graph_ptsd.g = qgraph(
data222.cor,
labels = names,
graph = "pcor",
layout = "spring",
vsize = 6,
cut = 0,
maximum = .99,
sampleSize = nrow(dataw22),
border.width = 1.5,
border.color = "black",
minimum = .1,
groups = gr,
color = c('#a8e6cf', '#dcedc1'),
nodeNames = longnames,
legend.cex = .4
)
#dev.off()
### B. Figure 2##
graph_ptsd.g <- qgraph(
data333.cor,
labels = names,
graph = "pcor",
layout = "spring",
vsize = 6,
cut = 0,
maximum = .99,
sampleSize = nrow(dataw33),
border.width = 1.5,
border.color = "black",
minimum = .1,
groups = gr,
color = c('#a8e6cf', '#dcedc1'),
nodeNames = longnames,
legend.cex = .4
)
#dev.off()
#桥梁分析部分
b2=data333.cor
colnames(b2)=c("RA","CO","PR","LE","RS","CR","AD")
a2=bridge(b2,communities = list("TYPEA"=c(1:3),"TYEPB"=c(4:7))) #计算桥梁中心性;这里的意思是b2的这个亚组(obs)区分;其中的每个变量和本组其他变量的连接重要性;不是两个网络,而是同一个网络中变量分组的所谓桥梁性质
plot(a2,include = c("Bridge Strength","Bridge Expected Influence (1-step)"),zscore = T,order="value")
#桥梁中心性图
#dev.off()
#网络比较分析;这里就是两个网络图像不像的问题了;显著就代表存在显著差异的意思,两个图的中心性和边的问题
colnames(dataw22)=c("RA","CO","PR","LE","RS","CR","AD")
colnames(dataw33)=c("RA","CO","PR","LE","RS","CR","AD")
com1 = NCT(
dataw22,
dataw33,
0.5,
it = 1000,
binary.data = FALSE,
paired = FALSE,
weighted = TRUE,
AND = FALSE,
abs = FALSE,
test.edges = TRUE,
edges = "all",
test.centrality = TRUE,
progressbar = TRUE,
make.positive.definite = TRUE,
verbose = TRUE
)
com1
以上两个例题作者认为基本的应付简单论文已经够用了。配有不算太详细的视频讲解备查!
1.3 原理补充解读
网络分析(Network
analysis)正是解决此类问题的优势方法,近年来正在不断受到更广泛的关注,并且正在逐步成为代替潜变量建模的优势方法。举例而言,在使用GAD-7测量焦虑症状时,将各个测量条目视为一个焦虑症状放入网络分析进行关联呈现,最后可以解析出最核心的焦虑症状,解析各个症状之间的复杂关联。网络分析以图论作为理论基础,用可视化方式呈现出统计结果,可以更加直观地了解各变量之间的关系。
网络结构图包括不同的类型,主要是涉及选择不同的矩阵类型。一般来说,包括两种类型:相关矩阵网络(Correlation
networks)和偏相关网络(Partial correlation
networks)。前面的例子给定的就是偏相关的矩阵作图和比较计算。
具体的语法不复杂,查阅相应的代码帮助文件即可。除了qgraph包之外,还可以使用“bootnet”包的“estimateNetwork”函数进行网络分析估计
Network<- estimateNetwork(data, default = "cor")#cor是矩阵类型为相关矩阵,pcor偏向关矩阵,glasso为自适应Lasso算法矩阵
2 调节的网络分析
2.1 modnets包实现过程
基于前面4,研究大部分仅探讨了节点之间的两两关系,但对于更复杂机制的考察很少,例如调节作用。并且,在考察调节作用的网络分析研究中,相当一部分仅仅是简单的将整个样本分为几个子样本(例如分为男性和女性)分别进行网络分析。因此,为了更准确的估计调节变量对节点网络的作用,有研究者开发了有调节的网络分析技术。
众所周知,采用GGM方法估计无向网络模型是构建偏相关矩阵。然而,当模型中包含调节因子、协变量或任何高阶交互项时,这种方法就不合适了。因此,可以使用另一种称为节点智能回归的方法(Epskamp
et al., 2018),该方法基于一种称为邻域选择(neighborhood
selection)的结构学习图论方法,并需要通过一系列单变量回归模型来估计网络结构。也就是说,为网络中为每个节点构建一个单独的回归模型,然后跨模型聚合系数以形成最终的网络结构。
rm(list = ls()) #痕迹清除
library(modnets) # Modeling Moderated Networks
skim(ggmDat)
fit1=fitNetwork(ggmDat)
plotNet(fit1) #plot出错,缺乏对象
fit1$adjMat
fit2=estimateNetwork(ggmDat,default = 'ggmModSelect')
plot(fit2)
fit2$graph
#可以看到,两种方法所得到的网络是相似的
fit3=fitNetwork(ggmDat,'M') #其中’M’为调节变量的变量名
plotNet(fit3)
#由于我们使用的是默认设置,该网络采用的是“OR”规则
fit3.1=fitNetwork(ggmDat,'M',rule = 'AND') #AND规则
plotNet(fit3.1)
#将调节变量在图中显示出来,同时显示边的系数。
plotNet(fit3,mnet = TRUE,elabs = T)
#加上将每个节点相关的预测误差在节点周围绘制为饼状图(不能和mnet = TRUE同时使用)
plotNet(fit3,predict = TRUE,elabs = T,con='R2') #饼子代表R2
#估计两个节点之间单向预测关系的调节边际效应图
library(arm) # Data Analysis Using Regression and Multilevel/HierarchicalModels
condPlot(fit3,from='V4',to='V5')
#估计节点的中心性指标
centPlot(fit3,scale = c("z-scores"))
centTable(fit3,scale = T)
#边的稳定性/准确性估计和差异检验
boot1=modnets::bootNet(ggmDat,'M',nboot=100)
plotBoot(boot1) #修订了推文命令左图代表交互作用的边,图右代表成对节点的边
boot2=modnets::bootNet(ggmDat,'M',nboot=100,caseDrop = T)
plotBoot(boot2) #进一步通过caseDrop bootstrap方法估计边的稳定性
plotBoot(boot1,difference = T) #检验边之间是否存在差异
#节点的稳定性/准确性估计
plotBoot(boot1,type='strength')
plotBoot(boot2,type='strength') #进一步通过caseDrop bootstrap方法估计节点的稳定性
plotBoot(boot1,difference = T,type='strength') #检验节点中心性之间是否存在差异
2.2 mgm包实现过程
以2022年在Applied Psychology: Health and
Well-Being上发表的文章《Changes in the network structure of mental
health after a multicomponent positive psychology intervention in
adolescents: A moderated network analysis》为例(Tejada‐Gallardo et al.,
2022),详细的代码和数据已经下载下载;基于下载的代码来进行复现和理解。
本研究的结果分为三个数据集DataPre、DataPost和DataFu,分别代表三个时间点所测得的数据。每个数据集包含7个变量。
rm(list = ls()) #痕迹清除
## Changes in the structure of mental health after a multicomponent positive psychology
##intervention in adolescents: A longitudinal network analysis
#setwd("~/...")
library("foreign") # Read Data Stored by 'Minitab', 'S', 'SAS', 'SPSS', 'Stata','Systat', 'Weka', 'dBase', ...
library(mgm) # Estimating Time-Varying k-Order Mixed Graphical Models
library(psych) # Procedures for Psychological, Psychometric, and Personality Research
library(qgraph) # Graph Plotting Methods, Psychometric Data Visualization and Graphical Model Estimation
library(bootnet) # Bootstrap Methods for Various Network Estimation Routines
##Load Data##
DataPre <-read.spss('/Users/mengtaogao/Library/CloudStorage/OneDrive-共享的库-onedrive/outsyn/station/Effects of an MPPI on mental health/Pre_MNM.sav', to.data.frame=T)
DataPost <-read.spss('/Users/mengtaogao/Library/CloudStorage/OneDrive-共享的库-onedrive/outsyn/station/Effects of an MPPI on mental health/Post_MNM.sav', to.data.frame=T)
DataFu <-read.spss('/Users/mengtaogao/Library/CloudStorage/OneDrive-共享的库-onedrive/outsyn/station/Effects of an MPPI on mental health/Fu_MNM.sav', to.data.frame=T)
# class(DataPre) #检查一下数据框架包括view
###Network models##
Net_Pre<-estimateNetwork(DataPre, default="ggmModSelect", stepwise=TRUE)
Net_Post<-estimateNetwork(DataPost, default="ggmModSelect", stepwise=TRUE)
Net_Fu<-estimateNetwork(DataFu, default="ggmModSelect", stepwise=TRUE)
plot(Net_Pre)
plot(Net_Post)
plot(Net_Fu)
#从左到右分别是三个时间点横断网络,可以发现调节变量与任何节点均无显著相关
#将分组作为调节变量,估计MNMs;常规操作运行正常暂时略过
# centralityPlot(Net_Fu, include=c("Strength", "ExpectedInfluence"), scale=c("z-score"))
#weight-edge accuracy
# boot1<-bootnet(Net_Fu, nBoots=100, type="parametric", nCores=2)
# plot(boot1, order = "sample")
# plot(boot1)
# dev.off()
##centrality stability##
# boot2 <- bootnet(Net_Pre, nBoots = 100, type = "case", nCores = 2)
# plot(boot2)
# corStability(boot2)
#Pre-test#
set.seed(30)
mgm_objPre <- mgm(
data = as.matrix(DataPre),
type = c("c", "g", "g", "g", "g", "g", "g"),
level = c(2, 1, 1, 1, 1, 1, 1),
lambdaSel = "CV",
lambdaGam = .25,
ruleReg = "AND",
moderators = 1,
scale = TRUE
)
mgm_objPre
#Pre-test#
l_mgm_cond <- list()
for(g in 1:2) l_mgm_cond[[g]] <- condition(object = mgm_objPre,
values = list("1" = g))
v_max <- rep(NA, 2)
for(g in 1:2) v_max[g] <- max(l_mgm_cond[[g]]$pairwise$wadj)
par(mfrow=c(1, 2))
for(g in 1:2) {
qgraph(input = l_mgm_cond[[g]]$pairwise$wadj, #plot from web tutorial
edge.color = l_mgm_cond[[g]]$pairwise$edgecolor_cb,
lty = l_mgm_cond[[g]]$pairwise$edge_lty,
layout = "circle", mar = c(2, 3, 5, 3),
title = "Time 1", labels = colnames(DataPre),
maximum = max(v_max), vsize = 10, esize = 23,
edge.labels = TRUE, edge.label.cex = 3)
mtext(text = paste0("Group", g), line = 2.5,
)
}
# dev.off()
#Post-test#
set.seed(30)
mgm_objPost <- mgm(data = as.matrix(DataPost),
type = c("c", "g", "g", "g", "g", "g", "g"),
level = c(2, 1, 1, 1, 1, 1, 1),
lambdaSel = "CV",
lambdaGam =.25,
ruleReg = "AND",
moderators = 1,
scale = TRUE)
# Assess Stability,比较耗时
res_obj <- resample(object = mgm_objPost,
data = as.matrix(DataPost),
nB = 50,
pbar = TRUE)
plotRes(res_obj)
稳定性左图显示两个节点之间的成对效应,右图显示调节效应。圆圈中的值表示估计给定参数为非零的bootstrap样本的比例,黑色线条的两段表示5%和95%bootstra区间。可以发现,在不同时间下,成对和调节效应都是相当稳定的。调节效应在时间点2时明显更强,因为有几个值远离零。
感觉这个部分的原理还不是太清楚。
3 时间网络分析
纵向数据可以分为两种类型:发展过程数据和稳定过程数据。这两种数据是通过不同的研究设计和测量方法得到的,两者的主要差别可以见下表。针对2~3次追踪的面板数据,目前常用交叉滞后网络分析。而针对5次以上追踪的面板数据和密集纵向数据则常用时间网络分析。
主要参考推文:时间网络分析(Temporal
Network Analysis)入门教程。在这里我们使用《A Temporal Network
Approach to Paranoia: A Pilot Study》中的数据为例(Contreras et al.,
2020)。时间网络分析方法建立于“向量自回归”(Vector autoregression,
VAR)模型之上。简单来说,向量自回归模型中的“向量”指的是多元特征,是单变量自回归模型的延伸。而向量自回归模型由一组回归方程组成,其中所有变量都被视为内生变量。因此,它们既可以作为自变量,也可以作为因变量。所以,向量自回归分析可以在没有关于变量之间关联方向的先验假设的情况下进行。通过这种方法,我们就可以知道多个变量之间的跨时间动态关系。
在R中,我们使用mlVAR包实现时间网络分析。在R中,我们使用mlVAR包实现时间网络分析。
rm(list = ls()) #痕迹清除
# Load packages:
#---------------
library("mlVAR")
library("graphicalVAR")
library("qgraph")
library(foreign)
library(qgraph)
library(networktools)
library(corpcor)
library(tseries)
library(TSA)
library(dplyr)
dataset<- read.spss('/Users/mengtaogao/Library/CloudStorage/OneDrive-共享的库-onedrive/outsyn/station/A Temporal Network Approach to Paranoia/Temporal network approach to paranoia_data.sav',to.data.frame=TRUE, use.value.labels = F)
baseline<-dataset[,c(1:4,10:13)]
#Preparation:
#------------
names(baseline) <- c("subject","day","beep","sad","others","EA","SE","paranoia")
vars <- c ("sad","others","EA","SE","paranoia")
idvar <- "subject"
dayvar<-"day"
beepvar<-"beep"
#Estimation: two-step multilevel Vector Autoregressive (mlVAR):
#--------------------------------------------------------------
baseline_mlVAR <- mlVAR(baseline, vars, idvar, lags = 1, estimator = "lmer",temporal = "correlated", contemporaneous = "correlated")
#Visualization:
#--------------
#Separated plot:
contemporaneous<-plot(baseline_mlVAR, "contemporaneous", layout = "circle", nonsig = "hide", theme = "colorblind", title = "Contemporaneous",
labels = vars, vsize = 13, rule = "and", asize = 10, mar = c(5,5,5,5))
temporal<-plot(baseline_mlVAR, "temporal", layout = "circle", nonsig = "hide", theme = "colorblind", title = "Temporal",labels = vars, vsize = 13, rule = "and", asize = 5, mar = c(5,5,5,5))
between_subjects<-plot(baseline_mlVAR, "between", layout = "circle", nonsig = "hide", theme = "colorblind", title = "Between-subjects",labels = vars, vsize = 13, rule = "and", asize = 10, mar = c(5,5,5,5))
#节点中心性估计
centralityPlot(contemporaneous,include = c('Strength','Closeness','Betweenness',"ExpectedInfluence"))
centrality(contemporaneous)
centralityPlot(temporal,include = c('Strength','Closeness','Betweenness',"ExpectedInfluence"))
centrality(temporal)
centralityPlot(between_subjects,include = c('Strength','Closeness','Betweenness',"ExpectedInfluence"))
centrality(between_subjects)
时间网络(Temporal
network)。时间网络中边表示在控制了前一个测量点上的所有其他变量后,前一个测量点对下一个测量点的节点的预测能力。例如图中我们可以发现,悲伤、与他人的亲密度、体验回避、自尊、偏执信念都存在自回归效应。与他人的亲密度消极地预测了下一个时间点的偏执,悲伤积极地预测了体验回避,而体验回避反过来又积极地预测了下一个时间点的自尊;其实就是within估计类似。
同时网络(Contemporaneous
network)。同时网络中的边表示在控制了时间关联之后,同一时间框架内变量之间的关联。可以发现有几个联系非常突出,偏执信念和悲伤呈正相关,这表明在同一时间段内,偏执信念得分越高,悲伤水平越高。同样,悲伤与自尊和与他人的亲密度都是负相关。换句话说,悲伤程度越高,自尊水平越低,同时与他人的亲密感也越低。此外,自尊和与他人的亲密度是正相关的。最后,体验回避与任何其他变量无关;
个体间网络(Between-subject
network)。个体间网络模型边表示,在考虑到网络中的其余变量后,个体内部平均水平之间的相关性。可以发现,与他人的亲密度的平均水平与偏执信念的平均水平呈负相关,与自尊的平均水平呈正相关。悲伤的平均水平与自尊的平均水平呈负相关,与体验回避的平均水平呈正相关。其实就是Between估计量;
4 针对面板数据的时间网络分析(Temporal Network Analysis)
介绍针对面板数据的时间网络分析(Temporal Network
Analysis)。需要注意,这种纵向网络分析所需要的面板数据至少要有三个wave。并且,面板数据的时间网络分析与密集追踪数据的时间网络分析相似,同样区分了个体内和个体间效应,并可以估计时间网络、同时网络和个体间网络。
命令主要是:mlGVAR {modnets}:Fit GVAR models with
multilevel data Fits a graphical vector autoregressive model to data
containing multiple time points measured for multiple individuals.
纵向网络分析主要通过图形向量自回归模型(the graphical
vector-autoregression model, GVAR)实现(Epskamp et al., 2018; Wild et
al., 2010)。1阶滞后(lag-1) GVAR模型是由单主体时间序列的高斯图形模型(the
Gaussian graphical model,
GGM)推广而来。GGM模型大家都很熟悉,在横断网络分析中被用来估计部分相关,形成无向网络模型。而在(lag-1)
GVAR模型中,时间依赖关系通过对先前测量情况的回归来建模,这导致回归系数矩阵也可用于绘制有向网络模型(Bringmann
et al.,
2013),通常被称为时间网络。剩余的方差和协方差(即控制前一次测量场合后的协方差结构)可以建模为一个GGM模型,也称为同时网络。当多个主体的时间序列可用时,可以形成关于个体间效应(稳定均值之间的关系)的第三个GGM模型,也称为个体间网络。具体统计原理大家可以参考(Epskamp,
2020)。
简单通过例题数据来进行演示。按照这里的面板逻辑,仅仅fixed和between是有用的,时序上的ar过程其实没有太大意义。
rm(list = ls()) #痕迹清除
library(modnets)
head(mlgvarDat)
fit1 <- mlGVAR(mlgvarDat, 'M',idvar = "ID") #Estimating fixed networks
(p1=plotNet(fit1,mnet = TRUE,elabs = T))
fit2 <- mlGVAR(mlgvarDat, 'M', bm = TRUE) # Fit the same moderator in the between-subjects network
(p2=plotNet(fit2,mnet = TRUE,elabs = T))
fit3=mlGVAR(mlgvarDat, 'M', selectFUN = 'varSelect')
(p3=plotNet(fit3,mnet = TRUE,elabs = T))
#极为耗时的一些计算过程
(x <- lmerVAR(mlgvarDat, 'M', temporal = "fixed", contemp = "orthogonal"))
fit1 <- lmerVAR(mlgvarDat, temporal = "fixed", contemp = "orthogonal")
fit2 <- lmerVAR(mlgvarDat, temporal = "orthogonal", contemp = "orthogonal")
compareVAR(fit1, fit2)
目前,已有一些研究使用了基于面板数据的纵向网络分析,例如有研究考察了有问题的网络使用、心理困扰和饮食失调症状之间的关系(Lin
et al.,
2023)。但这种方法相比于横断网络分析,在评估网络和节点的中心性、稳定性、可重复性等方面存在不足,有待研究者们的进一步开发。2024年五月份的意见:基于面板数据的纵向网络分析-时间网络分析(Temporal
Network Analysis)入门教程(2)。
5 探索性图论分析
根据推文:探索性图论分析;这里原理进行了讲解,但是数据没有提供,直接采用?EGAnet
的例题自带数据进行处理就足够了。
探索性图论分析 (Exploratory Graph Analysis)
是近年来兴起的一种维度检测方法。这种方法有别于之前的探索性因子分析
(Exploratory Factor
Analysis),它将变量构建为多元正态分布网络,并将显性变量视为由边线(Edges)连接的节点(Nodes)所构成的网络,而因子模型中的潜在变量则使这些节点相互聚集。
通过将高斯图模型(Gaussian graphical
model,GGM)与加权网络的聚类算法相结合,EGA
可以对心理构念中条目维度进行评估。模拟研究显示,与作为评估维度“金标准”的因素分析法相比,EGA
在准确检测心理量表的正确维度方面表现更为出色(Golino et al., 2020)。EGA
以其以下优点而备受关注:(1)可视化能力:可以通过使用不同颜色编码的网络图直观地判断条目维度的归属;(2)自动估计:无需考虑采用何种旋转方法;(3)稳定性检验:可通过
bootstrap
方法进行维度稳定性检验。因此,Cosemans等人(2022)将EGA作为估计连续数据维度的首选方法。
rm(list = ls()) #痕迹清除
library(EGAnet) # Exploratory Graph Analysis – a Framework for Estimating theNumber of Dimensions in Multivariate Data using Network Psychometrics
# Get data
data = psych::bfi[,1:25]
## Not run: # Compute LCT
## Factor model;默认it=100
LCT(data,seed=123)
#结果表明,随机抽取的子样本总,有多少适合网络分析
#Bootstrap Exploratory Graph Analysis
# Load data
wmt = wmt2[,7:24]
## Not run:
# Standard EGA parametric example
boot.wmt = bootEGA(
data = wmt, iter = 500,
type = "parametric", ncores = 2,seed=123
) #项目的稳定性应该大于0.65
plot(boot.wmt$EGA)
boot.wmt$summary.table #得到的因子中位数与其他统计指标
boot.wmt$frequency #得到的因子数量估计分布
dimensionStability(boot.wmt) #维数的稳定性应该大于0.75
net.loads(boot.wmt$EGA) #载荷为0.15表示非常小
结合item stability和network loading对各个项目进行检查,当itme
stability小于0.65,network
loading也较小时,则考虑删除该项目。值得注意的是,项目的删除与否需要考虑多方面的原因,例如理论层面上,该项目是否反映了核心变量;实践层面上,该项目是否是主要关注的变量。因此,项目的删除与否需要结合文献具体分析。
6 网络分析中控制协变量
主要根据推文:如何在网络分析中控制协变量?和推文上的两篇论文来进行实操和理解。目前主要有两种方式控制协变量:一种直接把每个节点回归掉协变量后取残差,另一种将协变量也当做节点纳入网络模型。
两种方法各有利弊,第一种的问题在于节点是基于总样本的残差,在后续bootstrap时会引入误差(另外,有时候,使用这种方法与不控制协变量相比,在进行网络中心性估计时,稳定性和准确性会相对差一些);第二种的问题在于协变量的引入会造成网络的结构变化。采用的时候要说清楚利弊何在。其实一般来说,第二种方法实施起来似乎简单。从实际运用的角度,采用第二种方法更为便利一些。
示例数据来自于networktools中的depression数据集,这个模拟数据集包含1000个人中9种重度抑郁症症状(PHQ-9)的严重程度评级。症状评级假设是在100点滑动量表上自我报告的。
rm(list = ls()) #痕迹清除
#3.1载入包与确定代码路径(载入出现错误的话需要先去安装包)----
library(networktools) # Tools for Identifying Important Nodes in Networks
library(bootnet) # Bootstrap Methods for Various Network Estimation Routines
library(mgm) # Estimating Time-Varying k-Order Mixed Graphical Models
#3.2 数据和网络估计准备------
data = networktools::depression #用depression数据作为本教程的示例数据;指明究竟哪个包
#生成协变量并组合成新数据集
gender = as.numeric(sample(x = c(1, 2), size = nrow(data), replace = TRUE))
# 随机生成1000个性别数据
age = sample(x = 20:30, size = nrow(data), replace = TRUE) #随机生成1000个年龄数据
usedata = data.frame(data, age,gender) # 将生成的数据合并成一个数据框
# 3.3 协变量网络估计
##3.3.1 第一种方法
###回归掉协变量
depression_mat=as.data.frame(matrix(nrow=1000,ncol=9)) #做出一个空的数据库来存储残差
colnames(depression_mat)=colnames(usedata)[1:9] #空数据库变量命名
#这个函数的意义是将每一个变量进行回归,然后将残差存储在depression_mat中
for (i in 1:(ncol(depression_mat))) { #留意一下循环的操作
formula <- paste(colnames(usedata)[i], '~age+gender')
lm1 <- glm(formula = formula,family = "gaussian", data = usedata)
y_res <- lm1$residuals
depression_mat[, i] <- y_res
}
head(depression_mat) #检查归结残差的数据
network = as.matrix(depression_mat)
p=ncol(network)
fit_obj = mgm(data = network, type = rep('g', p), level = rep(1, p), lambdaSel = 'CV', ruleReg = 'OR', pbar = TRUE)
pred_obj = predict(object = fit_obj, data = network, errorCon = 'R2')
pred_obj$error #可预测性计算结果,其实就是得到全部的R2而已
#估计网络
Network = estimateNetwork(data=network, default = "EBICglasso", tuning = 0.5, corMethod="cor",corArgs=list(method="spearman",use="pairwise.complete.obs"))
groups=list("PHQ-9 symptoms"=c(1:9))
colnames(usedata)=c("D1","D2","D3","D4","D5","D6","D7","D8","D9")
items =list("Angedonia","Sadmood","Sleep","Fatigue","Appeitite","Worthless","Concentration","Montor","Death")
#网络图
plot_network <- plot(
Network,
layout = "spring",
groups = groups,
label.cex = 1,
#调整节点中标签的字体大小
label.color = 'black',
# 调整节点中标签的字体颜色
negDashed = T,
#负相关的边为虚线
legend = T,
nodeNames = items,
legend.cex = 0.55,
#图例的字体大小
legend.mode = 'style1',
#图例的风格,默认是'style1'
pie = pred_obj$error[, 2]
#节点的环形图显示的是R2
)
#3.3.2 第二种方法
groups=list("PHQ-9 symptoms"=c(1:9),"Covariates"=c(10:11)) #协变量一组
colnames(usedata) =c("D1","D2","D3","D4","D5","D6","D7","D8","D9","C1","C2")
items = list("Angedonia","Sad mood","Sleep","Fatigue","Appeitite","Worthless","Concentration","Montor","Death","age","gender")
network = as.matrix(usedata) #整个运行的网络框架11个变量,包含两个协变量
p=ncol(network)
fit_obj = mgm(
data = network,
type = rep('g', p),
#这里将性别也作为连续变量进行处理
level = rep(1, p),
lambdaSel = 'CV',
ruleReg = 'OR',
pbar = TRUE
)
pred_obj = predict(object = fit_obj, data = network, errorCon = 'R2')
pred_obj$error#可预测性计算结果
#估计网络
Network = estimateNetwork(
data = network,
default = "EBICglasso",
tuning = 0.5,
corMethod = "cor",
corArgs = list(method = "spearman", use = "pairwise.complete.obs")
)
#网络图
plot_network = plot(
Network,
layout = "spring",
groups = groups,
label.cex = 1,
#调整节点中标签的字体大小
label.color = 'black',
# 调整节点中标签的字体颜色
negDashed = T,
#负相关的边为虚线
legend = T,
nodeNames = items,
#图例中的节点标签名
legend.cex = 0.55,
#图例的字体大小
legend.mode = 'style1',
#图例的风格,默认是'style1'
pie = pred_obj$error[, 2]
)
7 贝叶斯网络与因果推断之类
例子和演示的第一篇推文:一文搞懂贝叶斯网络模型及其R实现;贝叶斯网络(Bayesian
Network, BN)是一种概率图模型,它通过有向无环图(Directed Acyclic Graph,
DAG)表示一组随机变量及其相互之间的条件依赖性。在处理不确定性和复杂性问题时,贝叶斯网络提供了一种直观且强大的工具。
7.1 贝叶斯网络的构造
贝叶斯网络由两部分组成:网络结构和条件概率表(Conditional
Probability Table, CPT)。
网络结构:网络结构是指用DAG表示的变量间的拓扑关系。在DAG中,节点代表随机变量,有向边(从A指向B)表示变量A是变量B的父节点,即A对B有直接影响。根据DAG,我们可以得出变量间的条件独立性,即在给定父节点的情况下,一个节点的条件概率分布仅依赖于其父节点。
条件概率表(CPT):对于网络中的每个节点,我们需要定义一个CPT,它描述了该节点在其父节点取特定值时的概率分布。CPT是局部的,因为它只依赖于父节点的状态。
7.2 贝叶斯网络模型的学习分为两部分
结构学习提供了变量之间关系的框架,而参数学习则填充了这个框架中的具体内容。通过这两个步骤,我们可以得到一个能够对数据进行有效建模和推理的贝叶斯网络。
介绍四类主要的网络结构学习方法:基于约束、基于分数、配对和混合方法,以及他们的优缺点和比较网络结构学习方法的一些基本原则。
bnlearn是R中一个强大的包,用于学习、推理、模拟和分析贝叶斯网络。它提供了一系列工具来处理贝叶斯网络的不同方面,包括网络结构的学习、参数的估计、条件概率的查询、数据集的模拟,以及多种网络的图形表示方法。以下是如何使用bnlearn包构建贝叶斯网络的详细介绍。
本次使用的数据集是:BreastCancer数据集是著名的机器学习和数据挖掘领域的标准数据集之一,通常用于分类和预测任务。这个数据集包含了来自乳腺癌患者的各种特征,旨在通过这些特征预测肿瘤是良性还是恶性。
rm(list = ls()) #痕迹清除
# 加载bnlearn包
library(bnlearn) # Bayesian Network Structure Learning, Parameter Learning and Inference
# 导入BreastCancer数据集
library(mlbench) # Machine Learning Benchmark Problems
data(BreastCancer)
# 查看变量类型
str(BreastCancer)
# 查看摘要统计信息
skim(BreastCancer)
# 将数据集转换为离散变量
# 在构建贝叶斯网络模型之前,我们需要将连续变量转换为离散变量。可以使用discretize()函数将连续变量转换为离散变量。以下代码将数据集中的连续变量转换为离散变量:
# library(bnlearn)
data.bc <- discretize(BreastCancer[,2:ncol(BreastCancer)], method = "interval", breaks = "frequency")
# 数据预处理# 使用数据集
data.bc <- BreastCancer[,2:ncol(BreastCancer)]# 使用VIM::aggr()查看函数的缺失值
library(VIM) # Visualization and Imputation of Missing Values
aggr(data.bc) #缺失值的情况的可视化
# 使用随机森林填补缺失值
library(missForest) # Nonparametric Missing Value Imputation using Random Forest
data.bc_new <- missForest(data.bc,ntree = 100)
data.bc_new<- data.bc_new$ximp
# ① 使用希尔-克莱姆算法学习网络结构:
bn.structure <- hc(data.bc_new, score = "bic")
plot(bn.structure) # 绘制学习到的结构
# ② 使用基于约束的PC算法:
bn.structure <- pc.stable(data.bc_new,test="mi")
plot(bn.structure) # 绘制学习到的结构
# 1. 基于分数的方法# 贝叶斯网络结构的禁忌搜索(Tabu Search)
bn.tabu <- tabu(data.bc_new)
plot(bn.tabu) # 绘制学习到的结构
# 2. 基于约束的方法# Grow-Shrink算法(GS)
bn.gs <- gs(data.bc_new)
plot(bn.gs) # 绘制学习到的结构
# 3. 配对方法# 最大权重生成树算法(Chow-Liu)
bn.chowliu <- chow.liu(data.bc_new)
plot(bn.chowliu) # 绘制学习到的结构
#4. 混合方法#Max-Min Hill-Climbing算法(MMHC)
bn.mmhc <- mmhc(data.bc_new)
plot(bn.mmhc ) # 绘制学习到的结构
# 参数学习# 结构学习完成后,下一步是参数学习。参数学习是指学习网络中每个变量的条件概率分布(对于离散变量)或条件概率密度(对于连续变量)。
bn.parameters <- bn.fit(bn.structure, data.bc_new) #结构选择基于约束
bn.parameters
# 绘制网络
# graphviz.plot(bn.structure) #结构选择基于约束
# 计算在给定某些证据下肿瘤是良性的概率# 假设我们知道 Bare.nuclei = "1" 和 Marg.adhesion = "1"
prob_benign_given_evidence <- cpquery(fitted = bn.parameters, event = (Class == "benign"),evidence = ( Marg.adhesion == "1"))
prob_benign_given_evidence
# 生成给定证据下Class变量的条件概率分布
distribution_class_given_evidence <- cpdist(
fitted = bn.parameters,
nodes = "Class",
evidence = (Bare.nuclei == "1")
)
tabyl(distribution_class_given_evidence$Class)
# 比较模型,这将输出一个列表,其中包括两个网络共有的边、只在第一个网络中出现的边、以及只在第二个网络中出现的边。
compare(bn.tabu, bn.gs)
# 对Tabu搜索算法进行引导稳定性分析
bs.tabu <- boot.strength(data = data.bc_new, algorithm = "tabu", R = 100)
bs.tabu
#Rgraphviz没有安装,无法可视化
# 条件独立性测试# 条件独立性测试是评估变量间是否独立的一种方法,对于基于约束的网络学习方法尤其重要。bnlearn提供了ci.test函数来执行条件独立性测试。以下是如何在变量之间进行条件独立性测试的示例:
ci.test("Marg.adhesion", "Bare.nuclei", data = data.bc_new)
7.3 横断网络中的因果推断
基于推文:贝叶斯网络分析入门-横断网络中的因果推断下载了数据。以此为例子。doi顺手把参考文献添加。
rm(list = ls()) #痕迹清除
# A tutorial on Bayesian networks for psychopathology researchers
# Briganti G, Scutari M, McNally RJ
library(stats)
library(qgraph)
library(readr)
library(bootnet)
library(dplyr)
library(corpcor)
library(bnlearn)
library(psych)
library (ggplot2)
data <- read_delim('/Users/mengtaogao/Library/CloudStorage/OneDrive-共享的库-onedrive/outsyn/station/A tutorial on Bayesian Networks/data.csv', ";", escape_double = FALSE, trim_ws = TRUE)
names <- c("DepMood",
"Sleep",
"Weight",
"Fatigue",
"Irritable",
"SuicideId",
"Anhedonia")
longnames <- c("Depressive Mood",
"Sleep Problems",
"Weight",
"Fatigue",
"Irritable",
"Suicidal Ideation",
"Anhedonia")
data <- as.data.frame(matrix(as.numeric(as.matrix(data)),
ncol=ncol(data),
byrow=TRUE)) #set data as numerics
# PC algorithm
BNpc<-pc.stable(data)
qgraph(BNpc, labels=names,
nodeNames=longnames,
legend.cex=.5,
vsize=6,
layout="circle")
# Boot stability for the DAG
# Strength: connection strength, e.g. 0.85 >
# connection appears in 86% of the fitted networks.
# Direction: probability of the direction
# e.g. 0.57 means that in 57% of the fitted networks the connection goes in
# the direction depicted in the graph.
BST <- boot.strength(data,
R = 1000,
algorithm = "pc.stable")
head(BST)
qgraph(BST) # visualize output with qgraph
BST[BST$strength > 0.85 & BST$direction > 0.5, ]
avgnet1 <- averaged.network(BST, threshold = 0.85)
astr1 <- arc.strength(avgnet1, data, "bic-g") # compute edge strengths
qgraph(
astr1,
labels = names,
nodeNames = longnames,
legend.cex = .5,
vsize = 6,
layout = "circle"
)
#公众号上的演示不完整
# Hill Climbing algorithm
# Boot stability for the DAG
# Strength: connection strength, e.g. 0.85 >
# connection appears in 86% of the fitted networks.
# Direction: probability of the direction
# e.g. 0.57 means that in 57% of the fitted networks the connection goes in
# the direction depicted in the graph.
BST <- boot.strength(data, R = 1000, algorithm = "hc", debug = TRUE)
head(BST)
BST[BST$strength > 0.85 & BST$direction > 0.5, ]
qgraph(BST)
avgnet1 <- averaged.network(BST, threshold = 0.85)
avgnet1
bnlearn::score(avgnet1, data = data)
astr1 <- arc.strength(avgnet1, data, "bic-g") ## compute edge strengths
qgraph(astr1,
labels=names,
nodeNames=longnames,
legend.cex=.5,
vsize=6,
layout="circle")
# Equivalence classes
BNpc<-pc.stable(data)
BNcp <- cpdag(BNpc)
qgraph(
BNcp,
labels = names,
nodeNames = longnames,
legend.cex = .5,
vsize = 6,
layout = "circle"
)
vstructs(BNcp)
BST <- boot.strength(
data,
R = 1000,
algorithm = "pc.stable",
debug = TRUE,
cpdag = TRUE
)
head(BST)
BST[BST$strength > 0.85 & BST$direction > 0.5, ]
qgraph(BST)
avgnet1 <- averaged.network(BST, threshold = 0.85)
avgnet1
bnlearn::score(avgnet1, data = data)
astr1 <- arc.strength(avgnet1, data, "bic-g") ## compute edge strengths
qgraph(
astr1,
labels = names,
nodeNames = longnames,
legend.cex = .5,
vsize = 6,
layout = "circle"
)
# Grow shrink
BNgs <- gs(data)
qgraph(
BNgs,
labels = names,
nodeNames = longnames,
legend.cex = .5,
vsize = 6,
layout = "circle"
)
BST <- boot.strength(data, R = 1000,
algorithm = "gs",
debug = TRUE)
head(BST)
BST[BST$strength > 0.85 & BST$direction > 0.5, ]
qgraph(BST)
avgnet1 <- averaged.network(BST, threshold = 0.85)
avgnet1
bnlearn::score(avgnet1, data = data)
astr1 <- arc.strength(avgnet1, data, "bic-g") ## compute edge strengths
qgraph(
astr1,
labels = names,
nodeNames = longnames,
legend.cex = .5,
vsize = 6,
layout = "circle"
)
# Restricted Maximization hybrid algorithm
BNrs <- rsmax2(data)
BST <- boot.strength(data,
R = 1000,
algorithm = "rsmax2",
debug = TRUE)
head(BST)
BST[BST$strength > 0.85 & BST$direction > 0.5, ]
avgnet1 <- averaged.network(BST, threshold = 0.85)
avgnet1
bnlearn::score(avgnet1, data = data)
astr1 <- arc.strength(avgnet1, data, "bic-g") ## compute edge strengths
qgraph(
astr1,
labels = names,
nodeNames = longnames,
legend.cex = .5,
vsize = 6,
layout = "circle"
)
## GGM for comparison
n1 <- estimateNetwork(data, default="EBICglasso", threshold=TRUE)
plot(
n1,
layout = "circle",
labels = names,
nodeNames = longnames,
theme = "colorblind",
legend.cex = 0.5,
vsize = 6
)
原理与工具的一些补充。神器dagitty;已经安装了dagitty包。基于推文:(因果)贝叶斯网络与有向无环图(DAG)在因果推断中的应用。原理以这个为基础:贝叶斯网络在精神病理学研究中的应用。
贝叶斯网络的优势:
a.可视化依赖关系:通过图结构直观展示变量之间的依赖性和因果方向,有助于理解复杂交互机制。
b.处理复杂交互关系:适合多变量、多层次交互分析,尤其是涉及心理学和医学中的复杂系统。
c.缺失数据处理能力:贝叶斯网络能够在数据缺失的情况下进行推断,不需要完整数据集即可进行分析。
d.因果推断:不仅可以分析相关性,还能明确变量之间的因果关系,有助于决策和干预方案的设计。
e.灵活性和扩展性:支持动态贝叶斯网络(DBN)分析时间序列数据,进一步研究变量随时间变化的动态影响。
贝叶斯网络与横断网络分析的区别
贝叶斯网络是分析复杂多变量关系的强大工具,尤其适用于心理学和医学领域的因果推断。它不仅可以揭示变量之间的条件依赖和方向性,还能有效处理缺失数据,并对变量之间的交互作用进行可视化和量化分析。
此外,贝叶斯网络具有灵活性和扩展性,支持动态贝叶斯网络(DBN)处理时间序列数据,进一步探索随时间变化的动态过程。因此,它在精神病理学等领域具有重要的应用价值,为诊断、预测和干预策略提供了科学依据和决策支持。
8 传统意义的社会网络分析(基于obs的处理)
前面的网络分析都是基于列的处理;传统的SNA是基于行的计算与可视化。这个部分就是补充一些关于行的计算。
LS0tCnRpdGxlOiAi572R57uc5YiG5p6Q5pWZ56iLIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OiB0cnVlCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKIyAxIOWfuuacrOeahOe9kee7nOWIhuaekOWOn+eQhuS4juS7o+eggQoK4oCD4oCD5pys6YOo5YiG5piv572R57uc5YiG5p6Q55qE5Z+656GA6YOo5YiG77yM5YWl6Zeo5ZKM5Z+65pys5qaC5b+1562J44CC5Z+65LqO55qE6LWE5paZ5ZKM5Luj56CB5Y+C6ICD5pyJ5Yeg5LiL5Yeg5Liq44CCCgoxLiAgW+e9kee7nOWIhuaekO+8iDHvvInvvJrmqKrmlq3pnaLnvZHnu5zliIbmnpDlj4rku6PnoIHlrp7kvotdKGh0dHBzOi8vbXAud2VpeGluLnFxLmNvbS9zL0k0YTVaNFc3NzVqeFktM0RwakRUNkEp77yb57uZ5Ye65LqG5YWs5byA55qE5Luj56CB5ZKM5pWw5o2u5bqT77yM5L6/5LqO5aSN546w5ZKM55CG6Kej77yb5Y+C6ICD5paH54yuCgoyLiAgW+e9kee7nOWIhuaekO+8iDLvvInvvJrmoaXmooHliIbmnpDjgIHnvZHnu5zmr5TovoPliIbmnpDlj4rku6PnoIHlrp7kvovkuI7nurXlkJHnvZHnu5zliIbmnpBdKGh0dHBzOi8vbXAud2VpeGluLnFxLmNvbS9zL0lnQzJTQWNpemphODRSUDVNdUNKWmcp77yb5L2c5Li656ysMemDqOWIhueahOaLk+Wxle+8jOS5n+acieebuOW6lOeahOS7o+eggeWSjOaVmeeoi+WkjeeOsO+8m+i/meS4quWFrOS8l+WPt+WFs+S6jue9kee7nOWIhuaekOeahOS7i+e7jeWwseaYr+i/meS4pOS4quaWh+eroO+8m+WPguiAg+aWh+eMrgoKMy4gIFvnnJ/nmoTmnInlhpnnmoTov5nkuYjor6bnu4bnmoTnvZHnu5zliIbmnpDmlZnnqIvlmJvvvJ9dKGh0dHBzOi8vbXAud2VpeGluLnFxLmNvbS9zL0ZhMGk0QXN6Mk9pSDd0d01IaUVMZXcp77yb5Y6f55CG55qE6K6y6Kej6Z2e5bi45riF5qWa77yM5L2G5piv5pWw5o2u5ZKM5Luj56CB5aSN546w6KaB5pS26LS577yM5L2c5Li66KGl5YWF5p2Q5paZ77ybCgo0LiAgW+S9oOingei/h+acieiwg+iKgueahOe9kee7nOWIhuaekOWQl++8n+S/neWnhue6p+aVmeeoi++8ge+8ge+8gV0oaHR0cHM6Ly9tcC53ZWl4aW4ucXEuY29tL3MvN1hBQ3A1c2N3SkhoWlBKakplUjExUSnvvIwz55qE5ouT5bGV77yM5Y6f55CG5riF5qWa77yM5peg5rOV5Luj56CB5aSN546w44CC6KGl5YWF5LiA5LiqW+acieiwg+iKgueahOe9kee7nOWIhuaekOKAlOKAlOWPpuS4gOenjeaWueazlV0oaHR0cHM6Ly9tcC53ZWl4aW4ucXEuY29tL3M/X19iaXo9TXpJeE9UYzRNRGswTmc9PSZtaWQ9MjI0NzQ4Mzk1MSZpZHg9MSZzbj1kNDhhYjdkYzMxOTAzMjZkNmRkYzgzNmYzZGFlNGM5NyZjaGtzbT05N2Q3NDAxMmEwYTBjOTA0MzFhM2UxNWNiZmIyYjRjNjY4ZTYwNmM4NWMyZmVkNTZkNTk5NDBkNWFjZDVjZWY3MTBlMmY3ZTY5YjE3JmN1cl9hbGJ1bV9pZD0zNDUyOTA0NjEzNDE3MDQxOTIxJnNjZW5lPTE5MCNyZCnvvJvljIXmi6zorrrmloflhajmloflkozmlbDmja7ku6PnoIHlpI3njrDmnZDmlpnvvJpFZmZlY3RzIG9mIGFuIE1QUEkgb24gbWVudGFsIGhlYWx0aOaWh+S7tuWkueOAggoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyAxLjEg5Z+65pys5aSN546w5L6L5a2Q5LiACgrigIPigIPpppblhYjln7rkuo4x55qE5Luj56CB5aSN546w6L+b6KGM5pON5L2c44CC572R57uc5YiG5p6Q77yITmV0d29yayBBbmFseXNpc++8ie+8jOWOn+acrOi+g+W4uOingeS6juekvuS8muWtpumihuWfn++8jOWQjeS4uuKAnOekvuS8mue9kee7nOWIhuaekOKAne+8iFNvY2lhbCBOZXR3b3JrIEFuYWx5c2lz77yJ77yM5Y+I6KKr56ew5L2c4oCc57uT5p6E5YiG5p6Q5pa55rOV4oCd44CC6LW35Yid77yM5piv55Sx56S+5Lya5a2m5a625qC55o2u5Zu+6K66562J5pa55rOV5Y+R5bGV6LW35p2l55qE5a6a6YeP5YiG5p6Q5pa55rOV44CC6L+R5Lqb5bm05p2l77yM56S+5Lya572R57uc5YiG5p6Q5pa55rOV57uP6L+H5b+D55CG5a2m56eR56CU5bel5L2c6ICF55qE6LCD5pW05ZKM5byV5YWl77yM5Zyo5b+D55CG5a2m56eR56CU6aKG5Z+f5Y2g5o2u5LqG6LaK5p2l6LaK6YeN6KaB55qE5L2N572u44CC5pys5paH5bCG5LuO5b+D55CG5a2m56eR56CU6aKG5Z+f6KeG6KeS5LuL57uN6K+l5pa55rOV77yM6ICM6Z2e56S+5Lya5a2m6aKG5Z+f55qE6KeG6KeS77yM5Zug5q2k5LiN5Lya6L+H5aSa6K6o6K6656S+5Lya5a2m6KeG6KeS5Lit55qE4oCc56S+5Lya572R57uc4oCd562J5oiQ5YiGCgpgYGB7ciBuZXQxfQpybShsaXN0ID0gbHMoKSkgI+eXlei/uea4hemZpAoj5a6J6KOF5b+F6KaB55qE5YyFCmxpYnJhcnkoYm9vdG5ldCkgIyBCb290c3RyYXAgTWV0aG9kcyBmb3IgVmFyaW91cyBOZXR3b3JrIEVzdGltYXRpb24gUm91dGluZXMKbGlicmFyeShxZ3JhcGgpICMgR3JhcGggUGxvdHRpbmcgTWV0aG9kcywgUHN5Y2hvbWV0cmljIERhdGEgVmlzdWFsaXphdGlvbiBhbmQgR3JhcGhpY2FsIE1vZGVsIEVzdGltYXRpb24KZGF0YSgnYXR0aXR1ZGUnKSAj6Ieq5bim55qE5pWw5o2u5bqTCmRhdGF3MjI9YXMuZGF0YS5mcmFtZShhdHRpdHVkZVssYygxOjcpXSkgI+mAieaLqeS9oOeahOW+heWIhuaekOaVsOaNrgojIyPmiormlbDmja7lj5jmiJDnn6npmLXlvaLlvI8KZGF0YTIyMi5jb3I9Y29yX2F1dG8oZGF0YXcyMixkZXRlY3RPcmRpbmFsID1GQUxTRSkgI+W+l+WIsOS4gOS4quWBj+ebuOWFs+ezu+aVsOefqemYtQojIyPlkb3lkI3oioLngrnlkozlj5jph48KbmFtZXM9YygiUkEiLCJDTyIsIlBSIiwiTEUiLCJSUyIsIkNSIiwiQUQiKQpsb25nbmFtZXMgPSBjKCJSYXRpbmciLCJDb21wbGFpbnRzIiwiUHJpdmlsZWdlcyIsIkxlYXJuaW5nIiwiUmFpc2VzIiwiQ3JpdGljYWwiLCJBZHZhbmNlIikKCiMjIyBBLiBGaWd1cmUgMSDnlZnmhI/plb/nn63moIfnrb7nmoTnlKjms5UKZ3JhcGhfcHRzZC5nPXFncmFwaChkYXRhMjIyLmNvciwgbGFiZWxzPW5hbWVzLCBncmFwaD0icGNvciIsIGxheW91dD0ic3ByaW5nIiwgdnNpemU9NiwgY3V0PTAsIG1heGltdW09Ljk5LCBzYW1wbGVTaXplID0gbnJvdyhkYXRhdzIyKSwgICAgICBib3JkZXIud2lkdGg9MS41LCBib3JkZXIuY29sb3I9ImJsYWNrIiwgbWluaW11bT0uMSwgICAgICAgICAgICAgICAgICBub2RlTmFtZXMgPWxvbmduYW1lcyxsZWdlbmQuY2V4PS40KQojIGRldi5vZmYoKQoKIyMjIEIuIEZpZ3VyZSAyIApjZW50cmFsaXR5UGxvdChncmFwaF9wdHNkLmcsaW5jbHVkZSA9IGMoJ1N0cmVuZ3RoJywnQ2xvc2VuZXNzJywnQmV0d2Vlbm5lc3MnLCJFeHBlY3RlZEluZmx1ZW5jZSIpKQojIGRldi5vZmYoKQpjZW50cmFsaXR5VGFibGUoZ3JhcGhfcHRzZC5nKSAjdGhlIGRldGFpbHMgb2YgY2VudHJhbGl0eQoKIyMjIOeos+WBpeaAp+ajgOmqjApuZXR3b3JrMT1lc3RpbWF0ZU5ldHdvcmsoZGF0YXcyMiwgZGVmYXVsdCA9ICJwY29yIikgI+i/nue7reWPmOmHjwojbmV0d29yazE9ZXN0aW1hdGVOZXR3b3JrKGRhdGF3MjIsIGRlZmF1bHQgPSAiRUJJQ2dsYXNzbyIpICPpobrluo/lj5jph48KCmJvb3QxID0gYm9vdG5ldChuZXR3b3JrMSwgbkJvb3RzID0gMTAwLCAgbkNvcmVzID0gNCkgIyDovrnkvLDorqHmo4DpqowKYm9vdDMgPSBib290bmV0KG5ldHdvcmsxLCBuQm9vdHMgPSAxMDAsIHR5cGUgPSAnY2FzZScsIG5Db3JlcyA9IDQpICMg5Lit5b+D5oCn5Lyw6K6h5qOA6aqMCgpwbG90KGJvb3QxLCBsYWJlbHMgPSBGLCBvcmRlciA9ICJzYW1wbGUiICkgCiMgZGV2Lm9mZigpCnBsb3QoYm9vdDMpCiNkZXYub2ZmKCkKY29yU3RhYmlsaXR5KGJvb3QzKSAj6L6T5Ye6Q1Pns7vmlbDvvIzlv4Xpobvpkojlr7l0eXBlID0gJ3BlcnNvbifmiY3ooYwKCmBgYAoKIyMgMS4yIOWIhue7hOWkjeeOsOS+i+WtkOS6jAoK4oCD4oCD5Zyo5LiA5Lqb5oOF5Ya15Lit77yM56CU56m26ICF5Y+v6IO95oOz6KaB5bCG5q+U6L6D5LiN5ZCM57uE5Y+Y6YeP6Ze055qE5YWz57O777yM5q2k5pe25bCx5Y+v5Lul5bCG5omA57qz5YWl55qE5Y+Y6YeP6L+b6KGM5YiG57uE77yI5aaC5ZCM5LiA5b+D55CG55a+55eF55qE5LiN5ZCM55eH54q257uE77yJ77yM5Lul5q2k5pu055u06KeC5ZywKirmr5TovoPkuI3lkIznu4Tlj5jph4/pl7TnmoTogZTns7sqKuOAguS4uuS6huWcqOWumumHj+WfuuehgOS4iuabtOWlveWcsCoq5o6i56m25LiN5ZCM57uE5Y+Y6YeP6Ze055qE5YWz6IGU5aSn5bCPKirvvIzluLjkvb/nlKjnmoTkuIDnp43liIbmnpDmlrnlvI/mmK/moaXmooHliIbmnpDjgIIKCuKAg+KAg+ahpeaigeWIhuaekOeUsUpvbmVz562J5Lq65Zyo5Lit5b+D5oCn5oyH5qCH55qE5Z+656GA5LiK5o+Q5Ye677yM5YyF5ous5qGl5by65bqm77yIYnJpZGdlIHN0cmVuZ3Ro77yJ44CB5qGl5Lit5LuL5bqm77yIYnJpZGdlIGJldHdlZW5uZXNz77yJ44CB5qGl5Lqy6L+R5bqm77yIYnJpZGdlIGNsb3NlbmVzc++8ieWSjOahpemihOacn+W9seWTjeW6pu+8iGJyaWRnZSBleHBlY3RlZCBpbmZsdWVuY2XvvIkoSm9uZXMgZXQgYWwuLCAyMDIxKeOAguWQhOaMh+agh+WumuS5ieexu+S8vOS4juWQhOS4reW/g+aAp+aMh+agh++8jOS4jeWQjOS5i+WkhOWcqOS6ju+8jOS4reW/g+aAp+aMh+agh+ihoemHj+eahOaYr+afkOiKgueCueS4juaJgOacieWFtuS7luiKgueCueeahOWFs+ezu++8jOiAjOahpeaigeS4reW/g+aAp+aYr+WfuuS6juiKgueCueWIhue7hO+8jOWIhuaekOafkOS4gOe7hO+8iEHnu4TvvInlhoXmn5DkuIDoioLngrlOMeS4juWPpuS4gOe7hO+8iELnu4TvvInlhoXmiYDmnInoioLngrnnmoTlhbPns7vvvIzogIzkuI3orqHnrpdOMeS4juWQjOe7hOWGheWFtuS7luiKgueCueeahOWFs+iBlOOAguWboOatpO+8jOafkOS4gOiKgueCueeahOahpeS4reW/g+aAp+i2iumrmO+8iOWmgk4x77yJ77yM6KGo56S65a6D5Y+v6IO95piv5Zyo572R57uc5Lit6LW35Yiw6L+e5o6l5a6D5omA5Zyo57uE5LiO5YW25LuW57uE5YWz6IGU55qE5L2c55So77yM5Y2zQee7hOeahOWFtuS7luiKgueCuemAmui/h04x5LiO5YW25LuW57uE55qE6IqC54K55Lqn55Sf6IGU57O777yM6L+Z5qC355qE6IqC54K56KKr56ew5L2c4oCc5qGl5qKB6IqC54K54oCd44CC57G75Ly85Zyw77yM5Zyo5qGl5qKB5YiG5p6Q5Lit77yM5qGl5Lit5b+D5oCn5ZKM5qGlRUnooajnjrDlh7rmm7Tlpb3nmoTnqLPlrprvvIhKb25lcyBldCBhbC4sIDIwMjHvvInjgILlnKjlv4PnkIbpoobln5/kuK3vvIzmoaXmooHliIbmnpDlj6/ku6XnlKjmnaXliIbmnpDkuKTnu4Tlv4PnkIblrablj5jph4/pl7TnmoTlhbPogZTjgILku6XmipHpg4Hnl4fnirblkoznhKbomZHnl4fnirbnmoTlhbHmgqPnl4XnoJTnqbbkuLrkvovvvIzmoaXmooHliIbmnpDlj6/ku6XmoIforrDlh7rog73lpJ/op6Pph4rkuKTogIXlhbHmgqPnl4XnmoTnl4fnirbvvIhLYWlzZXIgZXQgYWwuLCAyMDIx77yJ77yM5Li655CG6Kej5Lik55eF5YWx5oKj55eF55qE5r2c5Zyo5py655CG6LW35Yiw5LqG5o+Q56S65L2c55So55qE5ZCM5pe277yM5Lmf6IO96LW35Yiw5o+t56S65r2c5Zyo5bmy6aKE5pa55byP55qE5L2c55So44CCCgrigIPigIPnoJTnqbbogIXku6zlj6/og73kvJrlpb3lpYcqKuS4jeWQjOe9kee7nOe7k+aehOaYr+WQpuacieaYjuaYvuW3ruW8gu+8jOS7peatpOaOoueptuafkOS6m+WPmOmHj+WcqOS4pOS4quS4jeWQjOe+pOS9k+mXtOeahOW3ruW8gioq44CC6ZmQ5LqO56+H5bmF77yM5q2k5aSE5LiN6ZKI5a+557q15ZCR5pWw5o2u55qE572R57uc5YiG5p6Q6L+b6KGM6L+H5aSa55qE6ZiQ6YeK5ZKM5Li+5L6L77yM5oSf5YW06Laj55qE6K+76ICF5Lmf5Y+v5Lul6Ieq6KGM6ZiF6K+76L+Z5LiA5Y+C6ICD5paH54yu77yIQm9yc2Jvb20gZXQgYWwuLCAyMDIx77yJ77yM6I635b6X5pu05YWo6Z2i55qE5LuL57uN44CC5Luj56CB5ZKM5L6L6aKY5Y+v5Lul6KeB5LiL5pa544CCCgpgYGB7ciBuZXQyfQpybShsaXN0ID0gbHMoKSkgI+eXlei/uea4hemZpAoj5a6J6KOF5b+F6KaB55qE5YyFCmxpYnJhcnkocWdyYXBoKSAjIEdyYXBoIFBsb3R0aW5nIE1ldGhvZHMsIFBzeWNob21ldHJpYyBEYXRhIFZpc3VhbGl6YXRpb24gYW5kIEdyYXBoaWNhbCBNb2RlbCBFc3RpbWF0aW9uCmxpYnJhcnkoTmV0d29ya0NvbXBhcmlzb25UZXN0KSAjIFN0YXRpc3RpY2FsIENvbXBhcmlzb24gb2YgVHdvIE5ldHdvcmtzIEJhc2VkIG9uIFNldmVyYWwgSW52YXJpYW5jZSBNZWFzdXJlcwpsaWJyYXJ5KG5ldHdvcmt0b29scykgIyBUb29scyBmb3IgSWRlbnRpZnlpbmcgSW1wb3J0YW50IE5vZGVzIGluIE5ldHdvcmtzCmRhdGEoJ2F0dGl0dWRlJykKCiPliIbnu4Tmr5TovoPvvIzpppblhYjliJvpgKDkuKTkuKrnu4TvvJtvYnPlgZrmiJDkuKTkuKrnu4Q75Y+Y6YeP5Lmf5YiG5LqG5Lik5Liq57uECmRhdGF3MjI9YXMuZGF0YS5mcmFtZShhdHRpdHVkZVtjKDE6MjkpLF0pICPpgInmi6nkvaDnmoTlvoXliIbmnpDmlbDmja4KZGF0YXczMz1hcy5kYXRhLmZyYW1lKGF0dGl0dWRlW2MoMjozMCksXSkgI+mAieaLqeS9oOeahOW+heWIhuaekOaVsOaNrgoKIyMj5oqK5pWw5o2u5Y+Y5oiQ55+p6Zi15b2i5byPCmRhdGEyMjIuY29yPWNvcl9hdXRvKGRhdGF3MjIsZGV0ZWN0T3JkaW5hbCA9RkFMU0UpIApkYXRhMzMzLmNvcj1jb3JfYXV0byhkYXRhdzMzLGRldGVjdE9yZGluYWwgPUZBTFNFKQoKIyMj5ZG95ZCN6IqC54K5L+WPmOmHjwpuYW1lcz1jKCJSQSIsIkNPIiwiUFIiLCJMRSIsIlJTIiwiQ1IiLCJBRCIpCmxvbmduYW1lcyA9IGMoIlJhdGluZyIsIkNvbXBsYWludHMiLCJQcml2aWxlZ2VzIiwiTGVhcm5pbmciLCJSYWlzZXMiLCJDcml0aWNhbCIsIkFkdmFuY2UiKQpncj1saXN0KCJUWVBFQSI9YygxOjMpLCAiVFlFUEIiPWMoNDo3KSkgICPlj5jph4/lgZrmiJDkuKTkuKrnu4QKCiMjIyBBLiBGaWd1cmUgMSMjCmdyYXBoX3B0c2QuZyA9IHFncmFwaCgKICBkYXRhMjIyLmNvciwKICBsYWJlbHMgPSBuYW1lcywKICBncmFwaCA9ICJwY29yIiwKICBsYXlvdXQgPSAic3ByaW5nIiwKICB2c2l6ZSA9IDYsCiAgY3V0ID0gMCwKICBtYXhpbXVtID0gLjk5LAogIHNhbXBsZVNpemUgPSBucm93KGRhdGF3MjIpLAogIGJvcmRlci53aWR0aCA9IDEuNSwKICBib3JkZXIuY29sb3IgPSAiYmxhY2siLAogIG1pbmltdW0gPSAuMSwKICBncm91cHMgPSBnciwKICBjb2xvciA9IGMoJyNhOGU2Y2YnLCAnI2RjZWRjMScpLAogIG5vZGVOYW1lcyA9IGxvbmduYW1lcywKICBsZWdlbmQuY2V4ID0gLjQKKQojZGV2Lm9mZigpCiMjIyBCLiBGaWd1cmUgMiMjCmdyYXBoX3B0c2QuZyA8LSBxZ3JhcGgoCiAgZGF0YTMzMy5jb3IsCiAgbGFiZWxzID0gbmFtZXMsCiAgZ3JhcGggPSAicGNvciIsCiAgbGF5b3V0ID0gInNwcmluZyIsCiAgdnNpemUgPSA2LAogIGN1dCA9IDAsCiAgbWF4aW11bSA9IC45OSwKICBzYW1wbGVTaXplID0gbnJvdyhkYXRhdzMzKSwKICBib3JkZXIud2lkdGggPSAxLjUsCiAgYm9yZGVyLmNvbG9yID0gImJsYWNrIiwKICBtaW5pbXVtID0gLjEsCiAgZ3JvdXBzID0gZ3IsCiAgY29sb3IgPSBjKCcjYThlNmNmJywgJyNkY2VkYzEnKSwKICBub2RlTmFtZXMgPSBsb25nbmFtZXMsCiAgbGVnZW5kLmNleCA9IC40CikKCiNkZXYub2ZmKCkKCiPmoaXmooHliIbmnpDpg6jliIYKYjI9ZGF0YTMzMy5jb3IKY29sbmFtZXMoYjIpPWMoIlJBIiwiQ08iLCJQUiIsIkxFIiwiUlMiLCJDUiIsIkFEIikKYTI9YnJpZGdlKGIyLGNvbW11bml0aWVzID0gbGlzdCgiVFlQRUEiPWMoMTozKSwiVFlFUEIiPWMoNDo3KSkpICPorqHnrpfmoaXmooHkuK3lv4PmgKc76L+Z6YeM55qE5oSP5oCd5pivYjLnmoTov5nkuKrkuprnu4TvvIhvYnPvvInljLrliIbvvJvlhbbkuK3nmoTmr4/kuKrlj5jph4/lkozmnKznu4Tlhbbku5blj5jph4/nmoTov57mjqXph43opoHmgKfvvJvkuI3mmK/kuKTkuKrnvZHnu5zvvIzogIzmmK/lkIzkuIDkuKrnvZHnu5zkuK3lj5jph4/liIbnu4TnmoTmiYDosJPmoaXmooHmgKfotKgKCnBsb3QoYTIsaW5jbHVkZSA9IGMoIkJyaWRnZSBTdHJlbmd0aCIsIkJyaWRnZSBFeHBlY3RlZCBJbmZsdWVuY2UgKDEtc3RlcCkiKSx6c2NvcmUgPSBULG9yZGVyPSJ2YWx1ZSIpCiPmoaXmooHkuK3lv4PmgKflm74KI2Rldi5vZmYoKQoKI+e9kee7nOavlOi+g+WIhuaekO+8m+i/memHjOWwseaYr+S4pOS4que9kee7nOWbvuWDj+S4jeWDj+eahOmXrumimOS6hu+8m+aYvuiRl+WwseS7o+ihqOWtmOWcqOaYvuiRl+W3ruW8gueahOaEj+aAne+8jOS4pOS4quWbvueahOS4reW/g+aAp+WSjOi+ueeahOmXrumimApjb2xuYW1lcyhkYXRhdzIyKT1jKCJSQSIsIkNPIiwiUFIiLCJMRSIsIlJTIiwiQ1IiLCJBRCIpCmNvbG5hbWVzKGRhdGF3MzMpPWMoIlJBIiwiQ08iLCJQUiIsIkxFIiwiUlMiLCJDUiIsIkFEIikKCmNvbTEgPSBOQ1QoCiAgZGF0YXcyMiwKICBkYXRhdzMzLAogIDAuNSwKICBpdCA9IDEwMDAsCiAgYmluYXJ5LmRhdGEgPSBGQUxTRSwKICBwYWlyZWQgPSBGQUxTRSwKICB3ZWlnaHRlZCA9IFRSVUUsCiAgQU5EID0gRkFMU0UsCiAgYWJzID0gRkFMU0UsCiAgdGVzdC5lZGdlcyA9IFRSVUUsCiAgZWRnZXMgPSAiYWxsIiwKICB0ZXN0LmNlbnRyYWxpdHkgPSBUUlVFLAogIHByb2dyZXNzYmFyID0gVFJVRSwKICBtYWtlLnBvc2l0aXZlLmRlZmluaXRlID0gVFJVRSwKICB2ZXJib3NlID0gVFJVRQopCmNvbTEKYGBgCgrigIPigIPku6XkuIrkuKTkuKrkvovpopjkvZzogIXorqTkuLrln7rmnKznmoTlupTku5jnroDljZXorrrmloflt7Lnu4/lpJ/nlKjkuobjgILphY3mnInkuI3nrpflpKror6bnu4bnmoTop4bpopHorrLop6PlpIfmn6XvvIEKCiMjIDEuMyDljp/nkIbooaXlhYXop6Por7sKCuKAg+KAg+e9kee7nOWIhuaekO+8iE5ldHdvcmsgYW5hbHlzaXPvvInmraPmmK/op6PlhrPmraTnsbvpl67popjnmoTkvJjlir/mlrnms5XvvIzov5HlubTmnaXmraPlnKjkuI3mlq3lj5fliLDmm7Tlub/ms5vnmoTlhbPms6jvvIzlubbkuJTmraPlnKjpgJDmraXmiJDkuLrku6Pmm7/mvZzlj5jph4/lu7rmqKHnmoTkvJjlir/mlrnms5XjgILkuL7kvovogIzoqIDvvIzlnKjkvb/nlKhHQUQtN+a1i+mHj+eEpuiZkeeXh+eKtuaXtu+8jOWwhuWQhOS4qua1i+mHj+adoeebruinhuS4uuS4gOS4queEpuiZkeeXh+eKtuaUvuWFpee9kee7nOWIhuaekOi/m+ihjOWFs+iBlOWRiOeOsO+8jOacgOWQjuWPr+S7peino+aekOWHuuacgOaguOW/g+eahOeEpuiZkeeXh+eKtu+8jOino+aekOWQhOS4queXh+eKtuS5i+mXtOeahOWkjeadguWFs+iBlOOAgue9kee7nOWIhuaekOS7peWbvuiuuuS9nOS4uueQhuiuuuWfuuehgO+8jOeUqOWPr+inhuWMluaWueW8j+WRiOeOsOWHuue7n+iuoee7k+aenO+8jOWPr+S7peabtOWKoOebtOinguWcsOS6huino+WQhOWPmOmHj+S5i+mXtOeahOWFs+ezu+OAggoK4oCD4oCD572R57uc57uT5p6E5Zu+5YyF5ous5LiN5ZCM55qE57G75Z6L77yM5Li76KaB5piv5raJ5Y+K6YCJ5oup5LiN5ZCM55qE55+p6Zi157G75Z6L44CC5LiA6Iis5p2l6K+077yM5YyF5ous5Lik56eN57G75Z6LOioq55u45YWz55+p6Zi1572R57ucKiooQ29ycmVsYXRpb24gbmV0d29ya3Mp5ZKMKirlgY/nm7jlhbPnvZHnu5wqKihQYXJ0aWFsIGNvcnJlbGF0aW9uIG5ldHdvcmtzKeOAguWJjemdoueahOS+i+WtkOe7meWumueahOWwseaYr+WBj+ebuOWFs+eahOefqemYteS9nOWbvuWSjOavlOi+g+iuoeeul+OAggoK4oCD4oCD5YW35L2T55qE6K+t5rOV5LiN5aSN5p2C77yM5p+l6ZiF55u45bqU55qE5Luj56CB5biu5Yqp5paH5Lu25Y2z5Y+v44CC6Zmk5LqGcWdyYXBo5YyF5LmL5aSW77yM6L+Y5Y+v5Lul5L2/55So4oCcYm9vdG5ldOKAneWMheeahOKAnGVzdGltYXRlTmV0d29ya+KAneWHveaVsOi/m+ihjOe9kee7nOWIhuaekOS8sOiuoQoKYE5ldHdvcms8LSBlc3RpbWF0ZU5ldHdvcmsoZGF0YSwgZGVmYXVsdCA9ICJjb3IiKSNjb3LmmK/nn6npmLXnsbvlnovkuLrnm7jlhbPnn6npmLXvvIxwY29y5YGP5ZCR5YWz55+p6Zi177yMZ2xhc3Nv5Li66Ieq6YCC5bqUTGFzc2/nrpfms5Xnn6npmLVgCgojIDIg6LCD6IqC55qE572R57uc5YiG5p6QCgojIyAyLjEgbW9kbmV0c+WMheWunueOsOi/h+eoiwoK4oCD4oCD5Z+65LqO5YmN6Z2iNO+8jOeglOeptuWkp+mDqOWIhuS7heaOouiuqOS6huiKgueCueS5i+mXtOeahOS4pOS4pOWFs+ezu++8jOS9huWvueS6juabtOWkjeadguacuuWItueahOiAg+Wvn+W+iOWwke+8jOS+i+Wmguiwg+iKguS9nOeUqOOAguW5tuS4lO+8jOWcqOiAg+Wvn+iwg+iKguS9nOeUqOeahOe9kee7nOWIhuaekOeglOeptuS4re+8jOebuOW9k+S4gOmDqOWIhuS7heS7heaYr+eugOWNleeahOWwhuaVtOS4quagt+acrOWIhuS4uuWHoOS4quWtkOagt+acrO+8iOS+i+WmguWIhuS4uueUt+aAp+WSjOWls+aAp++8ieWIhuWIq+i/m+ihjOe9kee7nOWIhuaekOOAguWboOatpO+8jOS4uuS6huabtOWHhuehrueahOS8sOiuoeiwg+iKguWPmOmHj+WvueiKgueCuee9kee7nOeahOS9nOeUqO+8jOacieeglOeptuiAheW8gOWPkeS6huacieiwg+iKgueahOe9kee7nOWIhuaekOaKgOacr+OAggoK4oCD4oCD5LyX5omA5ZGo55+l77yM6YeH55SoR0dN5pa55rOV5Lyw6K6h5peg5ZCR572R57uc5qih5Z6L5piv5p6E5bu65YGP55u45YWz55+p6Zi144CC54S26ICM77yM5b2T5qih5Z6L5Lit5YyF5ZCr6LCD6IqC5Zug5a2Q44CB5Y2P5Y+Y6YeP5oiW5Lu75L2V6auY6Zi25Lqk5LqS6aG55pe277yM6L+Z56eN5pa55rOV5bCx5LiN5ZCI6YCC5LqG44CC5Zug5q2k77yM5Y+v5Lul5L2/55So5Y+m5LiA56eN56ew5Li66IqC54K55pm66IO95Zue5b2S55qE5pa55rOVKEVwc2thbXAgZXQgYWwuLCAyMDE4Ke+8jOivpeaWueazleWfuuS6juS4gOenjeensOS4uumCu+Wfn+mAieaLqShuZWlnaGJvcmhvb2Qgc2VsZWN0aW9uKeeahOe7k+aehOWtpuS5oOWbvuiuuuaWueazle+8jOW5tumcgOimgemAmui/h+S4gOezu+WIl+WNleWPmOmHj+WbnuW9kuaooeWei+adpeS8sOiuoee9kee7nOe7k+aehOOAguS5n+WwseaYr+ivtO+8jOS4uue9kee7nOS4reS4uuavj+S4quiKgueCueaehOW7uuS4gOS4quWNleeLrOeahOWbnuW9kuaooeWei++8jOeEtuWQjui3qOaooeWei+iBmuWQiOezu+aVsOS7peW9ouaIkOacgOe7iOeahOe9kee7nOe7k+aehOOAggoKYGBge3IgbmV0M30Kcm0obGlzdCA9IGxzKCkpICPnl5Xov7nmuIXpmaQKbGlicmFyeShtb2RuZXRzKSAjIE1vZGVsaW5nIE1vZGVyYXRlZCBOZXR3b3Jrcwpza2ltKGdnbURhdCkKCmZpdDE9Zml0TmV0d29yayhnZ21EYXQpCnBsb3ROZXQoZml0MSkgI3Bsb3Tlh7rplJnvvIznvLrkuY/lr7nosaEKZml0MSRhZGpNYXQKZml0Mj1lc3RpbWF0ZU5ldHdvcmsoZ2dtRGF0LGRlZmF1bHQgPSAnZ2dtTW9kU2VsZWN0JykKcGxvdChmaXQyKQpmaXQyJGdyYXBoCiPlj6/ku6XnnIvliLDvvIzkuKTnp43mlrnms5XmiYDlvpfliLDnmoTnvZHnu5zmmK/nm7jkvLznmoQKCmZpdDM9Zml0TmV0d29yayhnZ21EYXQsJ00nKSAj5YW25Lit4oCZTeKAmeS4uuiwg+iKguWPmOmHj+eahOWPmOmHj+WQjQpwbG90TmV0KGZpdDMpCiPnlLHkuo7miJHku6zkvb/nlKjnmoTmmK/pu5jorqTorr7nva7vvIzor6XnvZHnu5zph4fnlKjnmoTmmK/igJxPUuKAneinhOWImQpmaXQzLjE9Zml0TmV0d29yayhnZ21EYXQsJ00nLHJ1bGUgPSAnQU5EJykgI0FOROinhOWImQpwbG90TmV0KGZpdDMuMSkKCiPlsIbosIPoioLlj5jph4/lnKjlm77kuK3mmL7npLrlh7rmnaUs5ZCM5pe25pi+56S66L6555qE57O75pWw44CCCnBsb3ROZXQoZml0MyxtbmV0ID0gVFJVRSxlbGFicyA9IFQpCgoj5Yqg5LiK5bCG5q+P5Liq6IqC54K555u45YWz55qE6aKE5rWL6K+v5beu5Zyo6IqC54K55ZGo5Zu057uY5Yi25Li66aW854q25Zu+77yI5LiN6IO95ZKMbW5ldCA9IFRSVUXlkIzml7bkvb/nlKjvvIkKcGxvdE5ldChmaXQzLHByZWRpY3QgPSBUUlVFLGVsYWJzID0gVCxjb249J1IyJykgI+mlvOWtkOS7o+ihqFIyCgoj5Lyw6K6h5Lik5Liq6IqC54K55LmL6Ze05Y2V5ZCR6aKE5rWL5YWz57O755qE6LCD6IqC6L656ZmF5pWI5bqU5Zu+CmxpYnJhcnkoYXJtKSAjIERhdGEgQW5hbHlzaXMgVXNpbmcgUmVncmVzc2lvbiBhbmQgTXVsdGlsZXZlbC9IaWVyYXJjaGljYWxNb2RlbHMKY29uZFBsb3QoZml0Myxmcm9tPSdWNCcsdG89J1Y1JykKCiPkvLDorqHoioLngrnnmoTkuK3lv4PmgKfmjIfmoIcKY2VudFBsb3QoZml0MyxzY2FsZSA9IGMoInotc2NvcmVzIikpCmNlbnRUYWJsZShmaXQzLHNjYWxlID0gVCkKCiPovrnnmoTnqLPlrprmgKcv5YeG56Gu5oCn5Lyw6K6h5ZKM5beu5byC5qOA6aqMCmJvb3QxPW1vZG5ldHM6OmJvb3ROZXQoZ2dtRGF0LCdNJyxuYm9vdD0xMDApCnBsb3RCb290KGJvb3QxKSAj5L+u6K6i5LqG5o6o5paH5ZG95Luk5bem5Zu+5Luj6KGo5Lqk5LqS5L2c55So55qE6L6577yM5Zu+5Y+z5Luj6KGo5oiQ5a+56IqC54K555qE6L65Cgpib290Mj1tb2RuZXRzOjpib290TmV0KGdnbURhdCwnTScsbmJvb3Q9MTAwLGNhc2VEcm9wID0gVCkKcGxvdEJvb3QoYm9vdDIpICPov5vkuIDmraXpgJrov4djYXNlRHJvcCBib290c3RyYXDmlrnms5XkvLDorqHovrnnmoTnqLPlrprmgKcKCnBsb3RCb290KGJvb3QxLGRpZmZlcmVuY2UgPSBUKSAj5qOA6aqM6L655LmL6Ze05piv5ZCm5a2Y5Zyo5beu5byCCgoj6IqC54K555qE56iz5a6a5oCnL+WHhuehruaAp+S8sOiuoQoKcGxvdEJvb3QoYm9vdDEsdHlwZT0nc3RyZW5ndGgnKQpwbG90Qm9vdChib290Mix0eXBlPSdzdHJlbmd0aCcpICPov5vkuIDmraXpgJrov4djYXNlRHJvcCBib290c3RyYXDmlrnms5XkvLDorqHoioLngrnnmoTnqLPlrprmgKcKcGxvdEJvb3QoYm9vdDEsZGlmZmVyZW5jZSA9IFQsdHlwZT0nc3RyZW5ndGgnKSAj5qOA6aqM6IqC54K55Lit5b+D5oCn5LmL6Ze05piv5ZCm5a2Y5Zyo5beu5byCCmBgYAoKIyMgMi4yIG1nbeWMheWunueOsOi/h+eoiwoK4oCD4oCD5LulMjAyMuW5tOWcqEFwcGxpZWQgUHN5Y2hvbG9neTogSGVhbHRoIGFuZCBXZWxsLUJlaW5n5LiK5Y+R6KGo55qE5paH56ug44CKQ2hhbmdlcyBpbiB0aGUgbmV0d29yayBzdHJ1Y3R1cmUgb2YgbWVudGFsIGhlYWx0aCBhZnRlciBhIG11bHRpY29tcG9uZW50IHBvc2l0aXZlIHBzeWNob2xvZ3kgaW50ZXJ2ZW50aW9uIGluIGFkb2xlc2NlbnRzOiBBIG1vZGVyYXRlZCBuZXR3b3JrIGFuYWx5c2lz44CL5Li65L6LKFRlamFkYeKAkEdhbGxhcmRvIGV0IGFsLiwgMjAyMinvvIzor6bnu4bnmoTku6PnoIHlkozmlbDmja7lt7Lnu4/kuIvovb3kuIvovb3vvJvln7rkuo7kuIvovb3nmoTku6PnoIHmnaXov5vooYzlpI3njrDlkoznkIbop6PjgIIKCuKAg+KAg+acrOeglOeptueahOe7k+aenOWIhuS4uuS4ieS4quaVsOaNrumbhkRhdGFQcmXjgIFEYXRhUG9zdOWSjERhdGFGde+8jOWIhuWIq+S7o+ihqOS4ieS4quaXtumXtOeCueaJgOa1i+W+l+eahOaVsOaNruOAguavj+S4quaVsOaNrumbhuWMheWQqzfkuKrlj5jph4/jgIIKCmBgYHtyIG5ldDR9CnJtKGxpc3QgPSBscygpKSAj55eV6L+55riF6ZmkCiMjIENoYW5nZXMgaW4gdGhlIHN0cnVjdHVyZSBvZiBtZW50YWwgaGVhbHRoIGFmdGVyIGEgbXVsdGljb21wb25lbnQgcG9zaXRpdmUgcHN5Y2hvbG9neSAKIyNpbnRlcnZlbnRpb24gaW4gYWRvbGVzY2VudHM6IEEgbG9uZ2l0dWRpbmFsIG5ldHdvcmsgYW5hbHlzaXMKCiNzZXR3ZCgifi8uLi4iKQpsaWJyYXJ5KCJmb3JlaWduIikgIyBSZWFkIERhdGEgU3RvcmVkIGJ5ICdNaW5pdGFiJywgJ1MnLCAnU0FTJywgJ1NQU1MnLCAnU3RhdGEnLCdTeXN0YXQnLCAnV2VrYScsICdkQmFzZScsIC4uLgpsaWJyYXJ5KG1nbSkgIyBFc3RpbWF0aW5nIFRpbWUtVmFyeWluZyBrLU9yZGVyIE1peGVkIEdyYXBoaWNhbCBNb2RlbHMKbGlicmFyeShwc3ljaCkgIyBQcm9jZWR1cmVzIGZvciBQc3ljaG9sb2dpY2FsLCBQc3ljaG9tZXRyaWMsIGFuZCBQZXJzb25hbGl0eSBSZXNlYXJjaApsaWJyYXJ5KHFncmFwaCkgIyBHcmFwaCBQbG90dGluZyBNZXRob2RzLCBQc3ljaG9tZXRyaWMgRGF0YSBWaXN1YWxpemF0aW9uIGFuZCBHcmFwaGljYWwgTW9kZWwgRXN0aW1hdGlvbgpsaWJyYXJ5KGJvb3RuZXQpICMgQm9vdHN0cmFwIE1ldGhvZHMgZm9yIFZhcmlvdXMgTmV0d29yayBFc3RpbWF0aW9uIFJvdXRpbmVzCgoKIyNMb2FkIERhdGEjIwpEYXRhUHJlIDwtcmVhZC5zcHNzKCcvVXNlcnMvbWVuZ3Rhb2dhby9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS3lhbHkuqvnmoTlupMtb25lZHJpdmUvb3V0c3luL3N0YXRpb24vRWZmZWN0cyBvZiBhbiBNUFBJIG9uIG1lbnRhbCBoZWFsdGgvUHJlX01OTS5zYXYnLCB0by5kYXRhLmZyYW1lPVQpCkRhdGFQb3N0IDwtcmVhZC5zcHNzKCcvVXNlcnMvbWVuZ3Rhb2dhby9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS3lhbHkuqvnmoTlupMtb25lZHJpdmUvb3V0c3luL3N0YXRpb24vRWZmZWN0cyBvZiBhbiBNUFBJIG9uIG1lbnRhbCBoZWFsdGgvUG9zdF9NTk0uc2F2JywgdG8uZGF0YS5mcmFtZT1UKQpEYXRhRnUgPC1yZWFkLnNwc3MoJy9Vc2Vycy9tZW5ndGFvZ2FvL0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLeWFseS6q+eahOW6ky1vbmVkcml2ZS9vdXRzeW4vc3RhdGlvbi9FZmZlY3RzIG9mIGFuIE1QUEkgb24gbWVudGFsIGhlYWx0aC9GdV9NTk0uc2F2JywgdG8uZGF0YS5mcmFtZT1UKQoKIyBjbGFzcyhEYXRhUHJlKSAj5qOA5p+l5LiA5LiL5pWw5o2u5qGG5p625YyF5ousdmlldwojIyNOZXR3b3JrIG1vZGVscyMjCk5ldF9QcmU8LWVzdGltYXRlTmV0d29yayhEYXRhUHJlLCBkZWZhdWx0PSJnZ21Nb2RTZWxlY3QiLCBzdGVwd2lzZT1UUlVFKQpOZXRfUG9zdDwtZXN0aW1hdGVOZXR3b3JrKERhdGFQb3N0LCBkZWZhdWx0PSJnZ21Nb2RTZWxlY3QiLCBzdGVwd2lzZT1UUlVFKQpOZXRfRnU8LWVzdGltYXRlTmV0d29yayhEYXRhRnUsIGRlZmF1bHQ9ImdnbU1vZFNlbGVjdCIsIHN0ZXB3aXNlPVRSVUUpCgpwbG90KE5ldF9QcmUpCnBsb3QoTmV0X1Bvc3QpCnBsb3QoTmV0X0Z1KQoj5LuO5bem5Yiw5Y+z5YiG5Yir5piv5LiJ5Liq5pe26Ze054K55qiq5pat572R57uc77yM5Y+v5Lul5Y+R546w6LCD6IqC5Y+Y6YeP5LiO5Lu75L2V6IqC54K55Z2H5peg5pi+6JGX55u45YWzCiPlsIbliIbnu4TkvZzkuLrosIPoioLlj5jph4/vvIzkvLDorqFNTk1zO+W4uOinhOaTjeS9nOi/kOihjOato+W4uOaaguaXtueVpei/hwojIGNlbnRyYWxpdHlQbG90KE5ldF9GdSwgaW5jbHVkZT1jKCJTdHJlbmd0aCIsICJFeHBlY3RlZEluZmx1ZW5jZSIpLCBzY2FsZT1jKCJ6LXNjb3JlIikpCgojd2VpZ2h0LWVkZ2UgYWNjdXJhY3kKIyBib290MTwtYm9vdG5ldChOZXRfRnUsIG5Cb290cz0xMDAsIHR5cGU9InBhcmFtZXRyaWMiLCBuQ29yZXM9MikKIyBwbG90KGJvb3QxLCBvcmRlciA9ICJzYW1wbGUiKQojIHBsb3QoYm9vdDEpCiMgZGV2Lm9mZigpCgojI2NlbnRyYWxpdHkgc3RhYmlsaXR5IyMKIyBib290MiA8LSBib290bmV0KE5ldF9QcmUsIG5Cb290cyA9IDEwMCwgdHlwZSA9ICJjYXNlIiwgbkNvcmVzID0gMikKIyBwbG90KGJvb3QyKQojIGNvclN0YWJpbGl0eShib290MikKCiNQcmUtdGVzdCMKc2V0LnNlZWQoMzApCm1nbV9vYmpQcmUgPC0gbWdtKAogIGRhdGEgPSBhcy5tYXRyaXgoRGF0YVByZSksCiAgdHlwZSA9IGMoImMiLCAiZyIsICJnIiwgImciLCAiZyIsICJnIiwgImciKSwKICBsZXZlbCA9IGMoMiwgMSwgMSwgMSwgMSwgMSwgMSksCiAgbGFtYmRhU2VsID0gIkNWIiwKICBsYW1iZGFHYW0gPSAuMjUsCiAgcnVsZVJlZyA9ICJBTkQiLAogIG1vZGVyYXRvcnMgPSAxLAogIHNjYWxlID0gVFJVRQopCgptZ21fb2JqUHJlCgoKI1ByZS10ZXN0IwpsX21nbV9jb25kIDwtIGxpc3QoKQpmb3IoZyBpbiAxOjIpIGxfbWdtX2NvbmRbW2ddXSA8LSBjb25kaXRpb24ob2JqZWN0ID0gbWdtX29ialByZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGxpc3QoIjEiID0gZykpCgp2X21heCA8LSByZXAoTkEsIDIpCmZvcihnIGluIDE6Mikgdl9tYXhbZ10gPC0gbWF4KGxfbWdtX2NvbmRbW2ddXSRwYWlyd2lzZSR3YWRqKQpwYXIobWZyb3c9YygxLCAyKSkKZm9yKGcgaW4gMToyKSB7CiAgcWdyYXBoKGlucHV0ID0gbF9tZ21fY29uZFtbZ11dJHBhaXJ3aXNlJHdhZGosICNwbG90IGZyb20gd2ViIHR1dG9yaWFsCiAgICAgICAgIGVkZ2UuY29sb3IgPSBsX21nbV9jb25kW1tnXV0kcGFpcndpc2UkZWRnZWNvbG9yX2NiLAogICAgICAgICBsdHkgPSBsX21nbV9jb25kW1tnXV0kcGFpcndpc2UkZWRnZV9sdHksCiAgICAgICAgIGxheW91dCA9ICJjaXJjbGUiLCBtYXIgPSBjKDIsIDMsIDUsIDMpLAogICAgICAgICB0aXRsZSA9ICJUaW1lIDEiLCBsYWJlbHMgPSBjb2xuYW1lcyhEYXRhUHJlKSwKICAgICAgICAgbWF4aW11bSA9IG1heCh2X21heCksIHZzaXplID0gMTAsIGVzaXplID0gMjMsCiAgICAgICAgIGVkZ2UubGFiZWxzICA9IFRSVUUsIGVkZ2UubGFiZWwuY2V4ID0gMykKICBtdGV4dCh0ZXh0ID0gcGFzdGUwKCJHcm91cCIsIGcpLCBsaW5lID0gMi41LAogICkKfQojIGRldi5vZmYoKQoKI1Bvc3QtdGVzdCMKc2V0LnNlZWQoMzApCm1nbV9vYmpQb3N0IDwtIG1nbShkYXRhID0gYXMubWF0cml4KERhdGFQb3N0KSwKICAgICAgICAgICAgICAgICAgIHR5cGUgPSBjKCJjIiwgImciLCAiZyIsICJnIiwgImciLCAiZyIsICJnIiksCiAgICAgICAgICAgICAgICAgICBsZXZlbCA9IGMoMiwgMSwgMSwgMSwgMSwgMSwgMSksCiAgICAgICAgICAgICAgICAgICBsYW1iZGFTZWwgPSAiQ1YiLAogICAgICAgICAgICAgICAgICAgbGFtYmRhR2FtID0uMjUsCiAgICAgICAgICAgICAgICAgICBydWxlUmVnID0gIkFORCIsCiAgICAgICAgICAgICAgICAgICBtb2RlcmF0b3JzID0gMSwKICAgICAgICAgICAgICAgICAgIHNjYWxlID0gVFJVRSkKCiMgQXNzZXNzIFN0YWJpbGl0ee+8jOavlOi+g+iAl+aXtgpyZXNfb2JqIDwtIHJlc2FtcGxlKG9iamVjdCA9IG1nbV9vYmpQb3N0LAogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBhcy5tYXRyaXgoRGF0YVBvc3QpLAogICAgICAgICAgICAgICAgICAgIG5CID0gNTAsCiAgICAgICAgICAgICAgICAgICAgcGJhciA9IFRSVUUpCgpwbG90UmVzKHJlc19vYmopCgpgYGAKCuKAg+KAg+eos+WumuaAp+W3puWbvuaYvuekuuS4pOS4quiKgueCueS5i+mXtOeahOaIkOWvueaViOW6lO+8jOWPs+WbvuaYvuekuuiwg+iKguaViOW6lOOAguWchuWciOS4reeahOWAvOihqOekuuS8sOiuoee7meWumuWPguaVsOS4uumdnumbtueahGJvb3RzdHJhcOagt+acrOeahOavlOS+i++8jOm7keiJsue6v+adoeeahOS4pOauteihqOekujUl5ZKMOTUlYm9vdHN0cmHljLrpl7TjgILlj6/ku6Xlj5HnjrDvvIzlnKjkuI3lkIzml7bpl7TkuIvvvIzmiJDlr7nlkozosIPoioLmlYjlupTpg73mmK/nm7jlvZPnqLPlrprnmoTjgILosIPoioLmlYjlupTlnKjml7bpl7Tngrky5pe25piO5pi+5pu05by677yM5Zug5Li65pyJ5Yeg5Liq5YC86L+c56a76Zu244CCCgrigIPigIPmhJ/op4nov5nkuKrpg6jliIbnmoTljp/nkIbov5jkuI3mmK/lpKrmuIXmpZrjgIIKCiMgMyDml7bpl7TnvZHnu5zliIbmnpAKCuKAg+KAg+e6teWQkeaVsOaNruWPr+S7peWIhuS4uuS4pOenjeexu+Wei++8muWPkeWxlei/h+eoi+aVsOaNruWSjOeos+Wumui/h+eoi+aVsOaNruOAgui/meS4pOenjeaVsOaNruaYr+mAmui/h+S4jeWQjOeahOeglOeptuiuvuiuoeWSjOa1i+mHj+aWueazleW+l+WIsOeahO+8jOS4pOiAheeahOS4u+imgeW3ruWIq+WPr+S7peingeS4i+ihqOOAglvpkojlr7kyXH4z5qyh6L+96Liq55qE6Z2i5p2/5pWw5o2u77yM55uu5YmN5bi455So5Lqk5Y+J5rue5ZCO572R57uc5YiG5p6Q44CC6ICM6ZKI5a+5NeasoeS7peS4iui/vei4queahOmdouadv+aVsOaNruWSjOWvhumbhue6teWQkeaVsOaNruWImeW4uOeUqOaXtumXtOe9kee7nOWIhuaekOOAgl17LnVuZGVybGluZX0KCuKAg+KAg+S4u+imgeWPguiAg+aOqOaWh++8mlvml7bpl7TnvZHnu5zliIbmnpAoVGVtcG9yYWwgTmV0d29yayBBbmFseXNpcynlhaXpl6jmlZnnqItdKGh0dHBzOi8vbXAud2VpeGluLnFxLmNvbS9zL2lZT2pGSng5TEhIenlFdHIwdUJIbGcp44CC5Zyo6L+Z6YeM5oiR5Lus5L2/55So44CKQSBUZW1wb3JhbCBOZXR3b3JrIEFwcHJvYWNoIHRvIFBhcmFub2lhOiBBIFBpbG90IFN0dWR544CL5Lit55qE5pWw5o2u5Li65L6LKENvbnRyZXJhcyBldCBhbC4sIDIwMjAp44CC5pe26Ze0572R57uc5YiG5p6Q5pa55rOV5bu656uL5LqO4oCc5ZCR6YeP6Ieq5Zue5b2S4oCdKFZlY3RvciBhdXRvcmVncmVzc2lvbiwgVkFSKeaooeWei+S5i+S4iuOAgueugOWNleadpeivtO+8jOWQkemHj+iHquWbnuW9kuaooeWei+S4reeahOKAnOWQkemHj+KAneaMh+eahOaYr+WkmuWFg+eJueW+ge+8jOaYr+WNleWPmOmHj+iHquWbnuW9kuaooeWei+eahOW7tuS8uOOAguiAjOWQkemHj+iHquWbnuW9kuaooeWei+eUseS4gOe7hOWbnuW9kuaWueeoi+e7hOaIkO+8jOWFtuS4reaJgOacieWPmOmHj+mDveiiq+inhuS4uuWGheeUn+WPmOmHj+OAguWboOatpO+8jOWug+S7rOaXouWPr+S7peS9nOS4uuiHquWPmOmHj++8jOS5n+WPr+S7peS9nOS4uuWboOWPmOmHj+OAguaJgOS7pe+8jOWQkemHj+iHquWbnuW9kuWIhuaekOWPr+S7peWcqOayoeacieWFs+S6juWPmOmHj+S5i+mXtOWFs+iBlOaWueWQkeeahOWFiOmqjOWBh+iuvueahOaDheWGteS4i+i/m+ihjOOAgumAmui/h+i/meenjeaWueazle+8jOaIkeS7rOWwseWPr+S7peefpemBk+WkmuS4quWPmOmHj+S5i+mXtOeahOi3qOaXtumXtOWKqOaAgeWFs+ezu+OAggoK4oCD4oCD5ZyoUuS4re+8jOaIkeS7rOS9v+eUqG1sVkFS5YyF5a6e546w5pe26Ze0572R57uc5YiG5p6Q44CC5ZyoUuS4re+8jOaIkeS7rOS9v+eUqG1sVkFS5YyF5a6e546w5pe26Ze0572R57uc5YiG5p6Q44CCCgpgYGB7ciBuZXQ1fQpybShsaXN0ID0gbHMoKSkgI+eXlei/uea4hemZpAojIExvYWQgcGFja2FnZXM6CiMtLS0tLS0tLS0tLS0tLS0gICAgICAgICAgICAgICAgICAgICAgICAgCmxpYnJhcnkoIm1sVkFSIikKbGlicmFyeSgiZ3JhcGhpY2FsVkFSIikKbGlicmFyeSgicWdyYXBoIikKbGlicmFyeShmb3JlaWduKSAgICAgIApsaWJyYXJ5KHFncmFwaCkKbGlicmFyeShuZXR3b3JrdG9vbHMpIApsaWJyYXJ5KGNvcnBjb3IpICAgICAgCmxpYnJhcnkodHNlcmllcykgICAgICAKbGlicmFyeShUU0EpICAgICAgICAgIApsaWJyYXJ5KGRwbHlyKQoKICBkYXRhc2V0PC0gcmVhZC5zcHNzKCcvVXNlcnMvbWVuZ3Rhb2dhby9MaWJyYXJ5L0Nsb3VkU3RvcmFnZS9PbmVEcml2ZS3lhbHkuqvnmoTlupMtb25lZHJpdmUvb3V0c3luL3N0YXRpb24vQSBUZW1wb3JhbCBOZXR3b3JrIEFwcHJvYWNoIHRvIFBhcmFub2lhL1RlbXBvcmFsIG5ldHdvcmsgYXBwcm9hY2ggdG8gcGFyYW5vaWFfZGF0YS5zYXYnLHRvLmRhdGEuZnJhbWU9VFJVRSwgdXNlLnZhbHVlLmxhYmVscyA9IEYpCiAgYmFzZWxpbmU8LWRhdGFzZXRbLGMoMTo0LDEwOjEzKV0KICAKICAjUHJlcGFyYXRpb246CiMtLS0tLS0tLS0tLS0KICBuYW1lcyhiYXNlbGluZSkgPC0gYygic3ViamVjdCIsImRheSIsImJlZXAiLCJzYWQiLCJvdGhlcnMiLCJFQSIsIlNFIiwicGFyYW5vaWEiKQogIHZhcnMgPC0gYyAoInNhZCIsIm90aGVycyIsIkVBIiwiU0UiLCJwYXJhbm9pYSIpCiAgaWR2YXIgPC0gInN1YmplY3QiCiAgZGF5dmFyPC0iZGF5IgogIGJlZXB2YXI8LSJiZWVwIgogIAogICNFc3RpbWF0aW9uOiB0d28tc3RlcCBtdWx0aWxldmVsIFZlY3RvciBBdXRvcmVncmVzc2l2ZSAobWxWQVIpOgojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KYmFzZWxpbmVfbWxWQVIgPC0gbWxWQVIoYmFzZWxpbmUsIHZhcnMsIGlkdmFyLCBsYWdzID0gMSwgZXN0aW1hdG9yID0gImxtZXIiLHRlbXBvcmFsID0gImNvcnJlbGF0ZWQiLCBjb250ZW1wb3JhbmVvdXMgPSAiY29ycmVsYXRlZCIpCiAgCiAgI1Zpc3VhbGl6YXRpb246CiMtLS0tLS0tLS0tLS0tLQogIAogICNTZXBhcmF0ZWQgcGxvdDogCmNvbnRlbXBvcmFuZW91czwtcGxvdChiYXNlbGluZV9tbFZBUiwgImNvbnRlbXBvcmFuZW91cyIsIGxheW91dCA9ICJjaXJjbGUiLCBub25zaWcgPSAiaGlkZSIsIHRoZW1lID0gImNvbG9yYmxpbmQiLCB0aXRsZSA9ICJDb250ZW1wb3JhbmVvdXMiLApsYWJlbHMgPSB2YXJzLCB2c2l6ZSA9IDEzLCBydWxlID0gImFuZCIsIGFzaXplID0gMTAsIG1hciA9IGMoNSw1LDUsNSkpCgp0ZW1wb3JhbDwtcGxvdChiYXNlbGluZV9tbFZBUiwgInRlbXBvcmFsIiwgbGF5b3V0ID0gImNpcmNsZSIsIG5vbnNpZyA9ICJoaWRlIiwgdGhlbWUgPSAiY29sb3JibGluZCIsIHRpdGxlID0gIlRlbXBvcmFsIixsYWJlbHMgPSB2YXJzLCB2c2l6ZSA9IDEzLCBydWxlID0gImFuZCIsIGFzaXplID0gNSwgbWFyID0gYyg1LDUsNSw1KSkKCmJldHdlZW5fc3ViamVjdHM8LXBsb3QoYmFzZWxpbmVfbWxWQVIsICJiZXR3ZWVuIiwgbGF5b3V0ID0gImNpcmNsZSIsIG5vbnNpZyA9ICJoaWRlIiwgIHRoZW1lID0gImNvbG9yYmxpbmQiLCB0aXRsZSA9ICJCZXR3ZWVuLXN1YmplY3RzIixsYWJlbHMgPSB2YXJzLCB2c2l6ZSA9IDEzLCBydWxlID0gImFuZCIsIGFzaXplID0gMTAsIG1hciA9IGMoNSw1LDUsNSkpCgoj6IqC54K55Lit5b+D5oCn5Lyw6K6hCmNlbnRyYWxpdHlQbG90KGNvbnRlbXBvcmFuZW91cyxpbmNsdWRlID0gYygnU3RyZW5ndGgnLCdDbG9zZW5lc3MnLCdCZXR3ZWVubmVzcycsIkV4cGVjdGVkSW5mbHVlbmNlIikpCmNlbnRyYWxpdHkoY29udGVtcG9yYW5lb3VzKQpjZW50cmFsaXR5UGxvdCh0ZW1wb3JhbCxpbmNsdWRlID0gYygnU3RyZW5ndGgnLCdDbG9zZW5lc3MnLCdCZXR3ZWVubmVzcycsIkV4cGVjdGVkSW5mbHVlbmNlIikpCmNlbnRyYWxpdHkodGVtcG9yYWwpCmNlbnRyYWxpdHlQbG90KGJldHdlZW5fc3ViamVjdHMsaW5jbHVkZSA9IGMoJ1N0cmVuZ3RoJywnQ2xvc2VuZXNzJywnQmV0d2Vlbm5lc3MnLCJFeHBlY3RlZEluZmx1ZW5jZSIpKQpjZW50cmFsaXR5KGJldHdlZW5fc3ViamVjdHMpCmBgYAoKLSAgIOaXtumXtOe9kee7nO+8iFRlbXBvcmFsIG5ldHdvcmvvvInjgILml7bpl7TnvZHnu5zkuK3ovrnooajnpLrlnKjmjqfliLbkuobliY3kuIDkuKrmtYvph4/ngrnkuIrnmoTmiYDmnInlhbbku5blj5jph4/lkI7vvIzliY3kuIDkuKrmtYvph4/ngrnlr7nkuIvkuIDkuKrmtYvph4/ngrnnmoToioLngrnnmoTpooTmtYvog73lipvjgILkvovlpoLlm77kuK3miJHku6zlj6/ku6Xlj5HnjrDvvIzmgrLkvKTjgIHkuI7ku5bkurrnmoTkurLlr4bluqbjgIHkvZPpqozlm57pgb/jgIHoh6rlsIrjgIHlgY/miafkv6Hlv7Xpg73lrZjlnKhb6Ieq5Zue5b2S5pWI5bqUXXsudW5kZXJsaW5lfeOAguS4juS7luS6uueahOS6suWvhuW6pua2iOaegeWcsOmihOa1i+S6huS4i+S4gOS4quaXtumXtOeCueeahOWBj+aJp++8jOaCsuS8pOenr+aegeWcsOmihOa1i+S6huS9k+mqjOWbnumBv++8jOiAjOS9k+mqjOWbnumBv+WPjei/h+adpeWPiOenr+aegeWcsOmihOa1i+S6huS4i+S4gOS4quaXtumXtOeCueeahOiHquWwijvlhbblrp7lsLHmmK93aXRoaW7kvLDorqHnsbvkvLzjgIIKCi0gICDlkIzml7bnvZHnu5zvvIhDb250ZW1wb3JhbmVvdXMgbmV0d29ya++8ieOAguWQjOaXtue9kee7nOS4reeahOi+ueihqOekuuWcqOaOp+WItuS6huaXtumXtOWFs+iBlOS5i+WQju+8jOWQjOS4gOaXtumXtOahhuaetuWGheWPmOmHj+S5i+mXtOeahOWFs+iBlOOAguWPr+S7peWPkeeOsOacieWHoOS4quiBlOezu+mdnuW4uOeqgeWHuu+8jOWBj+aJp+S/oeW/teWSjOaCsuS8pOWRiOato+ebuOWFs++8jOi/meihqOaYjuWcqOWQjOS4gOaXtumXtOauteWGhe+8jOWBj+aJp+S/oeW/teW+l+WIhui2iumrmO+8jOaCsuS8pOawtOW5s+i2iumrmOOAguWQjOagt++8jOaCsuS8pOS4juiHquWwiuWSjOS4juS7luS6uueahOS6suWvhuW6pumDveaYr+i0n+ebuOWFs+OAguaNouWPpeivneivtO+8jOaCsuS8pOeoi+W6pui2iumrmO+8jOiHquWwiuawtOW5s+i2iuS9ju+8jOWQjOaXtuS4juS7luS6uueahOS6suWvhuaEn+S5n+i2iuS9juOAguatpOWklu+8jOiHquWwiuWSjOS4juS7luS6uueahOS6suWvhuW6puaYr+ato+ebuOWFs+eahOOAguacgOWQju+8jOS9k+mqjOWbnumBv+S4juS7u+S9leWFtuS7luWPmOmHj+aXoOWFszsKCi0gICDkuKrkvZPpl7TnvZHnu5zvvIhCZXR3ZWVuLXN1YmplY3QgbmV0d29ya++8ieOAguS4quS9k+mXtOe9kee7nOaooeWei+i+ueihqOekuu+8jOWcqOiAg+iZkeWIsOe9kee7nOS4reeahOWFtuS9meWPmOmHj+WQju+8jOS4quS9k+WGhemDqOW5s+Wdh+awtOW5s+S5i+mXtOeahOebuOWFs+aAp+OAguWPr+S7peWPkeeOsO+8jOS4juS7luS6uueahOS6suWvhuW6pueahOW5s+Wdh+awtOW5s+S4juWBj+aJp+S/oeW/teeahOW5s+Wdh+awtOW5s+WRiOi0n+ebuOWFs++8jOS4juiHquWwiueahOW5s+Wdh+awtOW5s+WRiOato+ebuOWFs+OAguaCsuS8pOeahOW5s+Wdh+awtOW5s+S4juiHquWwiueahOW5s+Wdh+awtOW5s+WRiOi0n+ebuOWFs++8jOS4juS9k+mqjOWbnumBv+eahOW5s+Wdh+awtOW5s+WRiOato+ebuOWFs+OAguWFtuWunuWwseaYr0JldHdlZW7kvLDorqHph4/vvJsKCiMgNCDpkojlr7npnaLmnb/mlbDmja7nmoTml7bpl7TnvZHnu5zliIbmnpAoVGVtcG9yYWwgTmV0d29yayBBbmFseXNpcykKCuKAg+KAg+S7i+e7jemSiOWvuemdouadv+aVsOaNrueahOaXtumXtOe9kee7nOWIhuaekChUZW1wb3JhbCBOZXR3b3JrIEFuYWx5c2lzKeOAgumcgOimgeazqOaEj++8jOi/meenjee6teWQkee9kee7nOWIhuaekOaJgOmcgOimgeeahOmdouadv+aVsOaNruiHs+WwkeimgeacieS4ieS4qndhdmXjgILlubbkuJTvvIzpnaLmnb/mlbDmja7nmoTml7bpl7TnvZHnu5zliIbmnpDkuI7lr4bpm4bov73ouKrmlbDmja7nmoTml7bpl7TnvZHnu5zliIbmnpDnm7jkvLzvvIzlkIzmoLfljLrliIbkuobkuKrkvZPlhoXlkozkuKrkvZPpl7TmlYjlupTvvIzlubblj6/ku6XkvLDorqHml7bpl7TnvZHnu5zjgIHlkIzml7bnvZHnu5zlkozkuKrkvZPpl7TnvZHnu5zjgIIKCuKAg+KAg+WRveS7pOS4u+imgeaYr++8miptbEdWQVIqIHttb2RuZXRzfTpGaXQgR1ZBUiBtb2RlbHMgd2l0aCBtdWx0aWxldmVsIGRhdGEgRml0cyBhIGdyYXBoaWNhbCB2ZWN0b3IgYXV0b3JlZ3Jlc3NpdmUgbW9kZWwgdG8gZGF0YSBjb250YWluaW5nIG11bHRpcGxlIHRpbWUgcG9pbnRzIG1lYXN1cmVkIGZvciBtdWx0aXBsZSBpbmRpdmlkdWFscy4KCuKAg+KAg+e6teWQkee9kee7nOWIhuaekOS4u+imgemAmui/h+WbvuW9ouWQkemHj+iHquWbnuW9kuaooeWeiyh0aGUgZ3JhcGhpY2FsIHZlY3Rvci1hdXRvcmVncmVzc2lvbiBtb2RlbCwgR1ZBUinlrp7njrAoRXBza2FtcCBldCBhbC4sIDIwMTg7IFdpbGQgZXQgYWwuLCAyMDEwKeOAgjHpmLbmu57lkI4obGFnLTEpIEdWQVLmqKHlnovmmK/nlLHljZXkuLvkvZPml7bpl7Tluo/liJfnmoTpq5jmlq/lm77lvaLmqKHlnosodGhlIEdhdXNzaWFuIGdyYXBoaWNhbCBtb2RlbCwgR0dNKeaOqOW5v+iAjOadpeOAgkdHTeaooeWei+Wkp+WutumDveW+iOeGn+aCie+8jOWcqOaoquaWree9kee7nOWIhuaekOS4reiiq+eUqOadpeS8sOiuoemDqOWIhuebuOWFs++8jOW9ouaIkOaXoOWQkee9kee7nOaooeWei+OAguiAjOWcqChsYWctMSkgR1ZBUuaooeWei+S4re+8jOaXtumXtOS+nei1luWFs+ezu+mAmui/h+WvueWFiOWJjea1i+mHj+aDheWGteeahOWbnuW9kuadpeW7uuaooe+8jOi/meWvvOiHtOWbnuW9kuezu+aVsOefqemYteS5n+WPr+eUqOS6jue7mOWItuacieWQkee9kee7nOaooeWeiyhCcmluZ21hbm4gZXQgYWwuLCAyMDEzKe+8jOmAmuW4uOiiq+ensOS4uuaXtumXtOe9kee7nOOAguWJqeS9meeahOaWueW3ruWSjOWNj+aWueW3rijljbPmjqfliLbliY3kuIDmrKHmtYvph4/lnLrlkIjlkI7nmoTljY/mlrnlt67nu5PmnoQp5Y+v5Lul5bu65qih5Li65LiA5LiqR0dN5qih5Z6L77yM5Lmf56ew5Li65ZCM5pe2572R57uc44CC5b2T5aSa5Liq5Li75L2T55qE5pe26Ze05bqP5YiX5Y+v55So5pe277yM5Y+v5Lul5b2i5oiQ5YWz5LqO5Liq5L2T6Ze05pWI5bqUKOeos+WumuWdh+WAvOS5i+mXtOeahOWFs+ezuynnmoTnrKzkuInkuKpHR03mqKHlnovvvIzkuZ/np7DkuLrkuKrkvZPpl7TnvZHnu5zjgILlhbfkvZPnu5/orqHljp/nkIblpKflrrblj6/ku6Xlj4LogIMoRXBza2FtcCwgMjAyMCnjgIIKCuKAg+KAg+eugOWNlemAmui/h+S+i+mimOaVsOaNruadpei/m+ihjOa8lOekuuOAguaMieeFp+i/memHjOeahOmdouadv+mAu+i+ke+8jOS7heS7hWZpeGVk5ZKMYmV0d2VlbuaYr+acieeUqOeahO+8jOaXtuW6j+S4iueahGFy6L+H56iL5YW25a6e5rKh5pyJ5aSq5aSn5oSP5LmJ44CCCgpgYGB7ciBuZXQ2fQpybShsaXN0ID0gbHMoKSkgI+eXlei/uea4hemZpApsaWJyYXJ5KG1vZG5ldHMpCmhlYWQobWxndmFyRGF0KQpmaXQxIDwtIG1sR1ZBUihtbGd2YXJEYXQsICdNJyxpZHZhciA9ICJJRCIpICNFc3RpbWF0aW5nIGZpeGVkIG5ldHdvcmtzCihwMT1wbG90TmV0KGZpdDEsbW5ldCA9IFRSVUUsZWxhYnMgPSBUKSkKZml0MiA8LSBtbEdWQVIobWxndmFyRGF0LCAnTScsIGJtID0gVFJVRSkgIyBGaXQgdGhlIHNhbWUgbW9kZXJhdG9yIGluIHRoZSBiZXR3ZWVuLXN1YmplY3RzIG5ldHdvcmsKKHAyPXBsb3ROZXQoZml0MixtbmV0ID0gVFJVRSxlbGFicyA9IFQpKQpmaXQzPW1sR1ZBUihtbGd2YXJEYXQsICdNJywgc2VsZWN0RlVOID0gJ3ZhclNlbGVjdCcpCihwMz1wbG90TmV0KGZpdDMsbW5ldCA9IFRSVUUsZWxhYnMgPSBUKSkKCiPmnoHkuLrogJfml7bnmoTkuIDkupvorqHnrpfov4fnqIsKKHggPC0gbG1lclZBUihtbGd2YXJEYXQsICdNJywgdGVtcG9yYWwgPSAiZml4ZWQiLCBjb250ZW1wID0gIm9ydGhvZ29uYWwiKSkKZml0MSA8LSBsbWVyVkFSKG1sZ3ZhckRhdCwgdGVtcG9yYWwgPSAiZml4ZWQiLCBjb250ZW1wID0gIm9ydGhvZ29uYWwiKQpmaXQyIDwtIGxtZXJWQVIobWxndmFyRGF0LCB0ZW1wb3JhbCA9ICJvcnRob2dvbmFsIiwgY29udGVtcCA9ICJvcnRob2dvbmFsIikKCmNvbXBhcmVWQVIoZml0MSwgZml0MikKCmBgYAoK4oCD4oCD55uu5YmN77yM5bey5pyJ5LiA5Lqb56CU56m25L2/55So5LqG5Z+65LqO6Z2i5p2/5pWw5o2u55qE57q15ZCR572R57uc5YiG5p6Q77yM5L6L5aaC5pyJ56CU56m26ICD5a+f5LqG5pyJ6Zeu6aKY55qE572R57uc5L2/55So44CB5b+D55CG5Zuw5omw5ZKM6aWu6aOf5aSx6LCD55eH54q25LmL6Ze055qE5YWz57O7KExpbiBldCBhbC4sIDIwMjMp44CC5L2G6L+Z56eN5pa55rOV55u45q+U5LqO5qiq5pat572R57uc5YiG5p6Q77yM5Zyo6K+E5Lyw572R57uc5ZKM6IqC54K555qE5Lit5b+D5oCn44CB56iz5a6a5oCn44CB5Y+v6YeN5aSN5oCn562J5pa56Z2i5a2Y5Zyo5LiN6Laz77yM5pyJ5b6F56CU56m26ICF5Lus55qE6L+b5LiA5q2l5byA5Y+R44CCMjAyNOW5tOS6lOaciOS7veeahOaEj+inge+8mlvln7rkuo7pnaLmnb/mlbDmja7nmoTnurXlkJHnvZHnu5zliIbmnpAt5pe26Ze0572R57uc5YiG5p6QKFRlbXBvcmFsIE5ldHdvcmsgQW5hbHlzaXMp5YWl6Zeo5pWZ56iL77yIMu+8iV0oaHR0cHM6Ly9tcC53ZWl4aW4ucXEuY29tL3MvQmdkNnI2MTA3RGR5Q0VVYUw2ZFJnQSnjgIIKCiMgNSDmjqLntKLmgKflm77orrrliIbmnpAKCuKAg+KAg+agueaNruaOqOaWh++8mlvmjqLntKLmgKflm77orrrliIbmnpBdKGh0dHBzOi8vbXAud2VpeGluLnFxLmNvbS9zL1gyZTBnX2E0SEhJdE1xcXNraGVDV2cp77yb6L+Z6YeM5Y6f55CG6L+b6KGM5LqG6K6y6Kej77yM5L2G5piv5pWw5o2u5rKh5pyJ5o+Q5L6b77yM55u05o6l6YeH55SoYD9FR0FuZXRg55qE5L6L6aKY6Ieq5bim5pWw5o2u6L+b6KGM5aSE55CG5bCx6Laz5aSf5LqG44CCCgrigIPigIPmjqLntKLmgKflm77orrrliIbmnpAgKEV4cGxvcmF0b3J5IEdyYXBoIEFuYWx5c2lzKSDmmK/ov5HlubTmnaXlhbTotbfnmoTkuIDnp43nu7Tluqbmo4DmtYvmlrnms5XjgILov5nnp43mlrnms5XmnInliKvkuo7kuYvliY3nmoTmjqLntKLmgKflm6DlrZDliIbmnpAgKEV4cGxvcmF0b3J5IEZhY3RvciBBbmFseXNpcynvvIzlroPlsIblj5jph4/mnoTlu7rkuLrlpJrlhYPmraPmgIHliIbluIPnvZHnu5zvvIzlubblsIbmmL7mgKflj5jph4/op4bkuLrnlLHovrnnur/vvIhFZGdlc++8iei/nuaOpeeahOiKgueCue+8iE5vZGVz77yJ5omA5p6E5oiQ55qE572R57uc77yM6ICM5Zug5a2Q5qih5Z6L5Lit55qE5r2c5Zyo5Y+Y6YeP5YiZ5L2/6L+Z5Lqb6IqC54K555u45LqS6IGa6ZuG44CCCgrigIPigIPpgJrov4flsIbpq5jmlq/lm77mqKHlnovvvIhHYXVzc2lhbiBncmFwaGljYWwgbW9kZWzvvIxHR03vvInkuI7liqDmnYPnvZHnu5znmoTogZrnsbvnrpfms5Xnm7jnu5PlkIjvvIxFR0Eg5Y+v5Lul5a+55b+D55CG5p6E5b+15Lit5p2h55uu57u05bqm6L+b6KGM6K+E5Lyw44CC5qih5ouf56CU56m25pi+56S677yM5LiO5L2c5Li66K+E5Lyw57u05bqm4oCc6YeR5qCH5YeG4oCd55qE5Zug57Sg5YiG5p6Q5rOV55u45q+U77yMRUdBIOWcqOWHhuehruajgOa1i+W/g+eQhumHj+ihqOeahOato+ehrue7tOW6puaWuemdouihqOeOsOabtOS4uuWHuuiJsihHb2xpbm8gZXQgYWwuLCAyMDIwKeOAgkVHQSDku6Xlhbbku6XkuIvkvJjngrnogIzlpIflj5flhbPms6jvvJrvvIgx77yJ5Y+v6KeG5YyW6IO95Yqb77ya5Y+v5Lul6YCa6L+H5L2/55So5LiN5ZCM6aKc6Imy57yW56CB55qE572R57uc5Zu+55u06KeC5Zyw5Yik5pat5p2h55uu57u05bqm55qE5b2S5bGe77yb77yIMu+8ieiHquWKqOS8sOiuoe+8muaXoOmcgOiAg+iZkemHh+eUqOS9leenjeaXi+i9rOaWueazle+8m++8iDPvvInnqLPlrprmgKfmo4DpqozvvJrlj6/pgJrov4cgYm9vdHN0cmFwIOaWueazlei/m+ihjOe7tOW6pueos+WumuaAp+ajgOmqjOOAguWboOatpO+8jENvc2VtYW5z562J5Lq6KDIwMjIp5bCGRUdB5L2c5Li65Lyw6K6h6L+e57ut5pWw5o2u57u05bqm55qE6aaW6YCJ5pa55rOV44CCCgpgYGB7ciBuZXQ3fQpybShsaXN0ID0gbHMoKSkgI+eXlei/uea4hemZpApsaWJyYXJ5KEVHQW5ldCkgIyBFeHBsb3JhdG9yeSBHcmFwaCBBbmFseXNpcyDigJMgYSBGcmFtZXdvcmsgZm9yIEVzdGltYXRpbmcgdGhlTnVtYmVyIG9mIERpbWVuc2lvbnMgaW4gTXVsdGl2YXJpYXRlIERhdGEgdXNpbmcgTmV0d29yayBQc3ljaG9tZXRyaWNzCgojIEdldCBkYXRhCmRhdGEgPSBwc3ljaDo6YmZpWywxOjI1XQoKIyMgTm90IHJ1bjogIyBDb21wdXRlIExDVAojIyBGYWN0b3IgbW9kZWw76buY6K6kaXQ9MTAwCkxDVChkYXRhLHNlZWQ9MTIzKQoj57uT5p6c6KGo5piO77yM6ZqP5py65oq95Y+W55qE5a2Q5qC35pys5oC777yM5pyJ5aSa5bCR6YCC5ZCI572R57uc5YiG5p6QCgojQm9vdHN0cmFwIEV4cGxvcmF0b3J5IEdyYXBoIEFuYWx5c2lzCiMgTG9hZCBkYXRhCndtdCA9IHdtdDJbLDc6MjRdCgojIyBOb3QgcnVuOiAKIyBTdGFuZGFyZCBFR0EgcGFyYW1ldHJpYyBleGFtcGxlCmJvb3Qud210ID0gYm9vdEVHQSgKICBkYXRhID0gd210LCBpdGVyID0gNTAwLAogIHR5cGUgPSAicGFyYW1ldHJpYyIsIG5jb3JlcyA9IDIsc2VlZD0xMjMKKSAj6aG555uu55qE56iz5a6a5oCn5bqU6K+l5aSn5LqOMC42NQpwbG90KGJvb3Qud210JEVHQSkKCmJvb3Qud210JHN1bW1hcnkudGFibGUgI+W+l+WIsOeahOWboOWtkOS4reS9jeaVsOS4juWFtuS7lue7n+iuoeaMh+aghwpib290LndtdCRmcmVxdWVuY3kgICPlvpfliLDnmoTlm6DlrZDmlbDph4/kvLDorqHliIbluIMKZGltZW5zaW9uU3RhYmlsaXR5KGJvb3Qud210KSAj57u05pWw55qE56iz5a6a5oCn5bqU6K+l5aSn5LqOMC43NQoKbmV0LmxvYWRzKGJvb3Qud210JEVHQSkgI+i9veiNt+S4ujAuMTXooajnpLrpnZ7luLjlsI8KYGBgCgrigIPigIPnu5PlkIhpdGVtIHN0YWJpbGl0eeWSjG5ldHdvcmsgbG9hZGluZ+WvueWQhOS4qumhueebrui/m+ihjOajgOafpe+8jOW9k2l0bWUgc3RhYmlsaXR55bCP5LqOMC42Ne+8jG5ldHdvcmsgbG9hZGluZ+S5n+i+g+Wwj+aXtu+8jOWImeiAg+iZkeWIoOmZpOivpemhueebruOAguWAvOW+l+azqOaEj+eahOaYr++8jOmhueebrueahOWIoOmZpOS4juWQpumcgOimgeiAg+iZkeWkmuaWuemdoueahOWOn+WboO+8jOS+i+WmgueQhuiuuuWxgumdouS4iu+8jOivpemhueebruaYr+WQpuWPjeaYoOS6huaguOW/g+WPmOmHj++8m+Wunui3teWxgumdouS4iu+8jOivpemhueebruaYr+WQpuaYr+S4u+imgeWFs+azqOeahOWPmOmHj+OAguWboOatpO+8jOmhueebrueahOWIoOmZpOS4juWQpumcgOimgee7k+WQiOaWh+eMruWFt+S9k+WIhuaekOOAggoKIyA2IOe9kee7nOWIhuaekOS4reaOp+WItuWNj+WPmOmHjwoK4oCD4oCD5Li76KaB5qC55o2u5o6o5paH77yaW+WmguS9leWcqOe9kee7nOWIhuaekOS4reaOp+WItuWNj+WPmOmHj++8n10oaHR0cHM6Ly9tcC53ZWl4aW4ucXEuY29tL3MvdWp6WldwR29OUks2MEdDb0pMMnZPUSnlkozmjqjmlofkuIrnmoTkuKTnr4forrrmlofmnaXov5vooYzlrp7mk43lkoznkIbop6PjgILnm67liY3kuLvopoHmnInkuKTnp43mlrnlvI/mjqfliLbljY/lj5jph4/vvJrkuIDnp43nm7TmjqXmiormr4/kuKroioLngrnlm57lvZLmjonljY/lj5jph4/lkI7lj5bmrovlt67vvIzlj6bkuIDnp43lsIbljY/lj5jph4/kuZ/lvZPlgZroioLngrnnurPlhaXnvZHnu5zmqKHlnovjgIIKCuKAg+KAg+S4pOenjeaWueazleWQhOacieWIqeW8iu+8jOesrOS4gOenjeeahOmXrumimOWcqOS6juiKgueCueaYr+WfuuS6juaAu+agt+acrOeahOaui+W3ru+8jOWcqOWQjue7rWJvb3RzdHJhcOaXtuS8muW8leWFpeivr+W3ru+8iOWPpuWklu+8jOacieaXtuWAme+8jOS9v+eUqOi/meenjeaWueazleS4juS4jeaOp+WItuWNj+WPmOmHj+ebuOavlO+8jOWcqOi/m+ihjOe9kee7nOS4reW/g+aAp+S8sOiuoeaXtu+8jOeos+WumuaAp+WSjOWHhuehruaAp+S8muebuOWvueW3ruS4gOS6m++8ie+8m+esrOS6jOenjeeahOmXrumimOWcqOS6juWNj+WPmOmHj+eahOW8leWFpeS8mumAoOaIkOe9kee7nOeahOe7k+aehOWPmOWMluOAgumHh+eUqOeahOaXtuWAmeimgeivtOa4healmuWIqeW8iuS9leWcqOOAguWFtuWunuS4gOiIrOadpeivtO+8jOesrOS6jOenjeaWueazleWunuaWvei1t+adpeS8vOS5jueugOWNleOAguS7juWunumZhei/kOeUqOeahOinkuW6pu+8jOmHh+eUqOesrOS6jOenjeaWueazleabtOS4uuS+v+WIqeS4gOS6m+OAggoK4oCD4oCDKirnpLrkvovmlbDmja7mnaXoh6rkuo5uZXR3b3JrdG9vbHPkuK3nmoRkZXByZXNzaW9u5pWw5o2u6ZuG77yMKirov5nkuKrmqKHmi5/mlbDmja7pm4bljIXlkKsxMDAw5Liq5Lq65LitOeenjemHjeW6puaKkemDgeeXh+eXh+eKtu+8iFBIUS0577yJ55qE5Lil6YeN56iL5bqm6K+E57qn44CC55eH54q26K+E57qn5YGH6K6+5piv5ZyoMTAw54K55ruR5Yqo6YeP6KGo5LiK6Ieq5oiR5oql5ZGK55qE44CCCgpgYGB7ciBuZXQ4fQpybShsaXN0ID0gbHMoKSkgI+eXlei/uea4hemZpAojMy4x6L295YWl5YyF5LiO56Gu5a6a5Luj56CB6Lev5b6E77yI6L295YWl5Ye6546w6ZSZ6K+v55qE6K+d6ZyA6KaB5YWI5Y675a6J6KOF5YyF77yJLS0tLQpsaWJyYXJ5KG5ldHdvcmt0b29scykgIyBUb29scyBmb3IgSWRlbnRpZnlpbmcgSW1wb3J0YW50IE5vZGVzIGluIE5ldHdvcmtzCmxpYnJhcnkoYm9vdG5ldCkgIyBCb290c3RyYXAgTWV0aG9kcyBmb3IgVmFyaW91cyBOZXR3b3JrIEVzdGltYXRpb24gUm91dGluZXMKbGlicmFyeShtZ20pICMgRXN0aW1hdGluZyBUaW1lLVZhcnlpbmcgay1PcmRlciBNaXhlZCBHcmFwaGljYWwgTW9kZWxzCgojMy4yIOaVsOaNruWSjOe9kee7nOS8sOiuoeWHhuWkhy0tLS0tLQpkYXRhID0gbmV0d29ya3Rvb2xzOjpkZXByZXNzaW9uICPnlKhkZXByZXNzaW9u5pWw5o2u5L2c5Li65pys5pWZ56iL55qE56S65L6L5pWw5o2uO+aMh+aYjueptuern+WTquS4quWMhQoj55Sf5oiQ5Y2P5Y+Y6YeP5bm257uE5ZCI5oiQ5paw5pWw5o2u6ZuGCgpnZW5kZXIgPSBhcy5udW1lcmljKHNhbXBsZSh4ID0gYygxLCAyKSwgc2l6ZSA9IG5yb3coZGF0YSksIHJlcGxhY2UgPSBUUlVFKSkKIyDpmo/mnLrnlJ/miJAxMDAw5Liq5oCn5Yir5pWw5o2uCmFnZSA9IHNhbXBsZSh4ID0gMjA6MzAsIHNpemUgPSBucm93KGRhdGEpLCByZXBsYWNlID0gVFJVRSkgI+maj+acuueUn+aIkDEwMDDkuKrlubTpvoTmlbDmja4KdXNlZGF0YSA9IGRhdGEuZnJhbWUoZGF0YSwgYWdlLGdlbmRlcikgIyDlsIbnlJ/miJDnmoTmlbDmja7lkIjlubbmiJDkuIDkuKrmlbDmja7moYYKCiMgMy4zIOWNj+WPmOmHj+e9kee7nOS8sOiuoQojIzMuMy4xIOesrOS4gOenjeaWueazlQojIyPlm57lvZLmjonljY/lj5jph48KCmRlcHJlc3Npb25fbWF0PWFzLmRhdGEuZnJhbWUobWF0cml4KG5yb3c9MTAwMCxuY29sPTkpKSAj5YGa5Ye65LiA5Liq56m655qE5pWw5o2u5bqT5p2l5a2Y5YKo5q6L5beuCmNvbG5hbWVzKGRlcHJlc3Npb25fbWF0KT1jb2xuYW1lcyh1c2VkYXRhKVsxOjldICPnqbrmlbDmja7lupPlj5jph4/lkb3lkI0KI+i/meS4quWHveaVsOeahOaEj+S5ieaYr+Wwhuavj+S4gOS4quWPmOmHj+i/m+ihjOWbnuW9ku+8jOeEtuWQjuWwhuaui+W3ruWtmOWCqOWcqGRlcHJlc3Npb25fbWF05LitCmZvciAoaSBpbiAxOihuY29sKGRlcHJlc3Npb25fbWF0KSkpIHsgI+eVmeaEj+S4gOS4i+W+queOr+eahOaTjeS9nAogIGZvcm11bGEgPC0gcGFzdGUoY29sbmFtZXModXNlZGF0YSlbaV0sICd+YWdlK2dlbmRlcicpCiAgbG0xIDwtIGdsbShmb3JtdWxhID0gZm9ybXVsYSxmYW1pbHkgPSAiZ2F1c3NpYW4iLCBkYXRhID0gdXNlZGF0YSkgCiAgeV9yZXMgPC0gbG0xJHJlc2lkdWFscwogIGRlcHJlc3Npb25fbWF0WywgaV0gPC0geV9yZXMKfQoKaGVhZChkZXByZXNzaW9uX21hdCkgI+ajgOafpeW9kue7k+aui+W3rueahOaVsOaNrgoKbmV0d29yayA9IGFzLm1hdHJpeChkZXByZXNzaW9uX21hdCkKcD1uY29sKG5ldHdvcmspCmZpdF9vYmogPSBtZ20oZGF0YSA9IG5ldHdvcmssIHR5cGUgPSByZXAoJ2cnLCBwKSwgbGV2ZWwgPSByZXAoMSwgcCksIGxhbWJkYVNlbCA9ICdDVicsIHJ1bGVSZWcgPSAnT1InLCBwYmFyID0gVFJVRSkKcHJlZF9vYmogPSBwcmVkaWN0KG9iamVjdCA9IGZpdF9vYmosIGRhdGEgPSBuZXR3b3JrLCBlcnJvckNvbiA9ICdSMicpCnByZWRfb2JqJGVycm9yICPlj6/pooTmtYvmgKforqHnrpfnu5PmnpzvvIzlhbblrp7lsLHmmK/lvpfliLDlhajpg6jnmoRSMuiAjOW3sgoKI+S8sOiuoee9kee7nApOZXR3b3JrID0gZXN0aW1hdGVOZXR3b3JrKGRhdGE9bmV0d29yaywgZGVmYXVsdCA9ICJFQklDZ2xhc3NvIiwgdHVuaW5nID0gMC41LCBjb3JNZXRob2Q9ImNvciIsY29yQXJncz1saXN0KG1ldGhvZD0ic3BlYXJtYW4iLHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIikpCmdyb3Vwcz1saXN0KCJQSFEtOSBzeW1wdG9tcyI9YygxOjkpKQpjb2xuYW1lcyh1c2VkYXRhKT1jKCJEMSIsIkQyIiwiRDMiLCJENCIsIkQ1IiwiRDYiLCJENyIsIkQ4IiwiRDkiKQppdGVtcyA9bGlzdCgiQW5nZWRvbmlhIiwiU2FkbW9vZCIsIlNsZWVwIiwiRmF0aWd1ZSIsIkFwcGVpdGl0ZSIsIldvcnRobGVzcyIsIkNvbmNlbnRyYXRpb24iLCJNb250b3IiLCJEZWF0aCIpCgoj572R57uc5Zu+CnBsb3RfbmV0d29yayA8LSBwbG90KAogIE5ldHdvcmssCiAgbGF5b3V0ID0gInNwcmluZyIsCiAgZ3JvdXBzID0gZ3JvdXBzLAogIGxhYmVsLmNleCA9IDEsCiAgI+iwg+aVtOiKgueCueS4reagh+etvueahOWtl+S9k+Wkp+WwjwogIGxhYmVsLmNvbG9yID0gJ2JsYWNrJywKICAjIOiwg+aVtOiKgueCueS4reagh+etvueahOWtl+S9k+minOiJsgogIG5lZ0Rhc2hlZCA9IFQsCiAgI+i0n+ebuOWFs+eahOi+ueS4uuiZmue6vwogIGxlZ2VuZCA9IFQsCiAgbm9kZU5hbWVzID0gaXRlbXMsCiAgbGVnZW5kLmNleCA9IDAuNTUsCiAgI+WbvuS+i+eahOWtl+S9k+Wkp+WwjwogIGxlZ2VuZC5tb2RlID0gJ3N0eWxlMScsCiAgI+WbvuS+i+eahOmjjuagvO+8jOm7mOiupOaYrydzdHlsZTEnCiAgcGllID0gcHJlZF9vYmokZXJyb3JbLCAyXQogICPoioLngrnnmoTnjq/lvaLlm77mmL7npLrnmoTmmK9SMgopCgojMy4zLjIg56ys5LqM56eN5pa55rOVCmdyb3Vwcz1saXN0KCJQSFEtOSBzeW1wdG9tcyI9YygxOjkpLCJDb3ZhcmlhdGVzIj1jKDEwOjExKSkgI+WNj+WPmOmHj+S4gOe7hApjb2xuYW1lcyh1c2VkYXRhKSA9YygiRDEiLCJEMiIsIkQzIiwiRDQiLCJENSIsIkQ2IiwiRDciLCJEOCIsIkQ5IiwiQzEiLCJDMiIpCml0ZW1zID0gbGlzdCgiQW5nZWRvbmlhIiwiU2FkIG1vb2QiLCJTbGVlcCIsIkZhdGlndWUiLCJBcHBlaXRpdGUiLCJXb3J0aGxlc3MiLCJDb25jZW50cmF0aW9uIiwiTW9udG9yIiwiRGVhdGgiLCJhZ2UiLCJnZW5kZXIiKQpuZXR3b3JrID0gYXMubWF0cml4KHVzZWRhdGEpICPmlbTkuKrov5DooYznmoTnvZHnu5zmoYbmnrYxMeS4quWPmOmHj++8jOWMheWQq+S4pOS4quWNj+WPmOmHjwpwPW5jb2wobmV0d29yaykKCmZpdF9vYmogPSBtZ20oCiAgZGF0YSA9IG5ldHdvcmssCiAgdHlwZSA9IHJlcCgnZycsIHApLAogICPov5nph4zlsIbmgKfliKvkuZ/kvZzkuLrov57nu63lj5jph4/ov5vooYzlpITnkIYKICBsZXZlbCA9IHJlcCgxLCBwKSwKICBsYW1iZGFTZWwgPSAnQ1YnLAogIHJ1bGVSZWcgPSAnT1InLAogIHBiYXIgPSBUUlVFCikKcHJlZF9vYmogPSBwcmVkaWN0KG9iamVjdCA9IGZpdF9vYmosIGRhdGEgPSBuZXR3b3JrLCBlcnJvckNvbiA9ICdSMicpCnByZWRfb2JqJGVycm9yI+WPr+mihOa1i+aAp+iuoeeul+e7k+aenAoKI+S8sOiuoee9kee7nApOZXR3b3JrID0gZXN0aW1hdGVOZXR3b3JrKAogIGRhdGEgPSBuZXR3b3JrLAogIGRlZmF1bHQgPSAiRUJJQ2dsYXNzbyIsCiAgdHVuaW5nID0gMC41LAogIGNvck1ldGhvZCA9ICJjb3IiLAogIGNvckFyZ3MgPSBsaXN0KG1ldGhvZCA9ICJzcGVhcm1hbiIsIHVzZSA9ICJwYWlyd2lzZS5jb21wbGV0ZS5vYnMiKQopCgoj572R57uc5Zu+CnBsb3RfbmV0d29yayA9IHBsb3QoCiAgTmV0d29yaywKICBsYXlvdXQgPSAic3ByaW5nIiwKICBncm91cHMgPSBncm91cHMsCiAgbGFiZWwuY2V4ID0gMSwKICAj6LCD5pW06IqC54K55Lit5qCH562+55qE5a2X5L2T5aSn5bCPCiAgbGFiZWwuY29sb3IgPSAnYmxhY2snLAogICMg6LCD5pW06IqC54K55Lit5qCH562+55qE5a2X5L2T6aKc6ImyCiAgbmVnRGFzaGVkID0gVCwKICAj6LSf55u45YWz55qE6L655Li66Jma57q/CiAgbGVnZW5kID0gVCwKICBub2RlTmFtZXMgPSBpdGVtcywKICAj5Zu+5L6L5Lit55qE6IqC54K55qCH562+5ZCNCiAgbGVnZW5kLmNleCA9IDAuNTUsCiAgI+WbvuS+i+eahOWtl+S9k+Wkp+WwjwogIGxlZ2VuZC5tb2RlID0gJ3N0eWxlMScsCiAgI+WbvuS+i+eahOmjjuagvO+8jOm7mOiupOaYrydzdHlsZTEnCiAgcGllID0gcHJlZF9vYmokZXJyb3JbLCAyXQopCmBgYAoKIyA3IOi0neWPtuaWr+e9kee7nOS4juWboOaenOaOqOaWreS5i+exuwoK4oCD4oCD5L6L5a2Q5ZKM5ryU56S655qE56ys5LiA56+H5o6o5paH77yaW+S4gOaWh+aQnuaHgui0neWPtuaWr+e9kee7nOaooeWei+WPiuWFtlLlrp7njrBdKGh0dHBzOi8vbXAud2VpeGluLnFxLmNvbS9zL2JJNm9lYzZ6bmtONW5RZDBlUE0tR0Ep77yb6LSd5Y+25pav572R57uc77yIQmF5ZXNpYW4gTmV0d29yaywgQk7vvInmmK/kuIDnp43mpoLnjoflm77mqKHlnovvvIzlroPpgJrov4fmnInlkJHml6Dnjq/lm77vvIhEaXJlY3RlZCBBY3ljbGljIEdyYXBoLCBEQUfvvInooajnpLrkuIDnu4Tpmo/mnLrlj5jph4/lj4rlhbbnm7jkupLkuYvpl7TnmoRb5p2h5Lu25L6d6LWW5oCnXXsudW5kZXJsaW5lfeOAguWcqOWkhOeQhuS4jeehruWumuaAp+WSjOWkjeadguaAp+mXrumimOaXtu+8jOi0neWPtuaWr+e9kee7nOaPkOS+m+S6huS4gOenjeebtOinguS4lOW8uuWkp+eahOW3peWFt+OAggoKIyMgNy4xIOi0neWPtuaWr+e9kee7nOeahOaehOmAoAoK4oCD4oCD6LSd5Y+25pav572R57uc55Sx5Lik6YOo5YiG57uE5oiQ77ya572R57uc57uT5p6E5ZKM5p2h5Lu25qaC546H6KGo77yIQ29uZGl0aW9uYWwgUHJvYmFiaWxpdHkgVGFibGUsIENQVO+8ieOAggoKLSAgIOe9kee7nOe7k+aehO+8mue9kee7nOe7k+aehOaYr+aMh+eUqERBR+ihqOekuueahOWPmOmHj+mXtOeahOaLk+aJkeWFs+ezu+OAguWcqERBR+S4re+8jOiKgueCueS7o+ihqOmaj+acuuWPmOmHj++8jOacieWQkei+ue+8iOS7jkHmjIflkJFC77yJ6KGo56S65Y+Y6YePQeaYr+WPmOmHj0LnmoTniLboioLngrnvvIzljbNB5a+5QuacieebtOaOpeW9seWTjeOAguagueaNrkRBR++8jOaIkeS7rOWPr+S7peW+l+WHuuWPmOmHj+mXtOeahOadoeS7tueLrOeri+aAp++8jOWNs+WcqOe7meWumueItuiKgueCueeahOaDheWGteS4i++8jOS4gOS4quiKgueCueeahOadoeS7tuamgueOh+WIhuW4g+S7heS+nei1luS6juWFtueItuiKgueCueOAggoKLSAgIOadoeS7tuamgueOh+ihqO+8iENQVO+8ie+8muWvueS6jue9kee7nOS4reeahOavj+S4quiKgueCue+8jOaIkeS7rOmcgOimgeWumuS5ieS4gOS4qkNQVO+8jOWug+aPj+i/sOS6huivpeiKgueCueWcqOWFtueItuiKgueCueWPlueJueWumuWAvOaXtueahOamgueOh+WIhuW4g+OAgkNQVOaYr+WxgOmDqOeahO+8jOWboOS4uuWug+WPquS+nei1luS6jueItuiKgueCueeahOeKtuaAgeOAggoKIyMgNy4yIOi0neWPtuaWr+e9kee7nOaooeWei+eahOWtpuS5oOWIhuS4uuS4pOmDqOWIhgoKLSAgICoq57uT5p6E5a2m5Lmg77yIU3RydWN0dXJlIExlYXJuaW5n77yJ77yaKiog57uT5p6E5a2m5Lmg5piv5oyH5LuO5pWw5o2u5Lit5a2m5Lmg5Y+Y6YeP5LmL6Ze06L+e5o6l55qE5ouT5omR57uT5p6E44CC6L+Z5Liq6L+H56iL6YCa5bi45raJ5Y+K5Lul5LiL5q2l6aqk77yaCgogICAgLSAgICoq5Y+Y6YeP6YCJ5oup77yaKirpgInmi6npnIDopoHlu7rmqKHnmoTlj5jph4/pm4blkIjjgIIKCiAgICAtICAgKirmnaHku7bni6znq4vmgKfmo4DpqozvvJoqKuWIqeeUqOadoeS7tueLrOeri+aAp+WOn+WImeadpeehruWumuWTquS6m+WPmOmHj+S5i+mXtOmcgOimgeW7uueri+i/nuaOpeOAguadoeS7tueLrOeri+aAp+aYr+aMh+WcqOe7meWumuafkOS6m+WPmOmHj+eahOWAvOeahOaDheWGteS4i++8jOWFtuS7luWPmOmHj+eahOWAvOaYr+ebuOS6kueLrOeri+eahOOAggoKICAgIC0gICAqKuivhOWIhuWSjOaQnOe0ou+8mioq5L2/55So6K+E5YiG5Ye95pWw77yI5aaC6LSd5Y+25pav5L+h5oGv5YeG5YiZQklD44CB6Zi/5Y2h5LyK5YWL5L+h5oGv5YeG5YiZQUlD562J77yJ5p2l6K+E5Lyw5LiN5ZCM57uT5p6E55qE5aW95Z2P77yM5bm257uT5ZCI5pCc57Si566X5rOV77yI5aaC6LSq5amq562J5Lu35pCc57Si44CB5qih5ouf6YCA54Gr562J77yJ5p2l5om+5Yiw5pyA5LyY55qE57uT5p6E44CCCgotICAg5Y+C5pWw5a2m5Lmg77yIUGFyYW1ldGVyIExlYXJuaW5n77yJ77yaIOWPguaVsOWtpuS5oOaYr+aMh+WcqOe7meWumue7k+aehOeahOaDheWGteS4i++8jOS8sOiuoeadoeS7tuamgueOh+ihqO+8iENQVHPvvInkuK3nmoTlj4LmlbDjgILov5nkuKrov4fnqIvpgJrluLjljIXmi6zvvJoKCiAgICAtICAg5p2h5Lu25qaC546H5YiG5biD55qE56Gu5a6a77ya5a+55LqO5q+P5Liq6IqC54K577yM56Gu5a6a5YW25Zyo54i26IqC54K55Y+W5LiN5ZCM5YC855qE5oOF5Ya15LiL55qE5p2h5Lu25qaC546H5YiG5biD44CCCgogICAgLSAgIOWPguaVsOS8sOiuoe+8muS9v+eUqOacgOWkp+S8vOeEtuS8sOiuoe+8iE1MRe+8ieOAgei0neWPtuaWr+S8sOiuoeetieaWueazle+8jOagueaNruaVsOaNruadpeS8sOiuoei/meS6m+adoeS7tuamgueOh+OAgui0neWPtuaWr+e9kee7nOeahOaehOmAoOWSjOWPguaVsOWtpuS5oOaYr+S4gOS4quebuOS6kuWFs+iBlOeahOi/h+eoi+OAggoK57uT5p6E5a2m5Lmg5o+Q5L6b5LqG5Y+Y6YeP5LmL6Ze05YWz57O755qE5qGG5p6277yM6ICM5Y+C5pWw5a2m5Lmg5YiZ5aGr5YWF5LqG6L+Z5Liq5qGG5p625Lit55qE5YW35L2T5YaF5a6544CC6YCa6L+H6L+Z5Lik5Liq5q2l6aqk77yM5oiR5Lus5Y+v5Lul5b6X5Yiw5LiA5Liq6IO95aSf5a+55pWw5o2u6L+b6KGM5pyJ5pWI5bu65qih5ZKM5o6o55CG55qE6LSd5Y+25pav572R57uc44CCCgrigIPigIPku4vnu43lm5vnsbvkuLvopoHnmoTnvZHnu5znu5PmnoTlrabkuaDmlrnms5XvvJrln7rkuo7nuqbmnZ/jgIHln7rkuo7liIbmlbDjgIHphY3lr7nlkozmt7flkIjmlrnms5XvvIzku6Xlj4rku5bku6znmoTkvJjnvLrngrnlkozmr5TovoPnvZHnu5znu5PmnoTlrabkuaDmlrnms5XnmoTkuIDkupvln7rmnKzljp/liJnjgIIKCuKAg+KAgypibmxlYXJuKuaYr1LkuK3kuIDkuKrlvLrlpKfnmoTljIXvvIznlKjkuo7lrabkuaDjgIHmjqjnkIbjgIHmqKHmi5/lkozliIbmnpDotJ3lj7bmlq/nvZHnu5zjgILlroPmj5DkvpvkuobkuIDns7vliJflt6XlhbfmnaXlpITnkIbotJ3lj7bmlq/nvZHnu5znmoTkuI3lkIzmlrnpnaLvvIzljIXmi6znvZHnu5znu5PmnoTnmoTlrabkuaDjgIHlj4LmlbDnmoTkvLDorqHjgIHmnaHku7bmpoLnjofnmoTmn6Xor6LjgIHmlbDmja7pm4bnmoTmqKHmi5/vvIzku6Xlj4rlpJrnp43nvZHnu5znmoTlm77lvaLooajnpLrmlrnms5XjgILku6XkuIvmmK/lpoLkvZXkvb/nlKhibmxlYXJu5YyF5p6E5bu66LSd5Y+25pav572R57uc55qE6K+m57uG5LuL57uN44CCIOacrOasoeS9v+eUqOeahOaVsOaNrumbhuaYr++8mkJyZWFzdENhbmNlcuaVsOaNrumbhuaYr+iRl+WQjeeahOacuuWZqOWtpuS5oOWSjOaVsOaNruaMluaOmOmihuWfn+eahOagh+WHhuaVsOaNrumbhuS5i+S4gO+8jOmAmuW4uOeUqOS6juWIhuexu+WSjOmihOa1i+S7u+WKoeOAgui/meS4quaVsOaNrumbhuWMheWQq+S6huadpeiHquS5s+iFuueZjOaCo+iAheeahOWQhOenjeeJueW+ge+8jOaXqOWcqOmAmui/h+i/meS6m+eJueW+gemihOa1i+iCv+eYpOaYr+iJr+aAp+i/mOaYr+aBtuaAp+OAggoKYGBge3IgbmV0OX0Kcm0obGlzdCA9IGxzKCkpICPnl5Xov7nmuIXpmaQKIyDliqDovb1ibmxlYXJu5YyFCmxpYnJhcnkoYm5sZWFybikgIyBCYXllc2lhbiBOZXR3b3JrIFN0cnVjdHVyZSBMZWFybmluZywgUGFyYW1ldGVyIExlYXJuaW5nIGFuZCBJbmZlcmVuY2UKIyDlr7zlhaVCcmVhc3RDYW5jZXLmlbDmja7pm4YKbGlicmFyeShtbGJlbmNoKSAjIE1hY2hpbmUgTGVhcm5pbmcgQmVuY2htYXJrIFByb2JsZW1zCgpkYXRhKEJyZWFzdENhbmNlcikKIyDmn6XnnIvlj5jph4/nsbvlnosKc3RyKEJyZWFzdENhbmNlcikKIyDmn6XnnIvmkZjopoHnu5/orqHkv6Hmga8Kc2tpbShCcmVhc3RDYW5jZXIpCgojIOWwhuaVsOaNrumbhui9rOaNouS4uuemu+aVo+WPmOmHjwojIOWcqOaehOW7uui0neWPtuaWr+e9kee7nOaooeWei+S5i+WJje+8jOaIkeS7rOmcgOimgeWwhui/nue7reWPmOmHj+i9rOaNouS4uuemu+aVo+WPmOmHj+OAguWPr+S7peS9v+eUqGRpc2NyZXRpemUoKeWHveaVsOWwhui/nue7reWPmOmHj+i9rOaNouS4uuemu+aVo+WPmOmHj+OAguS7peS4i+S7o+eggeWwhuaVsOaNrumbhuS4reeahOi/nue7reWPmOmHj+i9rOaNouS4uuemu+aVo+WPmOmHj++8mgojIGxpYnJhcnkoYm5sZWFybikKZGF0YS5iYyA8LSBkaXNjcmV0aXplKEJyZWFzdENhbmNlclssMjpuY29sKEJyZWFzdENhbmNlcildLCBtZXRob2QgPSAiaW50ZXJ2YWwiLCBicmVha3MgPSAiZnJlcXVlbmN5IikKCiMg5pWw5o2u6aKE5aSE55CGIyDkvb/nlKjmlbDmja7pm4YKZGF0YS5iYyA8LSBCcmVhc3RDYW5jZXJbLDI6bmNvbChCcmVhc3RDYW5jZXIpXSMg5L2/55SoVklNOjphZ2dyKCnmn6XnnIvlh73mlbDnmoTnvLrlpLHlgLwKbGlicmFyeShWSU0pICMgVmlzdWFsaXphdGlvbiBhbmQgSW1wdXRhdGlvbiBvZiBNaXNzaW5nIFZhbHVlcwphZ2dyKGRhdGEuYmMpICPnvLrlpLHlgLznmoTmg4XlhrXnmoTlj6/op4bljJYKIyDkvb/nlKjpmo/mnLrmo67mnpfloavooaXnvLrlpLHlgLwKbGlicmFyeShtaXNzRm9yZXN0KSAjIE5vbnBhcmFtZXRyaWMgTWlzc2luZyBWYWx1ZSBJbXB1dGF0aW9uIHVzaW5nIFJhbmRvbSBGb3Jlc3QKZGF0YS5iY19uZXcgPC0gbWlzc0ZvcmVzdChkYXRhLmJjLG50cmVlID0gMTAwKQpkYXRhLmJjX25ldzwtIGRhdGEuYmNfbmV3JHhpbXAKCgojIOKRoCDkvb/nlKjluIzlsJQt5YWL6I6x5aeG566X5rOV5a2m5Lmg572R57uc57uT5p6E77yaCmJuLnN0cnVjdHVyZSA8LSBoYyhkYXRhLmJjX25ldywgc2NvcmUgPSAiYmljIikKcGxvdChibi5zdHJ1Y3R1cmUpICMg57uY5Yi25a2m5Lmg5Yiw55qE57uT5p6ECgojIOKRoSDkvb/nlKjln7rkuo7nuqbmnZ/nmoRQQ+eul+azle+8mgpibi5zdHJ1Y3R1cmUgPC0gcGMuc3RhYmxlKGRhdGEuYmNfbmV3LHRlc3Q9Im1pIikKcGxvdChibi5zdHJ1Y3R1cmUpICMg57uY5Yi25a2m5Lmg5Yiw55qE57uT5p6ECgojIDEuIOWfuuS6juWIhuaVsOeahOaWueazlSMg6LSd5Y+25pav572R57uc57uT5p6E55qE56aB5b+M5pCc57Si77yIVGFidSBTZWFyY2jvvIkKYm4udGFidSA8LSB0YWJ1KGRhdGEuYmNfbmV3KQpwbG90KGJuLnRhYnUpICMg57uY5Yi25a2m5Lmg5Yiw55qE57uT5p6ECgojIDIuIOWfuuS6jue6puadn+eahOaWueazlSMgR3Jvdy1TaHJpbmvnrpfms5XvvIhHU++8iQpibi5ncyA8LSBncyhkYXRhLmJjX25ldykKcGxvdChibi5ncykgIyDnu5jliLblrabkuaDliLDnmoTnu5PmnoQKCiMgMy4g6YWN5a+55pa55rOVIyDmnIDlpKfmnYPph43nlJ/miJDmoJHnrpfms5XvvIhDaG93LUxpde+8iQpibi5jaG93bGl1IDwtIGNob3cubGl1KGRhdGEuYmNfbmV3KQpwbG90KGJuLmNob3dsaXUpICMg57uY5Yi25a2m5Lmg5Yiw55qE57uT5p6ECgojNC4g5re35ZCI5pa55rOVI01heC1NaW4gSGlsbC1DbGltYmluZ+eul+azle+8iE1NSEPvvIkKYm4ubW1oYyA8LSBtbWhjKGRhdGEuYmNfbmV3KQpwbG90KGJuLm1taGMgKSAjIOe7mOWItuWtpuS5oOWIsOeahOe7k+aehAoKIyDlj4LmlbDlrabkuaAjIOe7k+aehOWtpuS5oOWujOaIkOWQju+8jOS4i+S4gOatpeaYr+WPguaVsOWtpuS5oOOAguWPguaVsOWtpuS5oOaYr+aMh+WtpuS5oOe9kee7nOS4reavj+S4quWPmOmHj+eahOadoeS7tuamgueOh+WIhuW4g++8iOWvueS6juemu+aVo+WPmOmHj++8ieaIluadoeS7tuamgueOh+WvhuW6pu+8iOWvueS6jui/nue7reWPmOmHj++8ieOAggpibi5wYXJhbWV0ZXJzIDwtIGJuLmZpdChibi5zdHJ1Y3R1cmUsIGRhdGEuYmNfbmV3KSAj57uT5p6E6YCJ5oup5Z+65LqO57qm5p2fCmJuLnBhcmFtZXRlcnMKCiMg57uY5Yi2572R57ucCiMgZ3JhcGh2aXoucGxvdChibi5zdHJ1Y3R1cmUpICPnu5PmnoTpgInmi6nln7rkuo7nuqbmnZ8KCiMg6K6h566X5Zyo57uZ5a6a5p+Q5Lqb6K+B5o2u5LiL6IK/55ik5piv6Imv5oCn55qE5qaC546HIyDlgYforr7miJHku6znn6XpgZMgQmFyZS5udWNsZWkgPSAiMSIg5ZKMIE1hcmcuYWRoZXNpb24gPSAiMSIKcHJvYl9iZW5pZ25fZ2l2ZW5fZXZpZGVuY2UgPC0gY3BxdWVyeShmaXR0ZWQgPSBibi5wYXJhbWV0ZXJzLCBldmVudCA9IChDbGFzcyA9PSAiYmVuaWduIiksZXZpZGVuY2UgPSAoIE1hcmcuYWRoZXNpb24gPT0gIjEiKSkKCnByb2JfYmVuaWduX2dpdmVuX2V2aWRlbmNlCgojIOeUn+aIkOe7meWumuivgeaNruS4i0NsYXNz5Y+Y6YeP55qE5p2h5Lu25qaC546H5YiG5biDCmRpc3RyaWJ1dGlvbl9jbGFzc19naXZlbl9ldmlkZW5jZSA8LSBjcGRpc3QoCiAgZml0dGVkID0gYm4ucGFyYW1ldGVycywKICBub2RlcyA9ICJDbGFzcyIsCiAgZXZpZGVuY2UgPSAoQmFyZS5udWNsZWkgPT0gIjEiKQopCnRhYnlsKGRpc3RyaWJ1dGlvbl9jbGFzc19naXZlbl9ldmlkZW5jZSRDbGFzcykKIyDmr5TovoPmqKHlnoss6L+Z5bCG6L6T5Ye65LiA5Liq5YiX6KGo77yM5YW25Lit5YyF5ous5Lik5Liq572R57uc5YWx5pyJ55qE6L6544CB5Y+q5Zyo56ys5LiA5Liq572R57uc5Lit5Ye6546w55qE6L6544CB5Lul5Y+K5Y+q5Zyo56ys5LqM5Liq572R57uc5Lit5Ye6546w55qE6L6544CCCmNvbXBhcmUoYm4udGFidSwgYm4uZ3MpCgojIOWvuVRhYnXmkJzntKLnrpfms5Xov5vooYzlvJXlr7znqLPlrprmgKfliIbmnpAKYnMudGFidSA8LSBib290LnN0cmVuZ3RoKGRhdGEgPSBkYXRhLmJjX25ldywgYWxnb3JpdGhtID0gInRhYnUiLCBSID0gMTAwKQpicy50YWJ1CgojUmdyYXBodml65rKh5pyJ5a6J6KOF77yM5peg5rOV5Y+v6KeG5YyWCgojIOadoeS7tueLrOeri+aAp+a1i+ivlSMg5p2h5Lu254us56uL5oCn5rWL6K+V5piv6K+E5Lyw5Y+Y6YeP6Ze05piv5ZCm54us56uL55qE5LiA56eN5pa55rOV77yM5a+55LqO5Z+65LqO57qm5p2f55qE572R57uc5a2m5Lmg5pa55rOV5bCk5YW26YeN6KaB44CCYm5sZWFybuaPkOS+m+S6hmNpLnRlc3Tlh73mlbDmnaXmiafooYzmnaHku7bni6znq4vmgKfmtYvor5XjgILku6XkuIvmmK/lpoLkvZXlnKjlj5jph4/kuYvpl7Tov5vooYzmnaHku7bni6znq4vmgKfmtYvor5XnmoTnpLrkvovvvJoKY2kudGVzdCgiTWFyZy5hZGhlc2lvbiIsICJCYXJlLm51Y2xlaSIsIGRhdGEgPSBkYXRhLmJjX25ldykKYGBgCgojIyA3LjMg5qiq5pat572R57uc5Lit55qE5Zug5p6c5o6o5patCgrigIPigIPln7rkuo7mjqjmlofvvJpb6LSd5Y+25pav572R57uc5YiG5p6Q5YWl6ZeoLeaoquaWree9kee7nOS4reeahOWboOaenOaOqOaWrV0oaHR0cHM6Ly9tcC53ZWl4aW4ucXEuY29tL3MvWkREN2QySk5mVkwxR1BXUm5DVGs2QSnkuIvovb3kuobmlbDmja7jgILku6XmraTkuLrkvovlrZDjgIJkb2npobrmiYvmiorlj4LogIPmlofnjK7mt7vliqDjgIIKCmBgYHtyIG5ldDEwfQpybShsaXN0ID0gbHMoKSkgI+eXlei/uea4hemZpAojIEEgdHV0b3JpYWwgb24gQmF5ZXNpYW4gbmV0d29ya3MgZm9yIHBzeWNob3BhdGhvbG9neSByZXNlYXJjaGVycwojIEJyaWdhbnRpIEcsIFNjdXRhcmkgTSwgTWNOYWxseSBSSgoKbGlicmFyeShzdGF0cykKbGlicmFyeShxZ3JhcGgpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoYm9vdG5ldCkKbGlicmFyeShkcGx5cikKbGlicmFyeShjb3JwY29yKQpsaWJyYXJ5KGJubGVhcm4pCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkgKGdncGxvdDIpCgpkYXRhIDwtIHJlYWRfZGVsaW0oJy9Vc2Vycy9tZW5ndGFvZ2FvL0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLeWFseS6q+eahOW6ky1vbmVkcml2ZS9vdXRzeW4vc3RhdGlvbi9BIHR1dG9yaWFsIG9uIEJheWVzaWFuIE5ldHdvcmtzL2RhdGEuY3N2JywgIjsiLCBlc2NhcGVfZG91YmxlID0gRkFMU0UsIHRyaW1fd3MgPSBUUlVFKQoKbmFtZXMgPC0gYygiRGVwTW9vZCIsIAogICAgICAgICAgICJTbGVlcCIsIAogICAgICAgICAgICJXZWlnaHQiLCAKICAgICAgICAgICAiRmF0aWd1ZSIsIAogICAgICAgICAgICJJcnJpdGFibGUiLCAKICAgICAgICAgICAiU3VpY2lkZUlkIiwgCiAgICAgICAgICAgIkFuaGVkb25pYSIpCgpsb25nbmFtZXMgPC0gYygiRGVwcmVzc2l2ZSBNb29kIiwgCiAgICAgICAgICAgICAgICJTbGVlcCBQcm9ibGVtcyIsIAogICAgICAgICAgICAgICAiV2VpZ2h0IiwgCiAgICAgICAgICAgICAgICJGYXRpZ3VlIiwgCiAgICAgICAgICAgICAgICJJcnJpdGFibGUiLCAKICAgICAgICAgICAgICAgIlN1aWNpZGFsIElkZWF0aW9uIiwgCiAgICAgICAgICAgICAgICJBbmhlZG9uaWEiKQoKZGF0YSA8LSBhcy5kYXRhLmZyYW1lKG1hdHJpeChhcy5udW1lcmljKGFzLm1hdHJpeChkYXRhKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5jb2w9bmNvbChkYXRhKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnlyb3c9VFJVRSkpICAjc2V0IGRhdGEgYXMgbnVtZXJpY3MKIyBQQyBhbGdvcml0aG0KCkJOcGM8LXBjLnN0YWJsZShkYXRhKQpxZ3JhcGgoQk5wYywgbGFiZWxzPW5hbWVzLCAKICAgICAgIG5vZGVOYW1lcz1sb25nbmFtZXMsIAogICAgICAgbGVnZW5kLmNleD0uNSwgCiAgICAgICB2c2l6ZT02LCAKICAgICAgIGxheW91dD0iY2lyY2xlIikKCiMgQm9vdCBzdGFiaWxpdHkgZm9yIHRoZSBEQUcKIyBTdHJlbmd0aDogY29ubmVjdGlvbiBzdHJlbmd0aCwgZS5nLiAwLjg1ID4gCiMgICAgICAgICAgICAgIGNvbm5lY3Rpb24gYXBwZWFycyBpbiA4NiUgb2YgdGhlIGZpdHRlZCBuZXR3b3Jrcy4KIyBEaXJlY3Rpb246IHByb2JhYmlsaXR5IG9mIHRoZSBkaXJlY3Rpb24KIyAgICAgZS5nLiAwLjU3IG1lYW5zIHRoYXQgaW4gNTclIG9mIHRoZSBmaXR0ZWQgbmV0d29ya3MgdGhlIGNvbm5lY3Rpb24gZ29lcyBpbiAKIyAgICAgICAgICAgICAgICB0aGUgZGlyZWN0aW9uIGRlcGljdGVkIGluIHRoZSBncmFwaC4KCkJTVCA8LSBib290LnN0cmVuZ3RoKGRhdGEsIAogICAgICAgICAgICAgICAgICAgICBSID0gMTAwMCwgCiAgICAgICAgICAgICAgICAgICAgIGFsZ29yaXRobSA9ICJwYy5zdGFibGUiKSAKaGVhZChCU1QpCnFncmFwaChCU1QpICMgdmlzdWFsaXplIG91dHB1dCB3aXRoIHFncmFwaApCU1RbQlNUJHN0cmVuZ3RoID4gMC44NSAmIEJTVCRkaXJlY3Rpb24gPiAwLjUsIF0KCmF2Z25ldDEgPC0gYXZlcmFnZWQubmV0d29yayhCU1QsIHRocmVzaG9sZCA9IDAuODUpCmFzdHIxIDwtIGFyYy5zdHJlbmd0aChhdmduZXQxLCBkYXRhLCAiYmljLWciKSAgIyBjb21wdXRlIGVkZ2Ugc3RyZW5ndGhzCnFncmFwaCgKICBhc3RyMSwKICBsYWJlbHMgPSBuYW1lcywKICBub2RlTmFtZXMgPSBsb25nbmFtZXMsCiAgbGVnZW5kLmNleCA9IC41LAogIHZzaXplID0gNiwKICBsYXlvdXQgPSAiY2lyY2xlIgopCgoj5YWs5LyX5Y+35LiK55qE5ryU56S65LiN5a6M5pW0CgojIEhpbGwgQ2xpbWJpbmcgYWxnb3JpdGhtCgojIEJvb3Qgc3RhYmlsaXR5IGZvciB0aGUgREFHCiMgU3RyZW5ndGg6IGNvbm5lY3Rpb24gc3RyZW5ndGgsIGUuZy4gMC44NSA+IAojICAgICAgICAgICAgICBjb25uZWN0aW9uIGFwcGVhcnMgaW4gODYlIG9mIHRoZSBmaXR0ZWQgbmV0d29ya3MuCiMgRGlyZWN0aW9uOiBwcm9iYWJpbGl0eSBvZiB0aGUgZGlyZWN0aW9uCiMgICAgIGUuZy4gMC41NyBtZWFucyB0aGF0IGluIDU3JSBvZiB0aGUgZml0dGVkIG5ldHdvcmtzIHRoZSBjb25uZWN0aW9uIGdvZXMgaW4gCiMgICAgICAgICAgICAgICAgdGhlIGRpcmVjdGlvbiBkZXBpY3RlZCBpbiB0aGUgZ3JhcGguCgpCU1QgPC0gYm9vdC5zdHJlbmd0aChkYXRhLCBSID0gMTAwMCwgYWxnb3JpdGhtID0gImhjIiwgZGVidWcgPSBUUlVFKQpoZWFkKEJTVCkKQlNUW0JTVCRzdHJlbmd0aCA+IDAuODUgJiBCU1QkZGlyZWN0aW9uID4gMC41LCBdCnFncmFwaChCU1QpCgphdmduZXQxIDwtIGF2ZXJhZ2VkLm5ldHdvcmsoQlNULCB0aHJlc2hvbGQgPSAwLjg1KQphdmduZXQxCgpibmxlYXJuOjpzY29yZShhdmduZXQxLCBkYXRhID0gZGF0YSkKCmFzdHIxIDwtIGFyYy5zdHJlbmd0aChhdmduZXQxLCBkYXRhLCAiYmljLWciKSAgICMjIGNvbXB1dGUgZWRnZSBzdHJlbmd0aHMKCnFncmFwaChhc3RyMSwgCiAgICAgICBsYWJlbHM9bmFtZXMsIAogICAgICAgbm9kZU5hbWVzPWxvbmduYW1lcywgCiAgICAgICBsZWdlbmQuY2V4PS41LCAKICAgICAgIHZzaXplPTYsIAogICAgICAgbGF5b3V0PSJjaXJjbGUiKQoKCiMgRXF1aXZhbGVuY2UgY2xhc3NlcwoKQk5wYzwtcGMuc3RhYmxlKGRhdGEpCkJOY3AgPC0gY3BkYWcoQk5wYykKcWdyYXBoKAogIEJOY3AsCiAgbGFiZWxzID0gbmFtZXMsCiAgbm9kZU5hbWVzID0gbG9uZ25hbWVzLAogIGxlZ2VuZC5jZXggPSAuNSwKICB2c2l6ZSA9IDYsCiAgbGF5b3V0ID0gImNpcmNsZSIKKQoKdnN0cnVjdHMoQk5jcCkKCkJTVCA8LSBib290LnN0cmVuZ3RoKAogIGRhdGEsCiAgUiA9IDEwMDAsCiAgYWxnb3JpdGhtID0gInBjLnN0YWJsZSIsCiAgZGVidWcgPSBUUlVFLAogIGNwZGFnID0gVFJVRQopCgoKaGVhZChCU1QpCkJTVFtCU1Qkc3RyZW5ndGggPiAwLjg1ICYgQlNUJGRpcmVjdGlvbiA+IDAuNSwgXQpxZ3JhcGgoQlNUKQoKYXZnbmV0MSA8LSBhdmVyYWdlZC5uZXR3b3JrKEJTVCwgdGhyZXNob2xkID0gMC44NSkKYXZnbmV0MQoKYm5sZWFybjo6c2NvcmUoYXZnbmV0MSwgZGF0YSA9IGRhdGEpCgphc3RyMSA8LSBhcmMuc3RyZW5ndGgoYXZnbmV0MSwgZGF0YSwgImJpYy1nIikgICAjIyBjb21wdXRlIGVkZ2Ugc3RyZW5ndGhzCgpxZ3JhcGgoCiAgYXN0cjEsCiAgbGFiZWxzID0gbmFtZXMsCiAgbm9kZU5hbWVzID0gbG9uZ25hbWVzLAogIGxlZ2VuZC5jZXggPSAuNSwKICB2c2l6ZSA9IDYsCiAgbGF5b3V0ID0gImNpcmNsZSIKKQoKIyBHcm93IHNocmluawpCTmdzIDwtIGdzKGRhdGEpCnFncmFwaCgKICBCTmdzLAogIGxhYmVscyA9IG5hbWVzLAogIG5vZGVOYW1lcyA9IGxvbmduYW1lcywKICBsZWdlbmQuY2V4ID0gLjUsCiAgdnNpemUgPSA2LAogIGxheW91dCA9ICJjaXJjbGUiCikKCkJTVCA8LSBib290LnN0cmVuZ3RoKGRhdGEsIFIgPSAxMDAwLCAKICAgICAgICAgICAgICAgICAgICAgYWxnb3JpdGhtID0gImdzIiwgCiAgICAgICAgICAgICAgICAgICAgIGRlYnVnID0gVFJVRSkgIApoZWFkKEJTVCkKQlNUW0JTVCRzdHJlbmd0aCA+IDAuODUgJiBCU1QkZGlyZWN0aW9uID4gMC41LCBdCnFncmFwaChCU1QpCgphdmduZXQxIDwtIGF2ZXJhZ2VkLm5ldHdvcmsoQlNULCB0aHJlc2hvbGQgPSAwLjg1KQphdmduZXQxCgpibmxlYXJuOjpzY29yZShhdmduZXQxLCBkYXRhID0gZGF0YSkKCmFzdHIxIDwtIGFyYy5zdHJlbmd0aChhdmduZXQxLCBkYXRhLCAiYmljLWciKSAgICMjIGNvbXB1dGUgZWRnZSBzdHJlbmd0aHMKCnFncmFwaCgKICBhc3RyMSwKICBsYWJlbHMgPSBuYW1lcywKICBub2RlTmFtZXMgPSBsb25nbmFtZXMsCiAgbGVnZW5kLmNleCA9IC41LAogIHZzaXplID0gNiwKICBsYXlvdXQgPSAiY2lyY2xlIgopCgojIFJlc3RyaWN0ZWQgTWF4aW1pemF0aW9uIGh5YnJpZCBhbGdvcml0aG0KCkJOcnMgPC0gcnNtYXgyKGRhdGEpCkJTVCA8LSBib290LnN0cmVuZ3RoKGRhdGEsIAogICAgICAgICAgICAgICAgICAgICBSID0gMTAwMCwgCiAgICAgICAgICAgICAgICAgICAgIGFsZ29yaXRobSA9ICJyc21heDIiLCAKICAgICAgICAgICAgICAgICAgICAgZGVidWcgPSBUUlVFKSAgCmhlYWQoQlNUKQpCU1RbQlNUJHN0cmVuZ3RoID4gMC44NSAmIEJTVCRkaXJlY3Rpb24gPiAwLjUsIF0KCmF2Z25ldDEgPC0gYXZlcmFnZWQubmV0d29yayhCU1QsIHRocmVzaG9sZCA9IDAuODUpCmF2Z25ldDEKCmJubGVhcm46OnNjb3JlKGF2Z25ldDEsIGRhdGEgPSBkYXRhKQoKYXN0cjEgPC0gYXJjLnN0cmVuZ3RoKGF2Z25ldDEsIGRhdGEsICJiaWMtZyIpICAgIyMgY29tcHV0ZSBlZGdlIHN0cmVuZ3RocwoKcWdyYXBoKAogIGFzdHIxLAogIGxhYmVscyA9IG5hbWVzLAogIG5vZGVOYW1lcyA9IGxvbmduYW1lcywKICBsZWdlbmQuY2V4ID0gLjUsCiAgdnNpemUgPSA2LAogIGxheW91dCA9ICJjaXJjbGUiCikKCiMjIEdHTSBmb3IgY29tcGFyaXNvbgpuMSA8LSBlc3RpbWF0ZU5ldHdvcmsoZGF0YSwgZGVmYXVsdD0iRUJJQ2dsYXNzbyIsIHRocmVzaG9sZD1UUlVFKQpwbG90KAogIG4xLAogIGxheW91dCA9ICJjaXJjbGUiLAogIGxhYmVscyA9IG5hbWVzLAogIG5vZGVOYW1lcyA9IGxvbmduYW1lcywKICB0aGVtZSA9ICJjb2xvcmJsaW5kIiwKICBsZWdlbmQuY2V4ID0gMC41LAogIHZzaXplID0gNgopCgpgYGAKCuKAg+KAg+WOn+eQhuS4juW3peWFt+eahOS4gOS6m+ihpeWFheOAglvnpZ7lmahkYWdpdHR5XShodHRwczovL3d3dy5kYWdpdHR5Lm5ldC8p77yb5bey57uP5a6J6KOF5LqGZGFnaXR0eeWMheOAguWfuuS6juaOqOaWh++8mlvvvIjlm6DmnpzvvInotJ3lj7bmlq/nvZHnu5zkuI7mnInlkJHml6Dnjq/lm77vvIhEQUfvvInlnKjlm6Dmnpzmjqjmlq3kuK3nmoTlupTnlKhdKGh0dHBzOi8vbXAud2VpeGluLnFxLmNvbS9zLzlUOWVadzZWNU9xS2ZHNl9YdzlneGcp44CC5Y6f55CG5Lul6L+Z5Liq5Li65Z+656GA77yaW+i0neWPtuaWr+e9kee7nOWcqOeyvuelnueXheeQhuWtpueglOeptuS4reeahOW6lOeUqF0oaHR0cHM6Ly9tcC53ZWl4aW4ucXEuY29tL3MvejNocHVMdy0tdm5pV0xYa084Uzk2dynjgIIKCi0gICAqKui0neWPtuaWr+e9kee7nOeahOS8mOWKv++8mioqCgogICAgLSAgICoqYS7lj6/op4bljJbkvp3otZblhbPns7sqKu+8mumAmui/h+Wbvue7k+aehOebtOinguWxleekuuWPmOmHj+S5i+mXtOeahOS+nei1luaAp+WSjOWboOaenOaWueWQke+8jOacieWKqeS6jueQhuino+WkjeadguS6pOS6kuacuuWItuOAggoKICAgIC0gICAqKmIu5aSE55CG5aSN5p2C5Lqk5LqS5YWz57O7KirvvJrpgILlkIjlpJrlj5jph4/jgIHlpJrlsYLmrKHkuqTkupLliIbmnpDvvIzlsKTlhbbmmK/mtonlj4rlv4PnkIblrablkozljLvlrabkuK3nmoTlpI3mnYLns7vnu5/jgIIKCiAgICAtICAgKipjLue8uuWkseaVsOaNruWkhOeQhuiDveWKmyoq77ya6LSd5Y+25pav572R57uc6IO95aSf5Zyo5pWw5o2u57y65aSx55qE5oOF5Ya15LiL6L+b6KGM5o6o5pat77yM5LiN6ZyA6KaB5a6M5pW05pWw5o2u6ZuG5Y2z5Y+v6L+b6KGM5YiG5p6Q44CCCgogICAgLSAgICoqZC7lm6Dmnpzmjqjmlq0qKu+8muS4jeS7heWPr+S7peWIhuaekOebuOWFs+aAp++8jOi/mOiDveaYjuehruWPmOmHj+S5i+mXtOeahOWboOaenOWFs+ezu++8jOacieWKqeS6juWGs+etluWSjOW5sumihOaWueahiOeahOiuvuiuoeOAggoKICAgIC0gICAqKmUu54G15rS75oCn5ZKM5omp5bGV5oCnKirvvJrmlK/mjIHliqjmgIHotJ3lj7bmlq/nvZHnu5zvvIhEQk7vvInliIbmnpDml7bpl7Tluo/liJfmlbDmja7vvIzov5vkuIDmraXnoJTnqbblj5jph4/pmo/ml7bpl7Tlj5jljJbnmoTliqjmgIHlvbHlk43jgIIKCi0gICAqKui0neWPtuaWr+e9kee7nOS4juaoquaWree9kee7nOWIhuaekOeahOWMuuWIqyoqCgogICAgLSAgICoq5qiq5pat572R57uc5YiG5p6QKirvvJrliIbmnpDlj5jph4/pl7TnmoTnm7jlhbPmgKfmiJbogZTns7vlvLrluqbvvJvkvb/nlKjml6DlkJHlm77ooajnpLrlj5jph4/pl7TlhbPns7vvvIzkuI3og73ljLrliIbmlrnlkJHmgKfmiJblm6DmnpzmgKfvvJvpgILlkIjmj4/ov7Dlj5jph4/kuYvpl7TnmoTpnZnmgIHlhbPogZTnu5PmnoTjgIIKCiAgICAtICAgKirotJ3lj7bmlq/nvZHnu5zliIbmnpAqKu+8muW8uuiwg+WboOaenOaOqOaWreWSjOaWueWQkeS+nei1luWFs+ezu++8m+S9v+eUqOacieWQkeaXoOeOr+Wbvu+8iERBR++8ieaYjuehruWboOaenOi3r+W+hO+8jOiDveWkn+aOqOaWreWPmOmHj+S5i+mXtOeahOWboOaenOmTvuadoe+8m+mAguWQiOaOoue0ouWkjeadguS6pOS6kuWSjOmihOa1i+WIhuaekO+8jOWwpOWFtuWcqOW/g+eQhuWtpuWSjOWMu+WtpumihuWfn+OAggoK4oCD4oCD6LSd5Y+25pav572R57uc5piv5YiG5p6Q5aSN5p2C5aSa5Y+Y6YeP5YWz57O755qE5by65aSn5bel5YW377yM5bCk5YW26YCC55So5LqO5b+D55CG5a2m5ZKM5Yy75a2m6aKG5Z+f55qE5Zug5p6c5o6o5pat44CC5a6D5LiN5LuF5Y+v5Lul5o+t56S65Y+Y6YeP5LmL6Ze055qE5p2h5Lu25L6d6LWW5ZKM5pa55ZCR5oCn77yM6L+Y6IO95pyJ5pWI5aSE55CG57y65aSx5pWw5o2u77yM5bm25a+55Y+Y6YeP5LmL6Ze055qE5Lqk5LqS5L2c55So6L+b6KGM5Y+v6KeG5YyW5ZKM6YeP5YyW5YiG5p6Q44CCCgrigIPigIPmraTlpJbvvIzotJ3lj7bmlq/nvZHnu5zlhbfmnInngbXmtLvmgKflkozmianlsZXmgKfvvIzmlK/mjIHliqjmgIHotJ3lj7bmlq/nvZHnu5zvvIhEQk7vvInlpITnkIbml7bpl7Tluo/liJfmlbDmja7vvIzov5vkuIDmraXmjqLntKLpmo/ml7bpl7Tlj5jljJbnmoTliqjmgIHov4fnqIvjgILlm6DmraTvvIzlroPlnKjnsr7npZ7nl4XnkIblrabnrYnpoobln5/lhbfmnInph43opoHnmoTlupTnlKjku7flgLzvvIzkuLror4rmlq3jgIHpooTmtYvlkozlubLpooTnrZbnlaXmj5Dkvpvkuobnp5Hlrabkvp3mja7lkozlhrPnrZbmlK/mjIHjgIIKCiMgOCDkvKDnu5/mhI/kuYnnmoTnpL7kvJrnvZHnu5zliIbmnpDvvIjln7rkuo5vYnPnmoTlpITnkIbvvIkKCuKAg+KAg+WJjemdoueahOe9kee7nOWIhuaekOmDveaYr+WfuuS6juWIl+eahOWkhOeQhu+8m+S8oOe7n+eahFNOQeaYr+WfuuS6juihjOeahOiuoeeul+S4juWPr+inhuWMluOAgui/meS4qumDqOWIhuWwseaYr+ihpeWFheS4gOS6m+WFs+S6juihjOeahOiuoeeul+OAggo=