1 R Notebook-20181028-Install-R-RstudioServer-Git-In-CentOS7

20181028-Install-R-And_Rstudio-In-CentOS

1.1 CentOS7安装R及Rstudio Server

1.1.1 一、先来安装R

1.1.1.1 使用yum安装方式搭建R环境-推荐

安装Extra Packages for Enterprise Linux (EPEL);安装EPEL可以使你更方便的从EPEL来安装R语言,而无需通过其他途径来安装R。如果你运行的是RedHat或CentOS系统的话,你也要安装EPEL来确保RStudio Server正常运行。

CentOS7 64位版本安装EPEL的代码如下:

# sudo yum install  epel-release
# 接下来运行: 
# yum upgrade

EPEL成功安装后,使用以下代码便可以轻松的进行R语言的安装:

# sudo yum install R 

在Terminal试输入R,看能不能运行,可以的话就OK。不行的话就只能按自己出现的情况百度,google了。

1.1.1.2 使用源代码安装方式搭建R环境

1.1.1.2.1 1.下载R软件

使用下面命令下载R软件

# wget http://mirror.bjtu.edu.cn/cran/src/base/R-3/R-3.0.1.tar.gz
1.1.1.2.2 2.解压

执行下列命令解压R软件,并切换到解压目录中。

#解压命令
# tar -zxvf R-3.0.1.tar.gz

#切换目录
# cd R-3.0.1                      
1.1.1.2.3 3.安装

安装R软件,并设置好工作路径,后面配环境变量时需要。

# yum install readline-devel
# yum install libXt-devel
# mkdir -p /home/work/R
# # 设置工作路径
# ./configure --prefix=/home/work/R --enable-R-shlib 

# 接下来执行代码安装:
# make
# make install
1.1.1.2.4 4.配置环境变量

此处的R路径为上面安装时的–prefix=/home/work/R

# #添加到PATH中: PATH=/home/work/R/bin:$PATH
# vim ~/.bash_profile  
# source ~/.bash_profile  
1.1.1.2.5 5.测试
# R

# R version 3.5.1 (2018-07-02) -- "Feather Spray"
# Copyright (C) 2018 The R Foundation for Statistical Computing
# Platform: x86_64-redhat-linux-gnu (64-bit)
# 
# R是自由软件,不带任何担保。
# 在某些条件下你可以将其自由散布。
# 用'license()'或'licence()'来看散布的详细条件。
# 
# R是个合作计划,有许多人为之做出了贡献.
# 用'contributors()'来看合作者的详细情况
# 用'citation()'会告诉你如何在出版物中正确地引用R或R程序包。
# 
# 用'demo()'来看一些示范程序,用'help()'来阅读在线帮助文件,或
# 用'help.start()'通过HTML浏览器来看帮助文件。
# 用'q()'退出R.

1.1.2 二、安装Rstudio Server

去官网下载一个https://www.rstudio.com/products/rstudio/download-server/ 自己找找,总有一款适合你。我的系统是Centos 7 64bit。

# @2018-10-28我的是:
# $ wget https://download2.rstudio.org/rstudio-server-rhel-1.1.456-x86_64.rpm
# $ sudo yum install rstudio-server-rhel-1.1.456-x86_64.rpm

# 两行命令查看是否安装成功
# $ rstudio-server verify-installation
# $ ps -aux | grep rstudio-server

[siqin@localhost ~]$ wget https://download2.rstudio.org/rstudio-server-rhel-1.1.456-x86_64.rpm –2018-10-28 17:37:25– https://download2.rstudio.org/rstudio-server-rhel-1.1.456-x86_64.rpm 正在解析主机 download2.rstudio.org (download2.rstudio.org)… 52.85.82.34, 52.85.82.209, 52.85.82.189, … 正在连接 download2.rstudio.org (download2.rstudio.org)|52.85.82.34|:443… 已连接。 已发出 HTTP 请求,正在等待回应… 200 OK 长度:45678052 (44M) [application/x-redhat-package-manager] 正在保存至: “rstudio-server-rhel-1.1.456-x86_64.rpm”

100%[======================================>] 45,678,052 2.60MB/s 用时 16s

2018-10-28 17:37:43 (2.66 MB/s) - 已保存 “rstudio-server-rhel-1.1.456-x86_64.rpm” [45678052/45678052])

1.1.3 三、在浏览器中启动Rstudio

Linux下使用浏览器访问,可以开始R语言的学习了: http://[你的IP地址]:8787,例如http://192.168.1XX.XX:8787 其中你的IP地址可以在linux下输入 ifconfig 获取。 inet 192.168.140.128
netmask 255.255.255.0
broadcast 192.168.140.255

输入账号密码后,浏览器出现Rstudio界面 http://192.168.140.128:8787

1.1.4 四、RStudio Server新建用户多人在线协作开发

root用户无法登陆,新建一个用户进行登陆 useradd -d /home/R -m R,创建用户的同时指定主目录 passwd R,设置密码

1.1.4.1 增加新用户案例1

# ~ sudo groupadd hadoop 
# ~ sudo useradd hadoop -g hadoop;
# ~ sudo passwd hadoop 
# ~ sudo adduser hadoop sudo
# ~ sudo mkdir /home/hadoop 
# ~ sudo chown -R hadoop:hadoop /home/hadoop

1.1.4.2 测试账号设置成功

# ~ ssh hadoop@localhost
# ~ bash
# ~ pwd
# /home/hadoop

新打开浏览器窗口通过 hadoop账号登陆

1.1.4.3 添加新用户 案例2

添加用户的命令为:

# useradd username -u uid -p password

千万记得将uid设定为大于100的数字,大于500更好。

也许你会发现使用新创建的用户名依然无法登录,至少我的情况是这样。对此,我找到了解决办法,即通过修改RStudio Server的用户组限制来解决。

在设置用户组权限之前,必须先创建2个配置文件,RStudio Server在安装时不会自动创建这两个文件,必须手动操作。代码如下:

# $ touch /etc/rstudio/rserver.conf
# $ touch /etc/rstudio/rsession.conf
# $ ls

编辑rserver.conf文件并添加以下代码:

auth-required-user-group=rstudio_users

其中,你可以将“rstudio_users”命名为任何你想要的群组名字。

接下来,将刚才新建立的用户名添加到该用户组:

# $ groupadd rstudio_users
# $ usermod -g rstudio_users -G rstudio_users username
# $ rstudio-server restart

重启RStudio Server之后,你会发现终于可以用新用户登录啦!赶紧来体验在iPad上操作R的感觉吧!

还有一件事情必须注意噢! 如果你使用其他电脑的浏览器来远程使用R的话,请确保至少采用以下版本的浏览器:

  • Firefox 10;

  • Safari 5.0;

  • Google Chrome 15.

RStudio Server原生并不支持IE浏览器,但是你可以通过安装谷歌浏览器内嵌框架这个IE插件来实现IE操作。

如果你希望了解更多部署RStudio Server的信息,请前往RStudio Server Website进行了解。

1.1.5 五、RStudio Server配置

RStudio有2个配置文件,但是默认情况下,这2个文件没有创建,如果我们要修改这个配置,需要先创建这2个文件:

# [root@rac1 rstudio]# touch /etc/rstudio/rserver.conf
# [root@rac1 rstudio]# touch /etc/rstudio/rsession.conf

# [root@rac1 rstudio]# ls
# installed rserver.conf  rsession.conf  secure-cookie-key

创建配置文件之后就可以进行修改,修改完毕之后可以使用命令来验证修改的有效性:

[root@rac1 rstudio]# rstudio-server test-config

注意:

这个命令在启动和关闭RStudio server 时也会自动执行。当配置无效时,这个验证也会报错。

1.1.5.1 配置网络端口和地址

默认的端口是8787,如果我们想改成其他端口,可以在/etc/rstudio/rserver.conf 文件中添加并修改参数:

www-port=80

–这里我们是将端口改成80.

默认情况下,RStudio 是将IP地址绑定到0.0.0.0, 这样任何客户地址都可以访问。 我们可以改成其他地址,添加并修改参数:

www-address=127.0.0.1

修改完毕之后要验证参数有效性,并重启rstudio-server。

# [root@rac1 rstudio]# rstudio-server test-config
# [root@rac1 rstudio]# rstudio-server restart
# Stopping rstudio-server:                                   [  OK  ]
# Starting rstudio-server:                                   [  OK  ]

1.1.5.2 设置扩展库

如果我们添加其他的library到默认LD_LIBRARY_PATH 中指定库,可以通过rsession-ld-library-path参数,在/etc/rstudio/rserver.conf 文件中添加external library的位置即可,如:

rsession-ld-library-path=/opt/local/lib:/opt/local/someapp/lib

1.1.5.3 指定R 版本

默认情况下,RStudio server 运行时使用的R是系统PATH中指定的R,这个位置可以使用which R确定,如果我们的系统上有多个版本的R,那么可以使用rsession-which-r参数指定RStudio 使用哪个版本的R。 如:

rsession-which-r=/usr/local/bin/R

在/etc/rstudio/rserver.conf文件里添加这个参数之后,必须重启rstudio server 才能生效。

1.1.5.4 设置用户限制

如果有大量的用户使用,那么会消耗很多的资源,可以限制一些用户对资源的使用。

在/etc/rstudio/rserver.conf文件中添加auth-required-user-group参数,可以指定访问rstudio 的用户:

auth-required-user-group=rstudio_users

1.2 Git-Github集成-代码迭代与版本控制

1.2.1 安装Git

1.2.1.1 方法一 源码安装Git

# ubuntu安装git
# sudo apt-get install git

# //先安装git依赖的包 
# yum install zlib-devel 
# yum install openssl-devel 
# yum install perl 
# yum install cpio 
# yum install expat-devel 
# yum install gettext-devel 
# 
# //安装autoconf 
# yum install autoconf 
# 
# //安装git 
# wget http://www.codemonkey.org.uk/projects/git-snapshots/git/git-latest.tar.gz 
# tar xzvf git-latest.tar.gz 
# cd git-{date} 
# autoconf 
# ./configure --with-curl=/usr/local 
# make 
# make install

1.2.1.2 方法二推荐-yum安装epel后yum安装Git

# yum安装(epel源)
# sudo yum install epel-release
# yum install git  

# 测试安装成功:
# git --version

1.2.2 Github的rsa私钥 & 公钥

# 生成rsa密钥对
# ssh-keygen -t rsa

# 查看公钥并把公钥并上传到github
# cat /home/siqin/.ssh/id_rsa.pub

# ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1ZsNi2Rew4z3aq6ALXo4LMz8w6gYLpAnb8RqqiLTjTqVHqJapC8lVgqTciJ54ShpCD8/BFqmCWwx4LgiVWnJOyCkXKLFhS2rlr9qJlkfKgXqzaxOV2ZtdpC50VyIHWOLaFMWLQY9EP+kMU9Po399WNOryThD9KrfF34z7kj43SnMmK3zZzSd+1irb7s4UmjVaAy4O3nWMA56vO5AAHLkOdfWA9oswdF23mgaXafHG6+G07OtuAHJTx1jdg0XkHPSxOKGrNxDrhR8KKEbSz8Sc2X/gwmBr6pUx5R2wHbmatNXrAAyIKw5RMPmxBaVNCf9t/1tSdnZxmRmHSaKv4iX3 siqin@localhost.localdomain

1.2.3 配置用户名与邮箱

# git config --global user.name "xiangxing98"
# git config --global user.email "xiangxing985529@163.com"

1.2.4 创建一个项目并联系上Github

Clone Git Repository

Repository URL: git@github.com:xiangxing/rstudio-test.git

Or https://github.com/xiangxing98/learn-linux

Project direction name: rstudio-test

Create project as subdirectory of: ~/siqin/project

绑定本定项目和learn-linux

# ~ cd /home/siqin/R_Data_Science/learn-linux
# ~ touch README.md
# ~ echo Start-data-analyse >> README.md
# ~ git init
# ~ git add .
# ~ git commit -m 'first comment'
# ~ git remote add origin git@github.com:xiangxing98/learn-linux.git
# ~ git push -u origin master

# Push an existing repository from the command line
# git remote add origin git@github.com:xiangxing98/learn-linux.git
# git push -u origin master

打开RStudio设置到/home/siqin/R_Data_Science/learn-linux目录, tools–>version control –> project setup

在RStudio中修改sayHello.r的代码

sayHello<-function(name){ print(paste(“hello”,name)) }

sayHello(“Siqin”) sayHello(“World”)

提交:点击tools–>version control–> commit

上传到github:点击tools–>version control–> push

RStudio有如此强大的功能,极大的降低了编程的门槛。还没有用过的同学,赶紧去体验一把吧。极客的感觉!

1.2.5 云平台中的RStudio

如果有同道中人想进一步折腾可以考虑和云平台相接合,例如EC2。 Amazon EC2是Amazon Web Services(简称Aws)中的一个主要产品。 Amazon EC2可以看作是一台云主机,云主机上不仅可以搭建网站,也可以运行RStudio Sever。 目前Amazon对微型主机提供了新注册用户免费试用一年的活动,爱折腾的同学可以试试。 当然国内的盛大云也有超微型主机提供,一年400多元,比较适合个人或小型公司使用。

1.2.5.1 使用浏览器运行R的好处

  • 你可以从任何一台能上网的计算机去操作R

  • 共享代码、数据和其它文档

  • 多用户共享高性能计算资源与协同工作

  • 集中管理R扩展包

设想一下,你作为公司数据分析师到客户那里做咨询或培训, 使用客户电脑和RStudio Server就能直接利用公司主机上的数据集和程序代码作演示, 而不必携带厚重的笔记本出差,这样岂不轻松又显得有科技含量。

1.3 报错解决方案记录

1.3.1 UNABLE TO CONNECT TO SERVICE

报错: 解決登入 DOCKER 的 RSTUDIO 遇到錯誤 RSTUDIO INITIALIZATION ERROR: UNABLE TO CONNECT TO SERVICE。打開瀏覽器網址: http://localhost:8787/ 在 Username 與 Password 輸入剛剛建立的帳號密碼,卻遇到錯誤 Rstudio Initialization Error: Unable to connect to service

1.3.1.1 解決方式:

法1: 不需要額外建立帳號,直接輸入預設的帳號 rstudio 與密碼 rstudio 法2: 啟動 Container 指定帳號密碼。 (如果 Container 已經啟動,需要停止,避免衝到相同 port )

1.3.2 安装tidyverse出现的错误-退出狀態的值不是0

# install.packages(c("xml2","httr","rvest"))
# install.packages(c("rmarkdown","xml2","httr","rvest","tidyverse","bookdown","bookdownplus"))

1.3.2.1 解决方法

# XML 包退出狀態的值不是0
# sudo yum install libxml*
# 或者
# sudo yum install libxml2-devel

# 其他是httr 以及日vest包退出狀態的值不是0的解决方案
# sudo yum install openssl-devel
# sudo yum install libcurl-devel

1.3.3 安装REmap出现的错误dependency ‘XML’ is not available for package ‘REmap’

# library("devtools")
# install_github('lchiffon/REmap')
# dependency ‘XML’ is not available for package ‘REmap’

1.3.3.1 解决方法

# install.packages("XML")
LS0tCnRpdGxlOiAiMjAxODEwMjgtMjAxODEwMjgtSW5zdGFsbC1SLVJzdHVkaW9TZXJ2ZXItR2l0LUluLUNlbnRPUzcucm1kIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0aGVtZTogcGFwZXIKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAnNCcKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMgUiBOb3RlYm9vay0yMDE4MTAyOC1JbnN0YWxsLVItUnN0dWRpb1NlcnZlci1HaXQtSW4tQ2VudE9TNwo+IFsyMDE4MTAyOC1JbnN0YWxsLVItQW5kX1JzdHVkaW8tSW4tQ2VudE9TXShodHRwOi8veGlhbmd4aW5nOTguZ2l0aHViLmlvL2xlYXJuLWxpbnV4Ly8yMDE4MTAyOC0yMDE4MTAyOC1JbnN0YWxsLVItUnN0dWRpb1NlcnZlci1HaXQtSW4tQ2VudE9TNy5uYi5odG1sKQoKCiMjICBDZW50T1M35a6J6KOFUuWPilJzdHVkaW8gU2VydmVyCgojIyMg5LiA44CB5YWI5p2l5a6J6KOFUgoKIyMjIyDkvb/nlKh5dW3lronoo4XmlrnlvI/mkK3lu7pS546v5aKDLeaOqOiNkAoK5a6J6KOFRXh0cmEgUGFja2FnZXMgZm9yIEVudGVycHJpc2UgTGludXggKEVQRUwpO+WuieijhUVQRUzlj6/ku6Xkvb/kvaDmm7Tmlrnkvr/nmoTku45FUEVM5p2l5a6J6KOFUuivreiogO+8jOiAjOaXoOmcgOmAmui/h+WFtuS7lumAlOW+hOadpeWuieijhVLjgILlpoLmnpzkvaDov5DooYznmoTmmK9SZWRIYXTmiJZDZW50T1Pns7vnu5/nmoTor53vvIzkvaDkuZ/opoHlronoo4VFUEVM5p2l56Gu5L+dUlN0dWRpbyBTZXJ2ZXLmraPluLjov5DooYzjgIIKCkNlbnRPUzcgNjTkvY3niYjmnKzlronoo4VFUEVM55qE5Luj56CB5aaC5LiL77yaCmBgYHtiYXNofQojIHN1ZG8geXVtIGluc3RhbGwgIGVwZWwtcmVsZWFzZQojIOaOpeS4i+adpei/kOihjO+8miAKIyB5dW0gdXBncmFkZQpgYGAKCkVQRUzmiJDlip/lronoo4XlkI7vvIzkvb/nlKjku6XkuIvku6PnoIHkvr/lj6/ku6Xovbvmnb7nmoTov5vooYxS6K+t6KiA55qE5a6J6KOF77yaCmBgYHtiYXNofQojIHN1ZG8geXVtIGluc3RhbGwgUiAKYGBgCgrlnKhUZXJtaW5hbOivlei+k+WFpVLvvIznnIvog73kuI3og73ov5DooYzvvIzlj6/ku6XnmoTor53lsLFPS+OAguS4jeihjOeahOivneWwseWPquiDveaMieiHquW3seWHuueOsOeahOaDheWGteeZvuW6pu+8jGdvb2dsZeS6huOAggoKCiMjIyMg5L2/55So5rqQ5Luj56CB5a6J6KOF5pa55byP5pCt5bu6UueOr+WigwoKIyMjIyMgMS7kuIvovb1S6L2v5Lu2Cgrkvb/nlKjkuIvpnaLlkb3ku6TkuIvovb1S6L2v5Lu2CmBgYHtiYXNofQojIHdnZXQgaHR0cDovL21pcnJvci5ianR1LmVkdS5jbi9jcmFuL3NyYy9iYXNlL1ItMy9SLTMuMC4xLnRhci5negpgYGAKCiMjIyMjIDIu6Kej5Y6LCgrmiafooYzkuIvliJflkb3ku6Top6PljotS6L2v5Lu277yM5bm25YiH5o2i5Yiw6Kej5Y6L55uu5b2V5Lit44CCCmBgYHtyfQoj6Kej5Y6L5ZG95LukCiMgdGFyIC16eHZmIFItMy4wLjEudGFyLmd6Cgoj5YiH5o2i55uu5b2VCiMgY2QgUi0zLjAuMSAgICAgICAgICAgICAgICAgICAgICAKYGBgCgojIyMjIyAzLuWuieijhQoK5a6J6KOFUui9r+S7tu+8jOW5tuiuvue9ruWlveW3peS9nOi3r+W+hO+8jOWQjumdoumFjeeOr+Wig+WPmOmHj+aXtumcgOimgeOAggpgYGB7cn0KIyB5dW0gaW5zdGFsbCByZWFkbGluZS1kZXZlbAojIHl1bSBpbnN0YWxsIGxpYlh0LWRldmVsCiMgbWtkaXIgLXAgL2hvbWUvd29yay9SCiMgIyDorr7nva7lt6XkvZzot6/lvoQKIyAuL2NvbmZpZ3VyZSAtLXByZWZpeD0vaG9tZS93b3JrL1IgLS1lbmFibGUtUi1zaGxpYiAKCiMg5o6l5LiL5p2l5omn6KGM5Luj56CB5a6J6KOF77yaCiMgbWFrZQojIG1ha2UgaW5zdGFsbApgYGAKCiMjIyMjIDQu6YWN572u546v5aKD5Y+Y6YePCgrmraTlpITnmoRS6Lev5b6E5Li65LiK6Z2i5a6J6KOF5pe255qE4oCTcHJlZml4PS9ob21lL3dvcmsvUgpgYGB7YmFzaH0KIyAj5re75Yqg5YiwUEFUSOS4re+8miBQQVRIPS9ob21lL3dvcmsvUi9iaW46JFBBVEgKIyB2aW0gfi8uYmFzaF9wcm9maWxlICAKIyBzb3VyY2Ugfi8uYmFzaF9wcm9maWxlICAKYGBgCgojIyMjIyA1Lua1i+ivlQoKYGBge2Jhc2h9CiMgUgoKIyBSIHZlcnNpb24gMy41LjEgKDIwMTgtMDctMDIpIC0tICJGZWF0aGVyIFNwcmF5IgojIENvcHlyaWdodCAoQykgMjAxOCBUaGUgUiBGb3VuZGF0aW9uIGZvciBTdGF0aXN0aWNhbCBDb21wdXRpbmcKIyBQbGF0Zm9ybTogeDg2XzY0LXJlZGhhdC1saW51eC1nbnUgKDY0LWJpdCkKIyAKIyBS5piv6Ieq55Sx6L2v5Lu277yM5LiN5bim5Lu75L2V5ouF5L+d44CCCiMg5Zyo5p+Q5Lqb5p2h5Lu25LiL5L2g5Y+v5Lul5bCG5YW26Ieq55Sx5pWj5biD44CCCiMg55SoJ2xpY2Vuc2UoKSfmiJYnbGljZW5jZSgpJ+adpeeci+aVo+W4g+eahOivpue7huadoeS7tuOAggojIAojIFLmmK/kuKrlkIjkvZzorqHliJLvvIzmnInorrjlpJrkurrkuLrkuYvlgZrlh7rkuobotKHnjK4uCiMg55SoJ2NvbnRyaWJ1dG9ycygpJ+adpeeci+WQiOS9nOiAheeahOivpue7huaDheWGtQojIOeUqCdjaXRhdGlvbigpJ+S8muWRiuivieS9oOWmguS9leWcqOWHuueJiOeJqeS4reato+ehruWcsOW8leeUqFLmiJZS56iL5bqP5YyF44CCCiMgCiMg55SoJ2RlbW8oKSfmnaXnnIvkuIDkupvnpLrojIPnqIvluo/vvIznlKgnaGVscCgpJ+adpemYheivu+WcqOe6v+W4ruWKqeaWh+S7tu+8jOaIlgojIOeUqCdoZWxwLnN0YXJ0KCkn6YCa6L+HSFRNTOa1j+iniOWZqOadpeeci+W4ruWKqeaWh+S7tuOAggojIOeUqCdxKCkn6YCA5Ye6Ui4KCmBgYAoKCgojIyMg5LqM44CB5a6J6KOFUnN0dWRpbyBTZXJ2ZXIKCuWOu+WumOe9keS4i+i9veS4gOS4qmh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL3Byb2R1Y3RzL3JzdHVkaW8vZG93bmxvYWQtc2VydmVyLyDoh6rlt7Hmib7mib7vvIzmgLvmnInkuIDmrL7pgILlkIjkvaDjgILmiJHnmoTns7vnu5/mmK9DZW50b3MgNyA2NGJpdOOAggoKYGBge2Jhc2h9CiMgQDIwMTgtMTAtMjjmiJHnmoTmmK/vvJoKIyAkIHdnZXQgaHR0cHM6Ly9kb3dubG9hZDIucnN0dWRpby5vcmcvcnN0dWRpby1zZXJ2ZXItcmhlbC0xLjEuNDU2LXg4Nl82NC5ycG0KIyAkIHN1ZG8geXVtIGluc3RhbGwgcnN0dWRpby1zZXJ2ZXItcmhlbC0xLjEuNDU2LXg4Nl82NC5ycG0KCiMg5Lik6KGM5ZG95Luk5p+l55yL5piv5ZCm5a6J6KOF5oiQ5YqfCiMgJCByc3R1ZGlvLXNlcnZlciB2ZXJpZnktaW5zdGFsbGF0aW9uCiMgJCBwcyAtYXV4IHwgZ3JlcCByc3R1ZGlvLXNlcnZlcgpgYGAKCltzaXFpbkBsb2NhbGhvc3Qgfl0kIHdnZXQgaHR0cHM6Ly9kb3dubG9hZDIucnN0dWRpby5vcmcvcnN0dWRpby1zZXJ2ZXItcmhlbC0xLjEuNDU2LXg4Nl82NC5ycG0KLS0yMDE4LTEwLTI4IDE3OjM3OjI1LS0gIGh0dHBzOi8vZG93bmxvYWQyLnJzdHVkaW8ub3JnL3JzdHVkaW8tc2VydmVyLXJoZWwtMS4xLjQ1Ni14ODZfNjQucnBtCuato+WcqOino+aekOS4u+acuiBkb3dubG9hZDIucnN0dWRpby5vcmcgKGRvd25sb2FkMi5yc3R1ZGlvLm9yZykuLi4gNTIuODUuODIuMzQsIDUyLjg1LjgyLjIwOSwgNTIuODUuODIuMTg5LCAuLi4K5q2j5Zyo6L+e5o6lIGRvd25sb2FkMi5yc3R1ZGlvLm9yZyAoZG93bmxvYWQyLnJzdHVkaW8ub3JnKXw1Mi44NS44Mi4zNHw6NDQzLi4uIOW3sui/nuaOpeOAggrlt7Llj5Hlh7ogSFRUUCDor7fmsYLvvIzmraPlnKjnrYnlvoXlm57lupQuLi4gMjAwIE9LCumVv+W6pu+8mjQ1Njc4MDUyICg0NE0pIFthcHBsaWNhdGlvbi94LXJlZGhhdC1wYWNrYWdlLW1hbmFnZXJdCuato+WcqOS/neWtmOiHszog4oCccnN0dWRpby1zZXJ2ZXItcmhlbC0xLjEuNDU2LXg4Nl82NC5ycG3igJ0KCjEwMCVbPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0+XSA0NSw2NzgsMDUyICAyLjYwTUIvcyDnlKjml7YgMTZzICAgIAoKMjAxOC0xMC0yOCAxNzozNzo0MyAoMi42NiBNQi9zKSAtIOW3suS/neWtmCDigJxyc3R1ZGlvLXNlcnZlci1yaGVsLTEuMS40NTYteDg2XzY0LnJwbeKAnSBbNDU2NzgwNTIvNDU2NzgwNTJdKQoKIyMjIOS4ieOAgeWcqOa1j+iniOWZqOS4reWQr+WKqFJzdHVkaW8KCkxpbnV45LiL5L2/55So5rWP6KeI5Zmo6K6/6ZeuLOWPr+S7peW8gOWni1Lor63oqIDnmoTlrabkuaDkuobvvJoKaHR0cDovL1vkvaDnmoRJUOWcsOWdgF06ODc4N++8jOS+i+Wmgmh0dHA6Ly8xOTIuMTY4LjFYWC5YWDo4Nzg3CuWFtuS4reS9oOeahElQ5Zyw5Z2A5Y+v5Lul5ZyobGludXjkuIvovpPlhaUgaWZjb25maWcg6I635Y+W44CCCmluZXQgMTkyLjE2OC4xNDAuMTI4ICAKbmV0bWFzayAyNTUuMjU1LjI1NS4wICAKYnJvYWRjYXN0IDE5Mi4xNjguMTQwLjI1NQoK6L6T5YWl6LSm5Y+35a+G56CB5ZCO77yM5rWP6KeI5Zmo5Ye6546wUnN0dWRpb+eVjOmdogpodHRwOi8vMTkyLjE2OC4xNDAuMTI4Ojg3ODcKCiMjIyDlm5vjgIFSU3R1ZGlvIFNlcnZlcuaWsOW7uueUqOaIt+WkmuS6uuWcqOe6v+WNj+S9nOW8gOWPkQoKcm9vdOeUqOaIt+aXoOazleeZu+mZhu+8jOaWsOW7uuS4gOS4queUqOaIt+i/m+ihjOeZu+mZhgp1c2VyYWRkIC1kIC9ob21lL1IgLW0gUu+8jOWIm+W7uueUqOaIt+eahOWQjOaXtuaMh+WumuS4u+ebruW9lQpwYXNzd2QgUu+8jOiuvue9ruWvhueggQoKIyMjIyDlop7liqDmlrDnlKjmiLfmoYjkvosxCgpgYGB7YmFzaH0KIyB+IHN1ZG8gZ3JvdXBhZGQgaGFkb29wIAojIH4gc3VkbyB1c2VyYWRkIGhhZG9vcCAtZyBoYWRvb3A7CiMgfiBzdWRvIHBhc3N3ZCBoYWRvb3AgCiMgfiBzdWRvIGFkZHVzZXIgaGFkb29wIHN1ZG8KIyB+IHN1ZG8gbWtkaXIgL2hvbWUvaGFkb29wIAojIH4gc3VkbyBjaG93biAtUiBoYWRvb3A6aGFkb29wIC9ob21lL2hhZG9vcApgYGAKCiMjIyMg5rWL6K+V6LSm5Y+36K6+572u5oiQ5YqfCmBgYHtiYXNofQojIH4gc3NoIGhhZG9vcEBsb2NhbGhvc3QKIyB+IGJhc2gKIyB+IHB3ZAojIC9ob21lL2hhZG9vcApgYGAKCuaWsOaJk+W8gOa1j+iniOWZqOeql+WPo+mAmui/hyBoYWRvb3DotKblj7fnmbvpmYYKCiMjIyMg5re75Yqg5paw55So5oi3IOahiOS+izIKCua3u+WKoOeUqOaIt+eahOWRveS7pOS4uu+8mgpgYGB7YmFzaH0KIyB1c2VyYWRkIHVzZXJuYW1lIC11IHVpZCAtcCBwYXNzd29yZApgYGAKCuWNg+S4h+iusOW+l+WwhnVpZOiuvuWumuS4uuWkp+S6jjEwMOeahOaVsOWtl++8jOWkp+S6jjUwMOabtOWlveOAggoK5Lmf6K645L2g5Lya5Y+R546w5L2/55So5paw5Yib5bu655qE55So5oi35ZCN5L6d54S25peg5rOV55m75b2V77yM6Iez5bCR5oiR55qE5oOF5Ya15piv6L+Z5qC344CC5a+55q2k77yM5oiR5om+5Yiw5LqG6Kej5Yaz5Yqe5rOV77yM5Y2z6YCa6L+H5L+u5pS5UlN0dWRpbyBTZXJ2ZXLnmoTnlKjmiLfnu4TpmZDliLbmnaXop6PlhrPjgIIKCuWcqOiuvue9rueUqOaIt+e7hOadg+mZkOS5i+WJje+8jOW/hemhu+WFiOWIm+W7ujLkuKrphY3nva7mlofku7bvvIxSU3R1ZGlvIFNlcnZlcuWcqOWuieijheaXtuS4jeS8muiHquWKqOWIm+W7uui/meS4pOS4quaWh+S7tu+8jOW/hemhu+aJi+WKqOaTjeS9nOOAguS7o+eggeWmguS4i++8mgpgYGB7YmFzaH0KIyAkIHRvdWNoIC9ldGMvcnN0dWRpby9yc2VydmVyLmNvbmYKIyAkIHRvdWNoIC9ldGMvcnN0dWRpby9yc2Vzc2lvbi5jb25mCiMgJCBscwpgYGAKCue8lui+kXJzZXJ2ZXIuY29uZuaWh+S7tuW5tua3u+WKoOS7peS4i+S7o+egge+8mgpgYGAKYXV0aC1yZXF1aXJlZC11c2VyLWdyb3VwPXJzdHVkaW9fdXNlcnMKYGBgCuWFtuS4re+8jOS9oOWPr+S7peWwhuKAnHJzdHVkaW9fdXNlcnPigJ3lkb3lkI3kuLrku7vkvZXkvaDmg7PopoHnmoTnvqTnu4TlkI3lrZfjgIIKCuaOpeS4i+adpe+8jOWwhuWImuaJjeaWsOW7uueri+eahOeUqOaIt+WQjea3u+WKoOWIsOivpeeUqOaIt+e7hO+8mgpgYGB7YmFzaH0KIyAkIGdyb3VwYWRkIHJzdHVkaW9fdXNlcnMKIyAkIHVzZXJtb2QgLWcgcnN0dWRpb191c2VycyAtRyByc3R1ZGlvX3VzZXJzIHVzZXJuYW1lCiMgJCByc3R1ZGlvLXNlcnZlciByZXN0YXJ0CmBgYAoK6YeN5ZCvUlN0dWRpbyBTZXJ2ZXLkuYvlkI7vvIzkvaDkvJrlj5HnjrDnu4jkuo7lj6/ku6XnlKjmlrDnlKjmiLfnmbvlvZXllabvvIHotbbntKfmnaXkvZPpqozlnKhpUGFk5LiK5pON5L2cUueahOaEn+inieWQp++8gQoK6L+Y5pyJ5LiA5Lu25LqL5oOF5b+F6aG75rOo5oSP5Zmi77yBCuWmguaenOS9oOS9v+eUqOWFtuS7lueUteiEkeeahOa1j+iniOWZqOadpei/nOeoi+S9v+eUqFLnmoTor53vvIzor7fnoa7kv53oh7PlsJHph4fnlKjku6XkuIvniYjmnKznmoTmtY/op4jlmajvvJoKCi0gRmlyZWZveCAxMDsKCi0gU2FmYXJpIDUuMDsKCi0gR29vZ2xlIENocm9tZSAxNS4KClJTdHVkaW8gU2VydmVy5Y6f55Sf5bm25LiN5pSv5oyBSUXmtY/op4jlmajvvIzkvYbmmK/kvaDlj6/ku6XpgJrov4flronoo4XosLfmrYzmtY/op4jlmajlhoXltYzmoYbmnrbov5nkuKpJReaPkuS7tuadpeWunueOsElF5pON5L2c44CCCgrlpoLmnpzkvaDluIzmnJvkuobop6Pmm7TlpJrpg6jnvbJSU3R1ZGlvIFNlcnZlcueahOS/oeaBr++8jOivt+WJjeW+gFJTdHVkaW8gU2VydmVyIFdlYnNpdGXov5vooYzkuobop6PjgIIKCiMjIyDkupTjgIFSU3R1ZGlvIFNlcnZlcumFjee9rgoKUlN0dWRpb+aciTLkuKrphY3nva7mlofku7bvvIzkvYbmmK/pu5jorqTmg4XlhrXkuIvvvIzov5ky5Liq5paH5Lu25rKh5pyJ5Yib5bu677yM5aaC5p6c5oiR5Lus6KaB5L+u5pS56L+Z5Liq6YWN572u77yM6ZyA6KaB5YWI5Yib5bu66L+ZMuS4quaWh+S7tu+8mgoKYGBge3J9CiMgW3Jvb3RAcmFjMSByc3R1ZGlvXSMgdG91Y2ggL2V0Yy9yc3R1ZGlvL3JzZXJ2ZXIuY29uZgojIFtyb290QHJhYzEgcnN0dWRpb10jIHRvdWNoIC9ldGMvcnN0dWRpby9yc2Vzc2lvbi5jb25mCgojIFtyb290QHJhYzEgcnN0dWRpb10jIGxzCiMgaW5zdGFsbGVkIHJzZXJ2ZXIuY29uZiAgcnNlc3Npb24uY29uZiAgc2VjdXJlLWNvb2tpZS1rZXkKCmBgYAoK5Yib5bu66YWN572u5paH5Lu25LmL5ZCO5bCx5Y+v5Lul6L+b6KGM5L+u5pS577yM5L+u5pS55a6M5q+V5LmL5ZCO5Y+v5Lul5L2/55So5ZG95Luk5p2l6aqM6K+B5L+u5pS555qE5pyJ5pWI5oCn77yaCgpbcm9vdEByYWMxIHJzdHVkaW9dIyByc3R1ZGlvLXNlcnZlciB0ZXN0LWNvbmZpZwoK5rOo5oSP77yaCgrov5nkuKrlkb3ku6TlnKjlkK/liqjlkozlhbPpl61SU3R1ZGlvIHNlcnZlciDml7bkuZ/kvJroh6rliqjmiafooYzjgILlvZPphY3nva7ml6DmlYjml7bvvIzov5nkuKrpqozor4HkuZ/kvJrmiqXplJnjgIIKCiMjIyMg6YWN572u572R57uc56uv5Y+j5ZKM5Zyw5Z2ACgrpu5jorqTnmoTnq6/lj6PmmK84Nzg377yM5aaC5p6c5oiR5Lus5oOz5pS55oiQ5YW25LuW56uv5Y+j77yM5Y+v5Lul5ZyoL2V0Yy9yc3R1ZGlvL3JzZXJ2ZXIuY29uZiAg5paH5Lu25Lit5re75Yqg5bm25L+u5pS55Y+C5pWw77yaCgp3d3ctcG9ydD04MAoKLS3ov5nph4zmiJHku6zmmK/lsIbnq6/lj6PmlLnmiJA4MC4KCum7mOiupOaDheWGteS4i++8jFJTdHVkaW8g5piv5bCGSVDlnLDlnYDnu5HlrprliLAwLjAuMC4w77yMIOi/meagt+S7u+S9leWuouaIt+WcsOWdgOmDveWPr+S7peiuv+mXruOAgiDmiJHku6zlj6/ku6XmlLnmiJDlhbbku5blnLDlnYDvvIzmt7vliqDlubbkv67mlLnlj4LmlbDvvJoKCnd3dy1hZGRyZXNzPTEyNy4wLjAuMQoK5L+u5pS55a6M5q+V5LmL5ZCO6KaB6aqM6K+B5Y+C5pWw5pyJ5pWI5oCn77yM5bm26YeN5ZCvcnN0dWRpby1zZXJ2ZXLjgIIKYGBge2Jhc2h9CiMgW3Jvb3RAcmFjMSByc3R1ZGlvXSMgcnN0dWRpby1zZXJ2ZXIgdGVzdC1jb25maWcKIyBbcm9vdEByYWMxIHJzdHVkaW9dIyByc3R1ZGlvLXNlcnZlciByZXN0YXJ0CiMgU3RvcHBpbmcgcnN0dWRpby1zZXJ2ZXI6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbICBPSyAgXQojIFN0YXJ0aW5nIHJzdHVkaW8tc2VydmVyOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyAgT0sgIF0KYGBgCgojIyMjIOiuvue9ruaJqeWxleW6kwoK5aaC5p6c5oiR5Lus5re75Yqg5YW25LuW55qEbGlicmFyeeWIsOm7mOiupExEX0xJQlJBUllfUEFUSCDkuK3mjIflrprlupPvvIzlj6/ku6XpgJrov4dyc2Vzc2lvbi1sZC1saWJyYXJ5LXBhdGjlj4LmlbDvvIzlnKgvZXRjL3JzdHVkaW8vcnNlcnZlci5jb25mIOaWh+S7tuS4rea3u+WKoGV4dGVybmFsIGxpYnJhcnnnmoTkvY3nva7ljbPlj6/vvIzlpoLvvJoKCnJzZXNzaW9uLWxkLWxpYnJhcnktcGF0aD0vb3B0L2xvY2FsL2xpYjovb3B0L2xvY2FsL3NvbWVhcHAvbGliCgojIyMjIOaMh+WumlIg54mI5pysCgrpu5jorqTmg4XlhrXkuIvvvIxSU3R1ZGlvIHNlcnZlciDov5DooYzml7bkvb/nlKjnmoRS5piv57O757ufUEFUSOS4reaMh+WumueahFLvvIzov5nkuKrkvY3nva7lj6/ku6Xkvb/nlKh3aGljaCBS56Gu5a6a77yM5aaC5p6c5oiR5Lus55qE57O757uf5LiK5pyJ5aSa5Liq54mI5pys55qEUu+8jOmCo+S5iOWPr+S7peS9v+eUqHJzZXNzaW9uLXdoaWNoLXLlj4LmlbDmjIflrppSU3R1ZGlvIOS9v+eUqOWTquS4queJiOacrOeahFLjgIIg5aaC77yaCgpyc2Vzc2lvbi13aGljaC1yPS91c3IvbG9jYWwvYmluL1IKCuWcqC9ldGMvcnN0dWRpby9yc2VydmVyLmNvbmbmlofku7bph4zmt7vliqDov5nkuKrlj4LmlbDkuYvlkI7vvIzlv4Xpobvph43lkK9yc3R1ZGlvIHNlcnZlciDmiY3og73nlJ/mlYjjgIIKCiMjIyMg6K6+572u55So5oi36ZmQ5Yi2CgrlpoLmnpzmnInlpKfph4/nmoTnlKjmiLfkvb/nlKjvvIzpgqPkuYjkvJrmtojogJflvojlpJrnmoTotYTmupDvvIzlj6/ku6XpmZDliLbkuIDkupvnlKjmiLflr7notYTmupDnmoTkvb/nlKjjgIIKCuWcqC9ldGMvcnN0dWRpby9yc2VydmVyLmNvbmbmlofku7bkuK3mt7vliqBhdXRoLXJlcXVpcmVkLXVzZXItZ3JvdXDlj4LmlbDvvIzlj6/ku6XmjIflrprorr/pl65yc3R1ZGlvIOeahOeUqOaIt++8mgoKYXV0aC1yZXF1aXJlZC11c2VyLWdyb3VwPXJzdHVkaW9fdXNlcnMKCiMjIEdpdC1HaXRodWLpm4bmiJAt5Luj56CB6L+t5Luj5LiO54mI5pys5o6n5Yi2CgojIyMg5a6J6KOFR2l0CgojIyMjIOaWueazleS4gCDmupDnoIHlronoo4VHaXQKCmBgYHtiYXNofQojIHVidW50deWuieijhWdpdAojIHN1ZG8gYXB0LWdldCBpbnN0YWxsIGdpdAoKIyAvL+WFiOWuieijhWdpdOS+nei1lueahOWMhSAKIyB5dW0gaW5zdGFsbCB6bGliLWRldmVsIAojIHl1bSBpbnN0YWxsIG9wZW5zc2wtZGV2ZWwgCiMgeXVtIGluc3RhbGwgcGVybCAKIyB5dW0gaW5zdGFsbCBjcGlvIAojIHl1bSBpbnN0YWxsIGV4cGF0LWRldmVsIAojIHl1bSBpbnN0YWxsIGdldHRleHQtZGV2ZWwgCiMgCiMgLy/lronoo4VhdXRvY29uZiAKIyB5dW0gaW5zdGFsbCBhdXRvY29uZiAKIyAKIyAvL+WuieijhWdpdCAKIyB3Z2V0IGh0dHA6Ly93d3cuY29kZW1vbmtleS5vcmcudWsvcHJvamVjdHMvZ2l0LXNuYXBzaG90cy9naXQvZ2l0LWxhdGVzdC50YXIuZ3ogCiMgdGFyIHh6dmYgZ2l0LWxhdGVzdC50YXIuZ3ogCiMgY2QgZ2l0LXtkYXRlfSAKIyBhdXRvY29uZiAKIyAuL2NvbmZpZ3VyZSAtLXdpdGgtY3VybD0vdXNyL2xvY2FsIAojIG1ha2UgCiMgbWFrZSBpbnN0YWxsCmBgYAoKIyMjIyDmlrnms5XkuozmjqjojZAteXVt5a6J6KOFZXBlbOWQjnl1beWuieijhUdpdAoKYGBge2Jhc2h9CiMgeXVt5a6J6KOF77yIZXBlbOa6kO+8iQojIHN1ZG8geXVtIGluc3RhbGwgZXBlbC1yZWxlYXNlCiMgeXVtIGluc3RhbGwgZ2l0ICAKCiMg5rWL6K+V5a6J6KOF5oiQ5Yqf77yaCiMgZ2l0IC0tdmVyc2lvbgpgYGAKCgojIyMgR2l0aHVi55qEcnNh56eB6ZKlICYg5YWs6ZKlCgpgYGB7YmFzaH0KIyDnlJ/miJByc2Hlr4bpkqXlr7kKIyBzc2gta2V5Z2VuIC10IHJzYQoKIyDmn6XnnIvlhazpkqXlubbmiorlhazpkqXlubbkuIrkvKDliLBnaXRodWIKIyBjYXQgL2hvbWUvc2lxaW4vLnNzaC9pZF9yc2EucHViCgojIHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQURBUUFCQUFBQkFRQzFac05pMlJldzR6M2FxNkFMWG80TE16OHc2Z1lMcEFuYjhScXFpTFRqVHFWSHFKYXBDOGxWZ3FUY2lKNTRTaHBDRDgvQkZxbUNXd3g0TGdpVlduSk95Q2tYS0xGaFMycmxyOXFKbGtmS2dYcXpheE9WMlp0ZHBDNTBWeUlIV09MYUZNV0xRWTlFUCtrTVU5UG8zOTlXTk9yeVRoRDlLcmZGMzR6N2tqNDNTbk1tSzN6WnpTZCsxaXJiN3M0VW1qVmFBeTRPM25XTUE1NnZPNUFBSExrT2RmV0E5b3N3ZEYyM21nYVhhZkhHNitHMDdPdHVBSEpUeDFqZGcwWGtIUFN4T0tHck54RHJoUjhLS0ViU3o4U2MyWC9nd21CcjZwVXg1UjJ3SGJtYXROWHJBQXlJS3c1Uk1QbXhCYVZOQ2Y5dC8xdFNkblp4bVJtSFNhS3Y0aVgzIHNpcWluQGxvY2FsaG9zdC5sb2NhbGRvbWFpbgpgYGAKCiMjIyDphY3nva7nlKjmiLflkI3kuI7pgq7nrrEKCmBgYHtiYXNofQojIGdpdCBjb25maWcgLS1nbG9iYWwgdXNlci5uYW1lICJ4aWFuZ3hpbmc5OCIKIyBnaXQgY29uZmlnIC0tZ2xvYmFsIHVzZXIuZW1haWwgInhpYW5neGluZzk4NTUyOUAxNjMuY29tIgpgYGAKCgojIyMg5Yib5bu65LiA5Liq6aG555uu5bm26IGU57O75LiKR2l0aHViCgpDbG9uZSBHaXQgUmVwb3NpdG9yeQoKUmVwb3NpdG9yeSBVUkw6CmdpdEBnaXRodWIuY29tOnhpYW5neGluZy9yc3R1ZGlvLXRlc3QuZ2l0CgpPciBodHRwczovL2dpdGh1Yi5jb20veGlhbmd4aW5nOTgvbGVhcm4tbGludXgKClByb2plY3QgZGlyZWN0aW9uIG5hbWU6CnJzdHVkaW8tdGVzdAoKQ3JlYXRlIHByb2plY3QgYXMgc3ViZGlyZWN0b3J5IG9mOgp+L3NpcWluL3Byb2plY3QKCgrnu5HlrprmnKzlrprpobnnm67lkoxsZWFybi1saW51eApgYGB7cn0KIyB+IGNkIC9ob21lL3NpcWluL1JfRGF0YV9TY2llbmNlL2xlYXJuLWxpbnV4CiMgfiB0b3VjaCBSRUFETUUubWQKIyB+IGVjaG8gU3RhcnQtZGF0YS1hbmFseXNlID4+IFJFQURNRS5tZAojIH4gZ2l0IGluaXQKIyB+IGdpdCBhZGQgLgojIH4gZ2l0IGNvbW1pdCAtbSAnZmlyc3QgY29tbWVudCcKIyB+IGdpdCByZW1vdGUgYWRkIG9yaWdpbiBnaXRAZ2l0aHViLmNvbTp4aWFuZ3hpbmc5OC9sZWFybi1saW51eC5naXQKIyB+IGdpdCBwdXNoIC11IG9yaWdpbiBtYXN0ZXIKCiMgUHVzaCBhbiBleGlzdGluZyByZXBvc2l0b3J5IGZyb20gdGhlIGNvbW1hbmQgbGluZQojIGdpdCByZW1vdGUgYWRkIG9yaWdpbiBnaXRAZ2l0aHViLmNvbTp4aWFuZ3hpbmc5OC9sZWFybi1saW51eC5naXQKIyBnaXQgcHVzaCAtdSBvcmlnaW4gbWFzdGVyCmBgYAoKCuaJk+W8gFJTdHVkaW/orr7nva7liLAvaG9tZS9zaXFpbi9SX0RhdGFfU2NpZW5jZS9sZWFybi1saW51eOebruW9le+8jAp0b29sc+KAkz52ZXJzaW9uIGNvbnRyb2wg4oCTPiBwcm9qZWN0IHNldHVwCgrlnKhSU3R1ZGlv5Lit5L+u5pS5c2F5SGVsbG8ucueahOS7o+eggQoKCnNheUhlbGxvPC1mdW5jdGlvbihuYW1lKXsKICBwcmludChwYXN0ZSgiaGVsbG8iLG5hbWUpKQp9CgpzYXlIZWxsbygiU2lxaW4iKQpzYXlIZWxsbygiV29ybGQiKQoK5o+Q5Lqk77ya54K55Ye7dG9vbHPigJM+dmVyc2lvbiBjb250cm9s4oCTPiBjb21taXQKCuS4iuS8oOWIsGdpdGh1Yu+8mueCueWHu3Rvb2xz4oCTPnZlcnNpb24gY29udHJvbOKAkz4gcHVzaAoKUlN0dWRpb+acieWmguatpOW8uuWkp+eahOWKn+iDve+8jOaegeWkp+eahOmZjeS9juS6hue8lueoi+eahOmXqOanm+OAgui/mOayoeacieeUqOi/h+eahOWQjOWtpu+8jOi1tue0p+WOu+S9k+mqjOS4gOaKiuWQp+OAguaegeWuoueahOaEn+inie+8gQoKIAojIyMg5LqR5bmz5Y+w5Lit55qEUlN0dWRpbwoK5aaC5p6c5pyJ5ZCM6YGT5Lit5Lq65oOz6L+b5LiA5q2l5oqY6IW+5Y+v5Lul6ICD6JmR5ZKM5LqR5bmz5Y+w55u45o6l5ZCI77yM5L6L5aaCRUMy44CCCkFtYXpvbiBFQzLmmK9BbWF6b24gV2ViIFNlcnZpY2Vz77yI566A56ewQXdz77yJ5Lit55qE5LiA5Liq5Li76KaB5Lqn5ZOB44CCIApBbWF6b24gRUMy5Y+v5Lul55yL5L2c5piv5LiA5Y+w5LqR5Li75py677yM5LqR5Li75py65LiK5LiN5LuF5Y+v5Lul5pCt5bu6572R56uZ77yM5Lmf5Y+v5Lul6L+Q6KGMUlN0dWRpbyBTZXZlcuOAggrnm67liY1BbWF6b27lr7nlvq7lnovkuLvmnLrmj5DkvpvkuobmlrDms6jlhoznlKjmiLflhY3otLnor5XnlKjkuIDlubTnmoTmtLvliqjvvIzniLHmipjohb7nmoTlkIzlrablj6/ku6Xor5Xor5XjgIIK5b2T54S25Zu95YaF55qE55ub5aSn5LqR5Lmf5pyJ6LaF5b6u5Z6L5Li75py65o+Q5L6b77yM5LiA5bm0NDAw5aSa5YWD77yM5q+U6L6D6YCC5ZCI5Liq5Lq65oiW5bCP5Z6L5YWs5Y+45L2/55So44CCCiAKIyMjIyDkvb/nlKjmtY/op4jlmajov5DooYxS55qE5aW95aSECgotIOS9oOWPr+S7peS7juS7u+S9leS4gOWPsOiDveS4iue9keeahOiuoeeul+acuuWOu+aTjeS9nFIKCi0g5YWx5Lqr5Luj56CB44CB5pWw5o2u5ZKM5YW25a6D5paH5qGjCgotIOWkmueUqOaIt+WFseS6q+mrmOaAp+iDveiuoeeul+i1hOa6kOS4juWNj+WQjOW3peS9nAoKLSDpm4bkuK3nrqHnkIZS5omp5bGV5YyFCgrorr7mg7PkuIDkuIvvvIzkvaDkvZzkuLrlhazlj7jmlbDmja7liIbmnpDluIjliLDlrqLmiLfpgqPph4zlgZrlkqjor6LmiJbln7norq3vvIwK5L2/55So5a6i5oi355S16ISR5ZKMUlN0dWRpbyBTZXJ2ZXLlsLHog73nm7TmjqXliKnnlKjlhazlj7jkuLvmnLrkuIrnmoTmlbDmja7pm4blkoznqIvluo/ku6PnoIHkvZzmvJTnpLrvvIwK6ICM5LiN5b+F5pC65bim5Y6a6YeN55qE56yU6K6w5pys5Ye65beu77yM6L+Z5qC35bKC5LiN6L275p2+5Y+I5pi+5b6X5pyJ56eR5oqA5ZCr6YeP44CCCgojIyDmiqXplJnop6PlhrPmlrnmoYjorrDlvZUKCiMjIyBVTkFCTEUgVE8gQ09OTkVDVCBUTyBTRVJWSUNFCgrmiqXplJnvvJog6Kej5rG655m75YWlIERPQ0tFUiDnmoQgUlNUVURJTyDpgYfliLDpjK/oqqQgUlNUVURJTyBJTklUSUFMSVpBVElPTiBFUlJPUjogVU5BQkxFIFRPIENPTk5FQ1QgVE8gU0VSVklDReOAguaJk+mWi+eAj+imveWZqOe2suWdgDogaHR0cDovL2xvY2FsaG9zdDo4Nzg3LwrlnKggVXNlcm5hbWUg6IiHIFBhc3N3b3JkIOi8uOWFpeWJm+WJm+W7uueri+eahOW4s+iZn+WvhueivO+8jOWNu+mBh+WIsOmMr+iqpCBSc3R1ZGlvIEluaXRpYWxpemF0aW9uIEVycm9yOiBVbmFibGUgdG8gY29ubmVjdCB0byBzZXJ2aWNlCgojIyMjIOino+axuuaWueW8j++8mgoK5rOVMTog5LiN6ZyA6KaB6aGN5aSW5bu656uL5biz6Jmf77yM55u05o6l6Ly45YWl6aCQ6Kit55qE5biz6JmfIHJzdHVkaW8g6IiH5a+G56K8IHJzdHVkaW8K5rOVMjog5ZWf5YuVIENvbnRhaW5lciDmjIflrprluLPomZ/lr4bnorzjgIIKKOWmguaenCBDb250YWluZXIg5bey57aT5ZWf5YuV77yM6ZyA6KaB5YGc5q2i77yM6YG/5YWN6KGd5Yiw55u45ZCMIHBvcnQgKQoKIyMjIyDnu7zlkIjlj4LogIPljZrlrqLvvJoKCjHjgIFodHRwOi8vd3d3LmxpbnV4aWRjLmNvbS9MaW51eC8yMDEyLTAyLzU0NjEwLmh0bQoKMuOAgWh0dHA6Ly9ibG9nLmZlbnMubWUvci1yc3R1ZGlvLXNlcnZlci8KCjPjgIFodHRwOi8vd3d3Lmhhd2tpbnFpYW4uY29tL3poL3ItY2xvdWQtZGVwbG95aW5nLXJzdHVkaW8tc2VydmVyLwoKCiMjIyDlronoo4V0aWR5dmVyc2Xlh7rnjrDnmoTplJnor68t6YCA5Ye654uA5oWL55qE5YC85LiN5pivMAoKYGBge3J9CiMgaW5zdGFsbC5wYWNrYWdlcyhjKCJ4bWwyIiwiaHR0ciIsInJ2ZXN0IikpCiMgaW5zdGFsbC5wYWNrYWdlcyhjKCJybWFya2Rvd24iLCJ4bWwyIiwiaHR0ciIsInJ2ZXN0IiwidGlkeXZlcnNlIiwiYm9va2Rvd24iLCJib29rZG93bnBsdXMiKSkKYGBgCgojIyMjIOino+WGs+aWueazlQpgYGB7YmFzaH0KIyBYTUwg5YyF6YCA5Ye654uA5oWL55qE5YC85LiN5pivMAojIHN1ZG8geXVtIGluc3RhbGwgbGlieG1sKgojIOaIluiAhQojIHN1ZG8geXVtIGluc3RhbGwgbGlieG1sMi1kZXZlbAoKIyDlhbbku5bmmK9odHRyIOS7peWPiuaXpXZlc3TljIXpgIDlh7rni4DmhYvnmoTlgLzkuI3mmK8w55qE6Kej5Yaz5pa55qGICiMgc3VkbyB5dW0gaW5zdGFsbCBvcGVuc3NsLWRldmVsCiMgc3VkbyB5dW0gaW5zdGFsbCBsaWJjdXJsLWRldmVsCmBgYAoKCiMjIyDlronoo4VSRW1hcOWHuueOsOeahOmUmeivr2RlcGVuZGVuY3kg4oCYWE1M4oCZIGlzIG5vdCBhdmFpbGFibGUgZm9yIHBhY2thZ2Ug4oCYUkVtYXDigJkKCmBgYHtyfQojIGxpYnJhcnkoImRldnRvb2xzIikKIyBpbnN0YWxsX2dpdGh1YignbGNoaWZmb24vUkVtYXAnKQojIGRlcGVuZGVuY3kg4oCYWE1M4oCZIGlzIG5vdCBhdmFpbGFibGUgZm9yIHBhY2thZ2Ug4oCYUkVtYXDigJkKYGBgCgojIyMjIOino+WGs+aWueazlQpgYGB7cn0KIyBpbnN0YWxsLnBhY2thZ2VzKCJYTUwiKQpgYGAKCgoKCgoK