diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 22e1dc7..0000000 --- a/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.json -ssusers -*.log -sstraffic -tmp -*.swp -*~ -*.test \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d6e4096..0000000 --- a/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: bash - -install: - - sudo bash install.sh develop diff --git a/Explorer/Explorer.sh b/Explorer/Explorer.sh new file mode 100644 index 0000000..24a5f8a --- /dev/null +++ b/Explorer/Explorer.sh @@ -0,0 +1,318 @@ +#!/bin/bash + +#变量 +#app='/opt/QtPalmtop/bin/z' +app="$PWD" +listfile='/tmp/ListSelect.tmp' ; null='/dev/null' +recycle="$PWD/Recycle" +outfile='/tmp/DirFile.tmp' ; lstmp='/tmp/ls.tmp' +#optbin='/opt/QtPalmtop/bin' +declare -a dir style click clickterms \ +title=('文件管理' '打开文件' '选择文件' '保存文件') bak \ +clickbak clickmsg=('选择此项' '取消选择') \ +clickshow=('[ ]' '\E[94m[\E[31mX\E[94m]') \ +dirlink=("挂载到此文件夹" "进入链接目录") \ +linkshow=([1]="进入链接目录") clicknames \ +tar=("打开..." "打开..." "解压...") copy ok=("完成") +xy="4 14 0 0" ; select=1 +for ((n=1;n<=255;n++)) ; do + ok[$n]="失败" +done + +#转义序列 +inc='\E[33;40m' ; comc='\E[31m' ; end='\E[0m' +declare -a color=('\E[94m' '\E[92m' '\E[96m'\ + '\E[95m' '\E[31m' '\E[22;36m' '\E[92m') linkp=('' '\E[3;1H\E[2K') + +#函数 +prog_find(){ + n=0 ; unset dir[@] ; ls -1a > "$lstmp" + while read line ; do + if [ "${click[n]}" = "" ] ; then click[$n]=0 ; fi + prog_sure ; dir[$((n++))]="$line" + done < "$lstmp" + if [ "${dir[*]}" != "${bak[*]}" ] ; then + prog_click_back + fi + for ((n=0;n<=${#dir[@]};n++)) ; do + bak[$n]="${dir[n]}" + done + $app/List.sh " ${title[open]} "\ + "${PWD:((${#PWD}>36?-36:0))}" "" "0" "10" "$((select-1))"\ + "'..' `for ((n=2;n<${#dir[@]};n++)) ; do echo "'${clickshow[click[n]]}${color[style[n]]}${dir[n]}'" ; done`\ + '> $inc目录操作...' '> $inc选择项操作...' '> $inc磁盘信息' '> $inc退出'" +} +prog_sure(){ + if [ -d "$line" ] ; then style[n]=0 + if [ -h "$line" ] ; then style[n]=5 ; fi + elif [ -h "$line" ] ; then style[n]=2 + elif [ -b "$line" ] ; then style[n]=3 + elif [ -c "$line" ] ; then style[n]=4 + else + if [ "${line:(-7)}" = '.tar.gz' ] ; then style[n]=6 + else style[n]=1 + fi + fi +} +prog_msgbox_dirmenu(){ + $app/Msgbox.sh "$xy" "目录操作"\ + "'运行命令...' '新建文件(夹)...' 创建链接 粘贴 查找 返回" + case "$?" in + 0 ) prog_msgbox_run ;; + 1 ) prog_msgbox_new ;; + 2 ) prog_link_make ;; + 3 ) prog_paste ;; + 4 ) prog_search ;; + esac +} +prog_msgbox_run(){ + echo -e "$inc此功能未完成!$end" +} +prog_msgbox_new(){ + $app/Msgbox.sh "$xy" "'新建文件(夹)'"\ + "新建文件 新建文件夹 取消" + case "$?" in + 0 ) prog_input "新建文件" ; echo -n "" >> "$read" ;; + 1 ) prog_input "新建文件夹" ; mkdir "$read" ;; + esac +} +prog_link_make(){ + if [ "$mount" = "" ] ; then + echo -e "$inc没有选择链接原文件!$end" ; return + fi + prog_input 创建链接 ; ln -sn "$mount" "./$read" + echo -e "$inc链接创建${ok[$?]}!$end" +} +prog_input(){ + echo -e "\E[1m$inc$1 请输入名称: $end" + read -r read +} +prog_paste(){ + if [ "${copy[0]}" = "" ] ; then + echo -e "$inc剪贴板中无文件!$end" + usleep 500000 ; return + fi + echo -e "$inc粘贴中...$end" + for ((n=1;n<${#copy[@]};n++)) ; do + echo -e "$inc$n/$((${#copy[@]}-1)): ${copy[n]}$end" + if [ "${copy[0]}" = 0 ] ; then mv "${copy[n]}" . + else cp -rf "${copy[n]}" . + fi + done +} +prog_search(){ + echo -e "$inc此功能未完成!$end" +} +prog_file(){ + pwd="$PWD/${dir[select]}" ; tmp="$1" + if [ "$tmp" = 2 ] ; then tmp=0 ; fi + echo -ne "${linkp[$1]}$3$end" + if [ $1 = 2 ] ; then + $app/Msgbox.sh "$xy" "配置文件" "还原配置 取消" + if [ $? = 0 ] ; then echo "${PWD}/${dir[select]}" > /tmp/BakFilename.tmp ; echo -e "\033[?25h" ; stty echo ; break ; exit 1 ; fi + fi + $app/Msgbox.sh "$xy" "$2"\ + "'${clickmsg[click[select]]}' '运行...' ${linkshow[$1]} ${tar[$1]} '挂载/链接' ' 重命名' '删除...' '返回'" + case "$?" in + 0 ) click[$select]=$((click[select]==0)) ;; + 1 ) prog_file_msgbox_run ;; + $((tmp+1)) ) cd "$(dirname "$(readlink "${dir[select]}")")" ; select=1 ;; + $((tmp+2)) ) + if [ "$1" = 2 ] ; then prog_unpick + else prog_file_open + fi ;; + $((tmp+3)) ) prog_mount ;; + $((tmp+4)) ) prog_rename ;; + $((tmp+5)) ) prog_delete ;; + esac +} +prog_file_open(){ + $app/Msgbox.sh "$xy" "打开文件 请选择打开方式:"\ + "'备份还原' ' Vim ' 'MPlayer' ' 返回 '" + tmp=$? + if [ "$tmp" = 3 ] ; then return ; fi + case $tmp in + 0 ) echo "$PWD/${dir[select]}" > /tmp/BakFilename.tmp ;; + 1 ) vim "$PWD/${dir[select]}" ;; + 2 ) mplayer "$PWD/${dir[select]}" ;; + esac +} +prog_file_msgbox_run(){ + $app/Msgbox.sh "$xy" "运行文件"\ + "在此终端运行 取消" + case "$?" in + 0 ) (${dir[select]}) ;; + esac +} +prog_mount(){ + mount="$pwd" + echo -e "$inc$pwd已储存为挂载/链接原文件!$end" ; sleep 1s +} +prog_delete(){ + $app/Msgbox.sh "$xy" "删除文件 '确定要删除?'"\ + "删除到回收站 彻底删除 取消删除操作" + case "$?" in + 0 ) + rm -rf "$recycle/${dir[select]}" > "$null" + mv "${dir[select]}" "$recycle" ; tmp="$?" ;; + 1 ) rm -rf "${dir[select]}" ; tmp="$?" ;; + 2 ) return ;; + esac + echo -e "$inc删除${ok[tmp]}!$end" ; usleep 500000 +} +prog_rename(){ + prog_input 重命名文件 + mv "${dir[select]}" "$read" + echo -e "$inc重命名${ok[$?]}!$end" ; usleep 500000 +} +prog_click_back(){ + clickbak=(${click[@]}) ; unset click[@] + for ((n=0;n<=${#bak[@]};n++)) ; do + if [ "${clickbak[n]}" = 1 ] ; then + if [ "${bak[n]}" = "${dir[n]}" ] ; then + click[$n]=1 ; continue + fi + for ((m=0;m<=${#dir[@]};m++)) ; do + if [ "${bak[n]}" = "${dir[m]}" ] ; then + click[$m]=1 + fi + done + fi + done +} +prog_click(){ + clicknum=0 ; unset clickterms[@] ; unset clicknames[@] + declare -a clickterms ; declare -a clicknames + for ((n=0;n<=${#dir[@]};n++)) ; do + if [ "${click[n]}" = 1 ] ; then + clickterms[${#clickterms[@]}]="$PWD/${dir[n]}" + clicknames[${#clicknames[@]}]="${dir[n]}" + ((clicknum++)) + fi + done + if [ $clicknum = 0 ] ; then + echo ; echo -e "$inc无选择项!$end" + usleep 500000 ; return + fi + $app/Msgbox.sh "$xy" "选择项操作 已选择$clicknum项"\ + "剪切 复制 '删除...' '打包...' '返回'" + case $? in + 0 ) prog_multicut ;; + 1 ) prog_multicopy ;; + 2 ) prog_multidelete ;; + 3 ) prog_pickup ;; + esac +} +prog_click_clear(){ + unset clicktrems[@] clickname[@] click[@] ; clicknum=0 +} +prog_multicut(){ + unset copy[@] ; copy[0]=0 ; prog_copy_data + echo -e "$inc剪切: 已储存$clicknum个文件到剪贴板$end" + usleep 500000 +} +prog_multicopy(){ + unset copy[@] ; copy[0]=1 ; prog_copy_data + echo -e "$inc复制: 已储存$clicknum个文件到剪贴板$end" + usleep 500000 +} +prog_copy_data(){ + for ((n=0;n<${#clickterms[@]};n++)) ; do + copy[${#copy[@]}]="${clickterms[n]}" + done +} +prog_multidelete(){ + $app/Msgbox.sh "$xy" "删除文件 已选择$clicknum个文件"\ + "删除到回收站 彻底删除 取消删除操作" + tmp="$?" + if [ $tmp = 2 ] ; then return ; fi + echo -e "$inc正在删除文件中...$end" + for ((n=0;n<${#clickterms[@]};n++)) ; do + echo -e "$inc$((n+1))/${#clickterms[@]}: ${clickterms[n]}$end" + if [ $tmp = 0 ] ; then + rm -rf "$recycle/`basename "${clickterms[n]}"`" > "$null" + mv "${clickterms[n]}" "$recycle" + else + rm -rf "${clickterms[n]}" + fi + done + unset click[@] ; select=1 +} +prog_pickup(){ + $app/Msgbox.sh "$xy" "'创建.tar.gz压缩文件' '已选择$clicknum项'"\ + "'压缩到当前目录' '压缩到家目录' '压缩到根目录' '取消'" + case $? in + 0 ) tardir="$PWD" ;; + 1 ) tardir="$HOME" ;; + 2 ) tardir="/" ;; + 3 ) return ;; + esac + prog_input "文件打包" + echo -e "$inc压缩到$tardir/$read.tar.gz: 压缩中...$end" + tar -czvf "$tardir/$read.tar.gz" -C "$PWD" ${clicknames[@]} + echo -e "$inc压缩${ok[$?]}!$end" +} +prog_dir(){ + echo -e "${linkp[$1]}$3$end" + $app/Msgbox.sh "$xy" "文件夹$2"\ + "'进入' ${linkshow[$1]} '${clickmsg[click[select]]}' '挂载到此文件夹' '挂载/链接' '重命名' '删除...' '返回'" + case $? in + 0 ) cd "${dir[select]}" ; prog_click_clear ; select=1 ;; + $1 ) cd "`readlink "${dir[select]}"`" ; select=1 ;; + $((1+$1)) ) click[$select]=$((click[select]==0)) ;; + $((2+$1)) ) prog_mount_to ;; + $((3+$1)) ) pwd="$PWD/${dir[select]}" ; prog_mount ;; + $((4+$1)) ) prog_rename ;; + $((5+$1)) ) prog_delete ;; + esac +} +prog_mount_to(){ + if [ "$mount" = "" ] ; then + echo -e "$inc没有选择挂载原文件!$end" + usleep 500000 ; return + fi + umount -l "${dir[select]}" ; usleep 300000 + mount "$mount" "${dir[select]}" + echo -e "$inc挂载${ok[$?]}!$end" +} +prog_unpick(){ + $app/Msgbox.sh "$xy" "解压文件"\ + "解压到当前目录 解压到家目录 解压到根目录 取消" + case $? in + 0 ) tardir="$PWD" ;; + 1 ) tardir="$HOME" ;; + 2 ) tardir="/" ;; + 3 ) return ;; + esac + tar -xzvf "${dir[select]}" -C "$tardir" + echo -e "$inc解压${ok[$?]}$end" +} + +#初始化 +mkdir -p "$recycle" +initdir="$1" +power=1 ; open=0 + +#主程序 +stty -echo ; stty erase '^?' ; cd "$initdir" +trap 'echo -e "\033[?25h" ; stty echo ; exit 0' 2 +until [ "$quit" = 1 ] ; do + prog_find ; select="$(($(<$listfile)+1))" + case "$select" in + 1 ) cd .. ;; + ${#dir[@]} ) prog_msgbox_dirmenu ;; + $((${#dir[@]}+1)) ) prog_click ;; + $((${#dir[@]}+2)) ) df -h + echo -e "$inc按回车键继续...$end" ; read -s ;; + $((${#dir[@]}+3)) ) exit 1 ;; + * ) + case "${style[select]}" in + 0 ) prog_dir 0 ;; + 1 ) prog_file 0 普通文件 ;; + 2 ) prog_file 1 文件链接 "\E[2G$inc地址: `readlink "${dir[select]}"`" ;; + 5 ) prog_dir 1 链接 "\E[2G$inc地址: `readlink "${dir[select]}"`" ;; + 6 ) prog_file 2 压缩文件 ;; + esac ;; + esac +done +echo $result > $outfile ; echo -e "\033[?25h" ; stty echo ; exit 0 diff --git a/Explorer/List.sh b/Explorer/List.sh new file mode 100644 index 0000000..cd27635 --- /dev/null +++ b/Explorer/List.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +#文件位置 +#ctrlf="/opt/QtPalmtop/data/z/common/ctrl.dat" #按键数据 +ctrlf="$(dirname "$0")/term.dat" +outf="/tmp/ListSelect.tmp" + +#其它数据 +declare -a tmp=(`cat $ctrlf`) #按键数据处理 +up="${tmp[0]}" #上键数据 +down="${tmp[1]}" #下键数据 +left="${tmp[2]}" #左键数据 +right="${tmp[3]}" #右键数据 +pageup="${tmp[4]}" #上翻页键数据 +pagedown="${tmp[5]}" #下翻页键数据 +back="${tmp[6]}" #返回键数据 + +#颜色数据 +titc='\E[1;31;40m' #标题 +errc='\E[1;34;40m' #错误 没有列表项目 +color='\E[1;34;40m' #版权 Made By Norman (ZHIYB) +linc='\E[1;32;40m' #分割 ###分割线###颜色 +inc='\E[1;33;40m' #提示 提示文字 +declare -a listc=('\E[0;34;40m' '\E[1;34;102m') \ +term=('\E[0;34;40m' '\E[1;32;44m') +light="\E[1;37;40m" #高亮 强调文字 +end='\E[0m' #返回 返回初始颜色 + +#显示内容 +if [ "$1" = "" ] ; then + in_title=" 列表选择" ; in_made=" AR-B-P-B" + in_show="1" ; in_pagenum="0" ; in_init="0" + declare -a in_list=( '列表选择程序'\ + '参数: 标题 关于 错误 强调 数量 初始'\ + '参数1: 程序标题'\ + '参数2: 程序关于信息'\ + '参数3: 无选项错误显示'\ + '参数4: 选项左右提示条显示?'\ + '参数5: 每页显示数量'\ + '参数6: 初始选定项(从0开始)'\ + '参数7: 列表项'\ + '列表项详细信息见第二页'\ + '程序返回值: 选择的项目(从0开始)'\ + '返回值从0到255,共可返回256项'\ + '列表项输入说明:'\ + '全部列表项用\"\"括住,作为位置参数7'\ + '项与项之间用空格分开'\ + '最好把每一项都分别用'\'\''括住'\ + '某些特殊字符需用\\转义'\ + '其它:'\ + '可以在文本参数中使用\E[32;41mecho\E[7m转义\E[27m序列'\ + '位置参数必须存在(不为空)'\ + '否则会显示本帮助'\ + '它还会自动把选择的项保存到'\ + "\E[31m$outf文件中"\ + '这样就能选超过256个项了' ) +else + in_title="$1" ; in_made="$2" ; in_err="$3" + in_show="$4" ; in_pagenum="$5" ; in_init="$6" + eval declare -a in_list=($7) #列表项 + if [ "$in_init" = "" ] ; then in_init=0 ; fi +fi +lines="$linc################################################$end" #分割线 +title="$titc$in_title$color$in_made$end" #标题 +if [ "$in_show" = 1 ] ; then + declare -a chl=('------ ' '>>>>>> ') chr=(' ------' ' <<<<<<') +else declare -a chl=('' '') chr=('' '') +fi + +#函数 +prog_Auto(){ + ((pagenum=in_pagenum==0?$(tput lines)-4:in_pagenum)) + n=$lnum ; pages=0 + while ((n>pagenum)) ; do + ((pages++)) ; ((n-=pagenum)) + done +} + +#主程序 +lnum=${#in_list[@]} ; prog_Auto +quit=0 ; dat=$in_init ; pageno=1 +echo -ne '\E[?25l' ; stty -echo +until [ "$quit" = "1" ] ; do + if [ "$pages" = "0" ] ; then + n=0 ; page=$lnum #页面显示项 + else + page=0 ; pageno=1 ; n=$dat + while ((n>((pagenum-1)))) ; do + ((page+=pagenum)) ; ((n-=pagenum)) ; ((pageno++)) + done + n=$page ; ((page+=pagenum)) + if ((page>=((lnum+pagenum)))) ; then + ((n-=pagenum)) ; ((pageno--)) ; page=$lnum + elif ((page>lnum)) ; then page=$lnum + fi + fi + clear ; echo -e "$title\n$lines\n$inc上下键选择,左右键翻页: 第$light$pageno$inc, 共$light$((tmp=$pages+1))$inc页$end" + if [ "${#in_list[@]}" = "0" ] ; then + echo -e "$errc$in_err$end" ; dat=0 ; quit=1 + read -s ; continue + fi + until [ "$n" = "$page" ] ; do + echo -e "${term[((tmp=n++==dat))]}${chl[tmp]}${listc[tmp]}${in_list[((n-1))]}${term[tmp]}${chr[tmp]}$end" + done + read -sn 3 key + if [ "$key" = "$up" ] ; then ((dat--)) + ((dat=dat==-1?lnum-1:dat)) + elif [ "$key" = "$down" ] ; then ((dat++)) + ((dat=dat==lnum?0:dat)) + elif [ "$key" = "$right" ] ; then ((dat+=pagenum)) + ((dat=dat>=lnum?lnum-1:dat)) + elif [ "$key" = "$left" ] ; then + ((dat=dat>=lnum?lnum-pagenum:((dat "$outf" ; echo -ne '\E[?25h' +stty echo ; exit $dat diff --git a/Explorer/Msgbox.sh b/Explorer/Msgbox.sh new file mode 100644 index 0000000..0c3e6a1 --- /dev/null +++ b/Explorer/Msgbox.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +#变量 +#ctrlf='/opt/QtPalmtop/data/z/common/ctrl.dat' +ctrlf="$(dirname "$0")/term.dat" +declare -a tmp=($(<"$ctrlf")) +up="${tmp[0]}" ; down="${tmp[1]}" +left="${tmp[2]}" ; right="${tmp[3]}" +pageup="${tmp[4]}" ; pagedown="${tmp[5]}" +back="${tmp[6]}" +declare -a space upline midline downline + +#转义字符串 +titc='\E[91;40m' ; linc='\E[32;40m' +declare -a term=('\E[34;40m ' '\E[92;44m> \E[91;102m') +end='\E[0m' ; delete='\E[J' ; del='\E[2K' +declare -a frame=('\E[96;45m╔═\E[0m' \ +'\E[96;45m══\E[0m' '\E[96;45m═╗\E[0m' \ +'\E[96;45m║ \E[0m' '\E[96;45m ║\E[0m' \ +'\E[96;45m╚═\E[0m' '\E[96;45m══\E[0m' \ +'\E[96;45m═╝\E[0m' '##') +#frame框架顺序: 左上 上 右上 左 右 左下 下 右下 + +#函数 +prog_quit(){ + echo -e "\E[?25h" ; stty echo ; exit $select +} +prog_auto(){ + for ((n=0;n<${#message[@]};n++)) ; do + if ((${#message[n]}>xy[2])) ; then + xy[2]="${#message[n]}" + fi + done + for ((n=0;n<${#choose[@]};n++)) ; do + if ((${#choose[n]}>xy[2])) ; then + xy[2]="${#choose[n]}" + fi + done + xy[2]=$((xy[2]+1)) +} + +#初始化 +echo -ne "\E[?25l" ; stty -echo +if [ "$1" = "" ] ; then + declare -a xy=(4 14 0 0)\ + message=('Here is a message box.' '这是一个小提示选择框' 'Made by Norman (ZHIYB)')\ + choose=('Exit' 'Quit' 'Escape' '退出程序') + prog_auto ; xy[2]=$((xy[2]/2)) +else + eval declare -a xy=($1) message=($2) choose=($3) + if [ "${xy[2]}" = 0 ] ; then prog_auto ; fi + xy[2]=$((xy[2]/2)) +fi +for ((n=1;n<=xy[2]*2+4;n++)) ; do + space[n]="${space[n-1]} " + upline[n]="${upline[n-1]}${frame[1]}" + midline[n]="${midline[n-1]}${frame[8]}" + downline[n]="${downline[n-1]}${frame[6]}" +done +dat="${xy[3]}" + +#主程序 +echo -ne "\E[$((xy[0]<0?0:xy[0]));$((xy[1]-2))H$del$delete${frame[0]}${upline[xy[2]+2]}${frame[2]}" +for ((n=0;n<${#message[@]};n++)) ; do + echo -ne "\E[$((xy[0]+n+1));$((xy[1]-2))H${frame[3]} $titc${message[n]}${space[xy[2]*2-${#message[n]}+3]}${frame[4]}" +done +echo -ne " +\E[$((xy[0]+${#message[@]}+1));$((xy[1]-2))H${frame[3]} $linc${midline[xy[2]+1]} ${frame[4]}" +until [ "$quit" = 1 ] ; do + for ((n=0;n<${#choose[@]};n++)) ; do + echo -ne "\E[$((xy[0]+${#message[@]}+2+n));$((xy[1]-2))H${frame[3]} ${term[((dat==n))]}${choose[n]}$end${space[xy[2]*2-${#choose[n]}+1]}${frame[4]}" + done + echo -ne "\E[$((xy[0]+${#message[@]}+${#choose[@]}+2));$((xy[1]-2))H${frame[5]}${downline[xy[2]+2]}${frame[7]}" + read -sn 3 key + case "$key" in + "$up" ) ((dat--)) ; ((dat=dat<0?${#choose[@]}-1:dat)) ;; + "$down" ) ((dat++)) ; ((dat=dat>${#choose[@]}-1?0:dat)) ;; + "$left" ) dat=0 ;; + "$right" ) dat="$((${#choose[@]}-1))" ;; + "" ) quit=1 ; select="$dat" ;; + esac +done +prog_quit diff --git a/Explorer/ctrl.dat b/Explorer/ctrl.dat new file mode 100755 index 0000000..a370d8f --- /dev/null +++ b/Explorer/ctrl.dat @@ -0,0 +1 @@ +OA OB OD OC [20~ [21~  \ No newline at end of file diff --git a/Explorer/term.dat b/Explorer/term.dat new file mode 100644 index 0000000..a66b565 --- /dev/null +++ b/Explorer/term.dat @@ -0,0 +1 @@ +    [5~ [6~  \ No newline at end of file diff --git a/Explorer/usleep.c b/Explorer/usleep.c new file mode 100644 index 0000000..dd747ed --- /dev/null +++ b/Explorer/usleep.c @@ -0,0 +1,6 @@ +#include "stdlib.h" +#include "unistd.h" +int main(int argc, char **argv) { + if(argc == 2) { usleep(atoi(argv[1])); } + return 0; +} diff --git a/README.md b/README.md index a51ed2f..d8ef281 100644 --- a/README.md +++ b/README.md @@ -46,22 +46,15 @@ ## 脚本安全性声明 ## **本脚本采用Shell和Python语言编写,所有代码完全开源。不存在所谓的后台或挖矿代码,不会对您的任何信息进行上传,并在各个方面充分考虑到数据安全性。关于二维码生成过程是通过pip安装[第三方软件包](https://github.com/lincolnloop/python-qrcode),由第三方软件在服务器本地生成,生成的二维码链接也会自动销毁,不会上传任何信息。您的IP被封,或者您服务器出现不正常的负荷增高,与脚本本身没有任何关系,请您自行做好服务器安全维护工作,例如:不要使用弱密码、不要使用默认SSH端口,等等,防止被闲人爆破。_本着人与人之间的互信原则,请确认您相信我和我的脚本,否则请不要使用,不懂请不要喷,容易伤和气!!!_** -## 安装或更新到最新开发版(支持新特性,推荐使用) ## - wget -q -N --no-check-certificate https://git.fdos.me/stack/AR-B-P-B/raw/master/install.sh && bash install.sh develop ## 安装&更新 ## - wget -q -N --no-check-certificate https://git.fdos.me/stack/AR-B-P-B/raw/master/install.sh && bash install.sh + wget -q -N --no-check-certificate https://raw.githubusercontent.com/FunctionClub/SSR-Bash-Python/master/install.sh && bash install.sh ## 自检(没有卵用😝) ## - wget -q -N --no-check-certificate https://git.fdos.me/stack/AR-B-P-B/raw/master/install.sh && bash self-check.sh + wget -q -N --no-check-certificate https://raw.githubusercontent.com/FunctionClub/SSR-Bash-Python/master/self-check.sh && bash self-check.sh ## 卸载 ## - wget -q -N --no-check-certificate https://git.fdos.me/stack/AR-B-P-B/raw/master/install.sh && bash install.sh uninstall - -## 抓取日志 ## -``` -wget -q -N --no-check-certificate https://git.fdos.me/stack/AR-B-P-B/raw/master/install.sh && bash install.sh log -``` + wget -q -N --no-check-certificate https://raw.githubusercontent.com/FunctionClub/SSR-Bash-Python/master/install.sh && bash install.sh uninstall ## 离线安装 ## #此方法可用于网络情况不好,导致缺少文件的情况.亦可下载该脚本,用于备份 diff --git a/SSRStatus.sh b/SSRStatus.sh deleted file mode 100644 index 7ce0906..0000000 --- a/SSRStatus.sh +++ /dev/null @@ -1,908 +0,0 @@ -#!/usr/bin/env bash -PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin -export PATH - -#================================================= -# System Required: CentOS 6+/Debian 7+/Ubuntu 14.04+ -# Description: ShadowsocksR Status -# Version: 1.0.5 -# Author: Toyo -#================================================= - -sh_ver="1.0.5" -Timeout="10" -Test_URL="https://google.com" -Web_file="/usr/local/SSRStatus" -SSR_folder="/usr/local/shadowsocksr/shadowsocks" -filepath=$(cd "$(dirname "$0")"; pwd) -file=$(echo -e "${filepath}"|awk -F "$0" '{print $1}') -log_file="${file}/ssr_status.log" -config_file="${file}/ssr_status.conf" -JSON_file="/usr/local/SSRStatus/json/stats.json" - -Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m" -Info="${Green_font_prefix}[信息]${Font_color_suffix}" && Error="${Red_font_prefix}[错误]${Font_color_suffix}" && Tip="${Green_font_prefix}[注意]${Font_color_suffix}" - -#检查系统 -check_sys(){ - if [[ -f /etc/redhat-release ]]; then - release="centos" - elif cat /etc/issue | grep -q -E -i "debian"; then - release="debian" - elif cat /etc/issue | grep -q -E -i "ubuntu"; then - release="ubuntu" - elif cat /etc/issue | grep -q -E -i "centos|red hat|redhat"; then - release="centos" - elif cat /proc/version | grep -q -E -i "debian"; then - release="debian" - elif cat /proc/version | grep -q -E -i "ubuntu"; then - release="ubuntu" - elif cat /proc/version | grep -q -E -i "centos|red hat|redhat"; then - release="centos" - fi - #bit=`uname -m` -} -check_installed_server_status(){ - [[ ! -e "${Web_file}" ]] && echo -e "${Error} SSRStatus Web网页文件没有安装,请检查 !" && exit 1 -} -set_config_ip(){ - echo "请输入 ShadowsocksR 账号服务器公网IP" - stty erase '^H' && read -p "(默认取消):" ip - [[ -z "${ip}" ]] && echo "已取消..." && exit 1 - echo && echo -e " I P : ${Red_font_prefix}${ip}${Font_color_suffix}" && echo -} -set_config_port(){ - while true - do - echo -e "请输入 ShadowsocksR 账号端口" - stty erase '^H' && read -p "(默认: 2333):" port - [[ -z "$port" ]] && port="2333" - expr ${port} + 0 &>/dev/null - if [[ $? -eq 0 ]]; then - if [[ ${port} -ge 1 ]] && [[ ${port} -le 65535 ]]; then - echo && echo -e " 端口 : ${Red_font_prefix}${port}${Font_color_suffix}" && echo - break - else - echo -e "${Error} 请输入正确的数字!" - fi - else - echo -e "${Error} 请输入正确的数字!" - fi - done -} -set_config_password(){ - echo "请输入 ShadowsocksR 账号密码" - stty erase '^H' && read -p "(默认: doub.io):" passwd - [[ -z "${passwd}" ]] && passwd="doub.io" - echo && echo -e " 密码 : ${Red_font_prefix}${passwd}${Font_color_suffix}" && echo -} -set_config_method(){ - echo -e "请选择要设置的ShadowsocksR账号 加密方式 - ${Green_font_prefix} 1.${Font_color_suffix} none - - ${Green_font_prefix} 2.${Font_color_suffix} rc4 - ${Green_font_prefix} 3.${Font_color_suffix} rc4-md5 - ${Green_font_prefix} 4.${Font_color_suffix} rc4-md5-6 - - ${Green_font_prefix} 5.${Font_color_suffix} aes-128-ctr - ${Green_font_prefix} 6.${Font_color_suffix} aes-192-ctr - ${Green_font_prefix} 7.${Font_color_suffix} aes-256-ctr - - ${Green_font_prefix} 8.${Font_color_suffix} aes-128-cfb - ${Green_font_prefix} 9.${Font_color_suffix} aes-192-cfb - ${Green_font_prefix}10.${Font_color_suffix} aes-256-cfb - - ${Green_font_prefix}11.${Font_color_suffix} aes-128-cfb8 - ${Green_font_prefix}12.${Font_color_suffix} aes-192-cfb8 - ${Green_font_prefix}13.${Font_color_suffix} aes-256-cfb8 - - ${Green_font_prefix}14.${Font_color_suffix} salsa20 - ${Green_font_prefix}15.${Font_color_suffix} chacha20 - ${Green_font_prefix}16.${Font_color_suffix} chacha20-ietf - ${Tip} salsa20/chacha20-*系列加密方式,需要额外安装依赖 libsodium ,否则会无法启动ShadowsocksR !" && echo - stty erase '^H' && read -p "(默认: 5. aes-128-ctr):" method - [[ -z "${method}" ]] && method="5" - if [[ ${method} == "1" ]]; then - method="none" - elif [[ ${method} == "2" ]]; then - method="rc4" - elif [[ ${method} == "3" ]]; then - method="rc4-md5" - elif [[ ${method} == "4" ]]; then - method="rc4-md5-6" - elif [[ ${method} == "5" ]]; then - method="aes-128-ctr" - elif [[ ${method} == "6" ]]; then - method="aes-192-ctr" - elif [[ ${method} == "7" ]]; then - method="aes-256-ctr" - elif [[ ${method} == "8" ]]; then - method="aes-128-cfb" - elif [[ ${method} == "9" ]]; then - method="aes-192-cfb" - elif [[ ${method} == "10" ]]; then - method="aes-256-cfb" - elif [[ ${method} == "11" ]]; then - method="aes-128-cfb8" - elif [[ ${method} == "12" ]]; then - method="aes-192-cfb8" - elif [[ ${method} == "13" ]]; then - method="aes-256-cfb8" - elif [[ ${method} == "14" ]]; then - method="salsa20" - elif [[ ${method} == "15" ]]; then - method="chacha20" - elif [[ ${method} == "16" ]]; then - method="chacha20-ietf" - else - method="aes-128-ctr" - fi - echo && echo ${Separator_1} && echo -e " 加密 : ${Red_font_prefix}${method}${Font_color_suffix}" && echo ${Separator_1} && echo -} -set_config_protocol(){ - echo -e "请选择ShadowsocksR账号 协议插件 - ${Green_font_prefix}1.${Font_color_suffix} origin - ${Green_font_prefix}2.${Font_color_suffix} auth_sha1_v4 - ${Green_font_prefix}3.${Font_color_suffix} auth_aes128_md5 - ${Green_font_prefix}4.${Font_color_suffix} auth_aes128_sha1 - ${Green_font_prefix}5.${Font_color_suffix} auth_chain_a - ${Green_font_prefix}6.${Font_color_suffix} auth_chain_b" && echo - stty erase '^H' && read -p "(默认: 2. auth_sha1_v4):" protocol - [[ -z "${protocol}" ]] && protocol="2" - if [[ ${protocol} == "1" ]]; then - protocol="origin" - elif [[ ${protocol} == "2" ]]; then - protocol="auth_sha1_v4" - elif [[ ${protocol} == "3" ]]; then - protocol="auth_aes128_md5" - elif [[ ${protocol} == "4" ]]; then - protocol="auth_aes128_sha1" - elif [[ ${protocol} == "5" ]]; then - protocol="auth_chain_a" - elif [[ ${protocol} == "6" ]]; then - protocol="auth_chain_b" - else - protocol="auth_sha1_v4" - fi - echo && echo -e " 协议 : ${Red_font_prefix}${protocol}${Font_color_suffix}" && echo -} -set_config_obfs(){ - echo -e "请选择ShadowsocksR账号 混淆插件 - ${Green_font_prefix}1.${Font_color_suffix} plain - ${Green_font_prefix}2.${Font_color_suffix} http_simple - ${Green_font_prefix}3.${Font_color_suffix} http_post - ${Green_font_prefix}4.${Font_color_suffix} random_head - ${Green_font_prefix}5.${Font_color_suffix} tls1.2_ticket_auth" && echo - stty erase '^H' && read -p "(默认: 5. tls1.2_ticket_auth):" obfs - [[ -z "${obfs}" ]] && obfs="5" - if [[ ${obfs} == "1" ]]; then - obfs="plain" - elif [[ ${obfs} == "2" ]]; then - obfs="http_simple" - elif [[ ${obfs} == "3" ]]; then - obfs="http_post" - elif [[ ${obfs} == "4" ]]; then - obfs="random_head" - elif [[ ${obfs} == "5" ]]; then - obfs="tls1.2_ticket_auth" - else - obfs="tls1.2_ticket_auth" - fi - echo && echo -e " 混淆 : ${Red_font_prefix}${obfs}${Font_color_suffix}" && echo -} -set_config_like(){ - echo "请输入 ShadowsocksR 的链接(SS/SSR链接皆可,如 ss://xxxx ssr://xxxx)" - stty erase '^H' && read -p "(默认回车取消):" Like - [[ -z "${Like}" ]] && echo "已取消..." && exit 1 - echo && echo -e " 链接 : ${Red_font_prefix}${Like}${Font_color_suffix}" && echo -} -set_config_user(){ - echo -e "请输入选择输入方式 - ${Green_font_prefix}1.${Font_color_suffix} 输入ShadowsocksR账号全部信息(Shadowsocks原版也可以) - ${Green_font_prefix}2.${Font_color_suffix} 输入ShadowsocksR账号的 SSR链接(Shadowsocks原版也可以)" - stty erase '^H' && read -p "(默认:2):" enter_type - [[ -z "${enter_type}" ]] && enter_type="2" - if [[ ${enter_type} == "1" ]]; then - echo -e "下面依次开始输入要检测可用性的 ShadowsocksR账号信息。" && echo - set_config_ip - set_config_port - set_config_password - set_config_method - set_config_protocol - set_config_obfs - return 1 - elif [[ ${enter_type} == "2" ]]; then - set_config_like - return 2 - else - set_config_like - return 2 - fi -} -set_config_name(){ - echo "请输入 ShadowsocksR 账号的名称(用于区分,取个名字,可重复)" - stty erase '^H' && read -p "(默认取消):" Config_Name - [[ -z "${Config_Name}" ]] && echo "已取消..." && exit 1 - echo && echo -e " 名称 : ${Red_font_prefix}${Config_Name}${Font_color_suffix}" && echo -} -set_config_location(){ - echo "请输入 ShadowsocksR 账号的位置(用于区分,可重复)" - stty erase '^H' && read -p "(默认取消):" Config_Location - [[ -z "${Config_Location}" ]] && echo "已取消..." && exit 1 - echo && echo -e " 位置 : ${Red_font_prefix}${Config_Location}${Font_color_suffix}" && echo -} -Set_server(){ - echo -e "请输入 SSRStatus 网站要设置的 域名[server] -默认为本机IP为域名,例如输入: toyoo.ml,如果要使用本机IP,请留空直接回车" - stty erase '^H' && read -p "(默认: 本机IP):" server_s - [[ -z "$server_s" ]] && server_s="" - - echo && echo -e " IP/域名[server]: ${Red_background_prefix} ${server_s} ${Font_color_suffix}" && echo -} -Set_server_port(){ - while true - do - echo -e "请输入 SSRStatus 网站要设置的 域名/IP的端口[1-65535](如果是域名的话,一般建议用 http 80 端口)" - stty erase '^H' && read -p "(默认: 8888):" server_port_s - [[ -z "$server_port_s" ]] && server_port_s="8888" - expr ${server_port_s} + 0 &>/dev/null - if [[ $? -eq 0 ]]; then - if [[ ${server_port_s} -ge 1 ]] && [[ ${server_port_s} -le 65535 ]]; then - echo && echo -e " IP/域名[server]: ${Red_background_prefix} ${server_port_s} ${Font_color_suffix}" && echo - break - else - echo "输入错误, 请输入正确的端口。" - fi - else - echo "输入错误, 请输入正确的端口。" - fi - done -} -Set_crontab(){ - echo -e "请选择你要设置的ShadowsocksR账号检测时间间隔(如账号很多,请不要设置时间间隔过小) - ${Green_font_prefix}1.${Font_color_suffix} 5分钟 - ${Green_font_prefix}2.${Font_color_suffix} 10分钟 - ${Green_font_prefix}3.${Font_color_suffix} 20分钟 - ${Green_font_prefix}4.${Font_color_suffix} 30分钟 - ${Green_font_prefix}5.${Font_color_suffix} 40分钟 - ${Green_font_prefix}6.${Font_color_suffix} 50分钟 - ${Green_font_prefix}7.${Font_color_suffix} 1小时 - ${Green_font_prefix}8.${Font_color_suffix} 2小时 - ${Green_font_prefix}9.${Font_color_suffix} 自定义输入" && echo - stty erase '^H' && read -p "(默认: 2. 10分钟):" Crontab_time - [[ -z "${Crontab_time}" ]] && Crontab_time="2" - if [[ ${Crontab_time} == "1" ]]; then - Crontab_time="*/5 * * * *" - elif [[ ${Crontab_time} == "2" ]]; then - Crontab_time="*/10 * * * *" - elif [[ ${Crontab_time} == "3" ]]; then - Crontab_time="*/20 * * * *" - elif [[ ${Crontab_time} == "4" ]]; then - Crontab_time="*/30 * * * *" - elif [[ ${Crontab_time} == "5" ]]; then - Crontab_time="*/40 * * * *" - elif [[ ${Crontab_time} == "6" ]]; then - Crontab_time="*/50 * * * *" - elif [[ ${Crontab_time} == "7" ]]; then - Crontab_time="0 * * * *" - elif [[ ${Crontab_time} == "8" ]]; then - Crontab_time="0 */2 * * *" - elif [[ ${Crontab_time} == "9" ]]; then - Set_crontab_customize - else - Crontab_time="*/10 * * * *" - fi - echo && echo -e " 间隔时间 : ${Red_font_prefix}${Crontab_time}${Font_color_suffix}" && echo - Add_Crontab -} -Set_crontab_customize(){ - echo -e "请输入ShadowsocksR账号检测时间间隔(如账号很多,请不要设置时间间隔过小) - === 格式说明 === - * * * * * 分别对应 分钟 小时 日份 月份 星期 - ${Green_font_prefix} */10 * * * * ${Font_color_suffix} 代表每10分钟 检测一次 - ${Green_font_prefix} 0 */2 * * * ${Font_color_suffix} 代表每2小时的0分 检测一次 - ${Green_font_prefix} 10 * * * * ${Font_color_suffix} 代表每小时的第10分 检测一次 - ${Green_font_prefix} * 2 * * * ${Font_color_suffix} 代表每天的第2点 检测一次 - ${Green_font_prefix} 0 0 2 * * ${Font_color_suffix} 代表每2天的0点0分 检测一次" && echo - stty erase '^H' && read -p "(默认: */10 * * * *):" Crontab_time - [[ -z "${Crontab_time}" ]] && Crontab_time="*/10 * * * *" -} -GO(){ - echo -e "========== 开始记录测试信息 [$(date '+%Y-%m-%d %H:%M:%S')]==========\n" >> ${log_file} -} -exit_GG(){ - echo -e "========== 记录测试信息结束 [$(date '+%Y-%m-%d %H:%M:%S')]==========\n\n" >> ${log_file} - if [[ ${analysis_type} != "add" ]]; then - Config_JSON="{\n\"servers\": [\n${Config_JSON}],\n\"updated\": \"$(date +%s)\"\n}" - echo -e "${Config_JSON}" > ${JSON_file} - fi - exit 0 -} -Continue_if(){ - Config_Status="false" - [[ -z ${ip} ]] && ip="---.---.---.---" - if [[ ${Like_num} == ${integer} ]]; then - Config_JSON="${Config_JSON}{ \"ip\": \"${ip}\", \"name\": \"${Config_Name}\", \"type\": \"${Config_Type}\", \"type_1\": \"${Config_Type_1}\", \"location\": \"${Config_Location}\", \"status\": ${Config_Status}, \"time\": \"$(date '+%Y-%m-%d %H:%M:%S')\" }\n" - else - Config_JSON="${Config_JSON}{ \"ip\": \"${ip}\", \"name\": \"${Config_Name}\", \"type\": \"${Config_Type}\", \"type_1\": \"${Config_Type_1}\", \"location\": \"${Config_Location}\", \"status\": ${Config_Status}, \"time\": \"$(date '+%Y-%m-%d %H:%M:%S')\" },\n" - fi - continue -} -Get_Like(){ - [[ ! -e ${config_file} ]] && echo -e "${Error} 配置文件不存在!(${config_file})" | tee -a ${log_file} && exit 0 - Like=$(cat "${config_file}") - [[ -z ${Like} ]] && echo -e "${Error} 获取SS/SSR账号信息失败或配置文件为空 !" | tee -a ${log_file} && exit 0 - Like_num=$(echo -e "${Like}"|wc -l) -} -Analysis_Config(){ - Config=$(echo -e "${Like}"|sed -n "$1"p) - Config_info_base64=$(echo -e "${Config}"|awk -F '###' '{print $1}') - Config_Name=$(echo -e "${Config}"|awk -F '###' '{print $2}') - Config_Location=$(echo -e "${Config}"|awk -F '###' '{print $3}') - Config_Disabled=$(echo -e "${Config}"|awk -F '###' '{print $4}') - if [[ ${Config_Disabled} == "true" ]]; then - echo -e "${Info} 账号已禁用,跳过检测 [${Config_info_base64}] !" | tee -a ${log_file} - echo "---------------------------------------------------------" - continue - else - Config_info_base64_determine=$(echo -e ${Config_info_base64}|cut -c 1-6) - if [[ "${Config_info_base64_determine}" == "ssr://" ]]; then - Config_Type="ShadowsocksR" - Config_Type_1="SSR" - Config_info=$(echo -e "${Config_info_base64}"|cut -c 7-2000|base64 -d) - if [[ -z ${Config_info} ]]; then - echo -e "${Error} Base64解密失败 [${Config_info_base64}] !" | tee -a ${log_file} - if [[ ${analysis_type} == "add" ]]; then - exit_GG - else - Continue_if - fi - fi - ssr_config - else - Config_Type="Shadowsocks" - Config_Type_1="SS" - Config_info=$(echo -e "${Config_info_base64}"|cut -c 6-2000|base64 -d) - if [[ -z ${Config_info} ]]; then - echo -e "${Error} Base64解密失败 [${Config_info_base64}] !" | tee -a ${log_file} - if [[ ${analysis_type} == "add" ]]; then - exit_GG - else - Continue_if - fi - fi - ss_config - fi - fi -} -ss_config(){ - zuo=$(echo -e "${Config_info}"|awk -F "@" '{print $1}') - you=$(echo -e "${Config_info}"|awk -F "@" '{print $2}') - port=$(echo -e "${you}"|awk -F ":" '{print $NF}') - ip=$(echo -e "${you}"|awk -F ":${port}" '{print $1}') - if [[ $(echo -e "${ip}"|wc -L) -lt 7 ]]; then - echo -e "${Error} 错误,IP格式错误或为 ipv6地址[ ${ip} ]" | tee -a ${log_file} - if [[ ${analysis_type} == "add" ]]; then - exit_GG - else - Continue_if - fi - fi - method=$(echo -e "${zuo}"|awk -F ":" '{print $1}') - passwd=$(echo -e "${zuo}"|awk -F ":" '{print $2}') - protocol="origin" - obfs="plain" - echo -e "${ip} ${port} ${method} ${passwd} ${protocol} ${obfs}" - if [[ -z ${ip} ]] || [[ -z ${port} ]] || [[ -z ${method} ]] || [[ -z ${passwd} ]] || [[ -z ${protocol} ]] || [[ -z ${obfs} ]]; then - echo -e "${Error} 错误,有部分 账号参数为空![ ${ip} ,${port} ,${method} ,${passwd} ,${protocol} ,${obfs} ]" | tee -a ${log_file} - if [[ ${analysis_type} == "add" ]]; then - exit_GG - else - Continue_if - fi - fi -} -ssr_config(){ - zuo=$(echo -e "${Config_info}"|awk -F "/?" '{print $1}') - passwd_base64=$(echo -e "${zuo}"|awk -F ":" '{print $NF}') - zuo=$(echo -e "${Config_info}"|awk -F ":${passwd_base64}" '{print $1}') - obfs=$(echo -e "${zuo}"|awk -F ":" '{print $NF}') - zuo=$(echo -e "${Config_info}"|awk -F ":${obfs}" '{print $1}') - method=$(echo -e "${zuo}"|awk -F ":" '{print $NF}') - zuo=$(echo -e "${Config_info}"|awk -F ":${method}" '{print $1}') - protocol=$(echo -e "${zuo}"|awk -F ":" '{print $NF}') - zuo=$(echo -e "${Config_info}"|awk -F ":${protocol}" '{print $1}') - port=$(echo -e "${zuo}"|awk -F ":" '{print $NF}') - ip=$(echo -e "${Config_info}"|awk -F ":${port}" '{print $1}') - if [[ $(echo -e "${ip}"|wc -L) -lt 7 ]]; then - echo -e "${Error} 错误,IP格式错误[ ${ip} ]" | tee -a ${log_file} - if [[ ${analysis_type} == "add" ]]; then - exit_GG - else - Continue_if - fi - fi - passwd=$(echo -e "${passwd_base64}"|base64 -d) - echo -e "${ip} ${port} ${method} ${passwd} ${protocol} ${obfs}" - if [[ -z ${ip} ]] || [[ -z ${port} ]] || [[ -z ${method} ]] || [[ -z ${passwd} ]] || [[ -z ${protocol} ]] || [[ -z ${obfs} ]]; then - echo -e "${Error} 错误,有部分 账号参数为空![ ${ip} ,${port} ,${method} ,${passwd} ,${protocol} ,${obfs} ]" | tee -a ${log_file} - if [[ ${analysis_type} == "add" ]]; then - exit_GG - else - Continue_if - fi - fi -} -Start_Client(){ - nohup python "${SSR_folder}/local.py" -b "127.0.0.1" -l "${local_port}" -s "${ip}" -p "${port}" -k "${passwd}" -m "${method}" -O "${protocol}" -o "${obfs}" > /dev/null 2>&1 & - sleep 2s - PID=$(ps -ef |grep -v grep | grep "local.py" | grep "${local_port}" |awk '{print $2}') - if [[ -z ${PID} ]]; then - echo -e "${Error} ShadowsocksR客户端 启动失败,请检查 !" | tee -a ${log_file} - if [[ ${analysis_type} == "add" ]]; then - exit_GG - else - Continue_if - fi - fi -} -Socks5_test(){ - Test_results=$(curl --socks5 127.0.0.1:${local_port} -k -m ${Timeout} -s "${Test_URL}") - if [[ -z ${Test_results} ]]; then - echo -e "${Error} [${ip}] 检测失败,账号不可用,重新尝试一次..." | tee -a ${log_file} - sleep 2s - Test_results=$(curl --socks5 127.0.0.1:${local_port} -k -m ${Timeout} -s "${Test_URL}") - if [[ -z ${Test_results} ]]; then - echo -e "${Error} [${ip}] 检测失败,账号不可用(已重新尝试) !" | tee -a ${log_file} - Config_Status="false" - else - echo -e "${Info} [${ip}] 检测成功,账号可用 !" | tee -a ${log_file} - Config_Status="true" - fi - else - echo -e "${Info} [${ip}] 检测成功,账号可用 !" | tee -a ${log_file} - Config_Status="true" - fi - kill -9 ${PID} - PID=$(ps -ef |grep -v grep | grep "local.py" | grep "${local_port}" |awk '{print $2}') - if [[ ! -z ${PID} ]]; then - echo -e "${Error} ShadowsocksR客户端 停止失败,请检查 !" | tee -a ${log_file} - if [[ ${analysis_type} == "add" ]]; then - exit_GG - else - Continue_if - fi - fi - echo "---------------------------------------------------------" - if [[ ${analysis_type} != "add" ]]; then - if [[ ${Like_num} == ${integer} ]]; then - Config_JSON="${Config_JSON}{ \"ip\": \"${ip}\", \"name\": \"${Config_Name}\", \"type\": \"${Config_Type}\", \"type_1\": \"${Config_Type_1}\", \"location\": \"${Config_Location}\", \"status\": ${Config_Status}, \"time\": \"$(date '+%Y-%m-%d %H:%M:%S')\" }\n" - else - Config_JSON="${Config_JSON}{ \"ip\": \"${ip}\", \"name\": \"${Config_Name}\", \"type\": \"${Config_Type}\", \"type_1\": \"${Config_Type_1}\", \"location\": \"${Config_Location}\", \"status\": ${Config_Status}, \"time\": \"$(date '+%Y-%m-%d %H:%M:%S')\" },\n" - fi - fi -} -rand(){ - min=1000 - max=$((2000-$min+1)) - num=$(date +%s%N) - echo $(($num%$max+$min)) -} -Test(){ - GO - Get_Like - cd ${SSR_folder} - local_port=$(rand) - for((integer = 1; integer <= "${Like_num}"; integer++)) - do - Analysis_Config "${integer}" - Start_Client - Socks5_test - done - exit_GG -} -Test_add(){ - analysis_type="add" - GO - cd ${SSR_folder} - local_port=$(rand) - set_config_user - [[ $? == 2 ]] && Analysis_Config "1" - Start_Client - Socks5_test - exit_GG -} -Test_one(){ - List_SSRStatus - cd ${SSR_folder} - local_port=$(rand) - while true - do - echo -e "请选择你要单独测试的账号序号" - stty erase '^H' && read -p "(默认取消):" Test_one_num - [[ -z "${Test_one_num}" ]] && echo "已取消..." && exit 1 - expr ${Test_one_num} + 0 &>/dev/null - if [[ $? -eq 0 ]]; then - if [[ ${Test_one_num} -ge 1 ]] && [[ ${Test_one_num} -le ${Like_num} ]]; then - analysis_type="add" && Analysis_Config "${Test_one_num}" - Start_Client - Socks5_test - break - else - echo -e "${Error} 请输入正确的数字!" - fi - else - echo -e "${Error} 请输入正确的数字!" - fi - done -} -View_log(){ - [[ ! -e ${log_file} ]] && echo -e "${Error} 找不到 日志文件!(${log_file})" - cat "${log_file}" -} -Set_SSRStatus(){ - check_installed_server_status - echo && echo -e " 你要做什么? - - ${Green_font_prefix} 1.${Font_color_suffix} 添加 账号配置 - ${Green_font_prefix} 2.${Font_color_suffix} 删除 账号配置 - ${Green_font_prefix} 3.${Font_color_suffix} 修改 账号配置 -———————— - ${Green_font_prefix} 4.${Font_color_suffix} 启用/禁用 账号配置 - 注意:添加/修改/删除 账号配置后,不会立即更新,需要自动(定时)/手动检测一次所有账号,网页才会更新 !" && echo - stty erase '^H' && read -p "(默认: 取消):" server_num - [[ -z "${server_num}" ]] && echo "已取消..." && exit 1 - if [[ ${server_num} == "1" ]]; then - Add_SSRStatus - elif [[ ${server_num} == "2" ]]; then - Del_SSRStatus - elif [[ ${server_num} == "3" ]]; then - Modify_SSRStatus - elif [[ ${server_num} == "4" ]]; then - Modify_SSRStatus_disabled - else - echo -e "${Error} 请输入正确的数字[1-4]" && exit 1 - fi -} -List_SSRStatus(){ - Get_Like - echo -e "目前有 ${Like_num} 个账号配置\n$(echo -e "${Like}"|grep -n "#")" -} -Add_SSRStatus(){ - set_config_user - if [[ $? == 1 ]]; then - if [[ ${protocol} == "origin" ]] && [[ ${obfs} == "plain" ]]; then - Like_base64=$(echo -n "${method}:${passwd}@${ip}:${port}"|base64|sed ':a;N;s/\n/ /g;ta'|sed 's/ //g;s/=//g') - Like="ss://"${Like_base64} - else - passwd_base64=$(echo -n "${passwd}"|base64|sed ':a;N;s/\n/ /g;ta'|sed 's/ //g;s/=//g') - Like_base64=$(echo -n "${ip}:${port}:${protocol}:${method}:${obfs}:${passwd_base64}"|base64|sed ':a;N;s/\n/ /g;ta'|sed 's/ //g;s/=//g') - Like="ssr://"${Like_base64} - fi - fi - set_config_name - set_config_location - Like="${Like}###${Config_Name}###${Config_Location}###false" - echo -e "${Like}" >> ${config_file} - if [[ $? == 0 ]]; then - echo -e "${Info} 添加成功 ! [${Like}]" - else - echo -e "${Error} 添加失败 ! [${Like}]" - fi -} -Del_SSRStatus(){ - List_SSRStatus - [[ ${Like_num} == 1 ]] && echo -e "${Error} 当前仅剩一个账号配置,无法删除 !" && exit 0 - while true - do - echo -e "请选择你要删除的账号序号" - stty erase '^H' && read -p "(默认取消):" Del_num - [[ -z "${Del_num}" ]] && echo "已取消..." && exit 1 - expr ${Del_num} + 0 &>/dev/null - if [[ $? -eq 0 ]]; then - if [[ ${Del_num} -ge 1 ]] && [[ ${Del_num} -le ${Like_num} ]]; then - sed -i "${Del_num}d" ${config_file} - if [[ $? == 0 ]]; then - echo -e "${Info} 删除成功 ! [${Del_num}]" - else - echo -e "${Error} 删除失败 ! [${Del_num}]" - fi - break - else - echo -e "${Error} 请输入正确的数字!" - fi - else - echo -e "${Error} 请输入正确的数字!" - fi - done -} -Modify_SSRStatus(){ - List_SSRStatus - while true - do - echo -e "请选择你要修改的账号序号" - stty erase '^H' && read -p "(默认取消):" Modify_num - [[ -z "${Modify_num}" ]] && echo "已取消..." && exit 1 - expr ${Modify_num} + 0 &>/dev/null - if [[ $? -eq 0 ]]; then - if [[ ${Modify_num} -ge 1 ]] && [[ ${Modify_num} -le ${Like_num} ]]; then - set_config_user - if [[ $? == 1 ]]; then - if [[ ${protocol} == "origin" ]] && [[ ${obfs} == "plain" ]]; then - Like_base64=$(echo -n "${method}:${passwd}@${ip}:${port}"|base64|sed ':a;N;s/\n/ /g;ta'|sed 's/ //g;s/=//g') - Like="ss://"${Like_base64} - else - passwd_base64=$(echo -n "${passwd}"|base64|sed ':a;N;s/\n/ /g;ta'|sed 's/ //g;s/=//g') - Like_base64=$(echo -n "${ip}:${port}:${protocol}:${method}:${obfs}:${passwd_base64}"|base64|sed ':a;N;s/\n/ /g;ta'|sed 's/ //g;s/=//g') - Like="ssr://"${Like_base64} - fi - fi - set_config_name - set_config_location - Like="${Like}###${Config_Name}###${Config_Location}###false" - sed -i "${Modify_num}d" ${config_file} - sed -i "${Modify_num}i\\${Like}" ${config_file} - if [[ $? == 0 ]]; then - echo -e "${Info} 修改成功 ! [${Like}]" - else - echo -e "${Error} 修改失败 ! [${Like}]" - fi - break - else - echo -e "${Error} 请输入正确的数字!" - fi - else - echo -e "${Error} 请输入正确的数字!" - fi - done -} -Modify_SSRStatus_disabled(){ - List_SSRStatus - while true - do - echo -e "请选择你要启用/禁用的账号序号" - stty erase '^H' && read -p "(默认取消):" Modify_num - [[ -z "${Modify_num}" ]] && echo "已取消..." && exit 1 - expr ${Modify_num} + 0 &>/dev/null - if [[ $? -eq 0 ]]; then - if [[ ${Modify_num} -ge 1 ]] && [[ ${Modify_num} -le ${Like_num} ]]; then - Config_old=$(echo -e "${Like}"|sed -n "${Modify_num}"p) - echo -e "${Config_old}" - Config_old_Disabled=$(echo -e "${Config_old}"|awk -F '###' '{print $4}') - Config_old=$(echo -e "${Config_old}"|awk -F "###${Config_old_Disabled}" '{print $1}') - echo -e "${Config_old_Disabled}\n${Config_old}" - if [[ ${Config_old_Disabled} == "true" ]]; then - Config_Disabled="false" - Like="${Config_old}###${Config_Disabled}" - else - Config_Disabled="true" - Like="${Config_old}###${Config_Disabled}" - fi - echo -e "${Config_Disabled}\n${Like}" - sed -i "${Modify_num}d" ${config_file} - sed -i "${Modify_num}i\\${Like}" ${config_file} - if [[ $? == 0 ]]; then - echo -e "${Info} 修改成功 ! [账号状态为: ${Config_Disabled}]" - else - echo -e "${Error} 修改失败 ! [账号状态为: ${Config_Disabled}]" - fi - break - else - echo -e "${Error} 请输入正确的数字!" - fi - else - echo -e "${Error} 请输入正确的数字!" - fi - done -} -Installation_dependency(){ - if [[ ${release} == "centos" ]]; then - yum update - yum install -y unzip vim curl crond - [[ -z $(ls /usr/sbin/crond) ]] && echo -e "${Error} 依赖 crond 安装失败..." && exit 0 - else - apt-get update - apt-get install -y unzip vim curl cron - [[ -z $(ls /usr/sbin/cron) ]] && echo -e "${Error} 依赖 cron 安装失败..." && exit 0 - fi - [[ -z $(unzip --help) ]] && echo -e "${Error} 依赖 unzip 安装失败..." && exit 0 - [[ -z $(curl --help) ]] && echo -e "${Error} 依赖 curl 安装失败..." && exit 0 - cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime -} -Install_caddy(){ - echo -e "是否由脚本自动配置HTTP服务(在线监控网站)[Y/n]" - stty erase '^H' && read -p "(默认: Y 自动部署):" caddy_yn - [[ -z "$caddy_yn" ]] && caddy_yn="y" - if [[ "${caddy_yn}" == [Yy] ]]; then - Set_server - Set_server_port - if [[ ! -e "/usr/local/caddy/caddy" ]]; then - wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/caddy_install.sh - chmod +x caddy_install.sh - bash caddy_install.sh install - [[ ! -e "/usr/local/caddy/caddy" ]] && echo -e "${Error} Caddy安装失败,请手动部署,Web网页文件位置:${Web_file}" && exit 0 - else - echo -e "${Info} 发现Caddy已安装,开始配置..." - fi - if [[ ! -s "/usr/local/caddy/Caddyfile" ]]; then - cat > "/usr/local/caddy/Caddyfile"<<-EOF -http://${server_s}:${server_port_s} { - root ${Web_file} - timeouts none - gzip -} -EOF - /etc/init.d/caddy restart - else - echo -e "${Info} 发现 Caddy 配置文件非空,开始追加 ServerStatus 网站配置内容到文件最后..." - cat >> "/usr/local/caddy/Caddyfile"<<-EOF -http://${server_s}:${server_port_s} { - root ${Web_file} - timeouts none - gzip -} -EOF - /etc/init.d/caddy restart - fi - else - echo -e "${Info} 跳过 HTTP服务部署,请手动部署,Web网页文件位置:${Web_file} !" - fi -} -Download_SSRStatus(){ - cd "/usr/local" - wget -N --no-check-certificate "https://github.com/ToyoDAdoubi/SSRStatus/archive/master.zip" - [[ ! -e "master.zip" ]] && echo -e "${Error} SSRStatus 网页文件下载失败 !" && exit 1 - unzip master.zip && rm -rf master.zip - [[ ! -e "SSRStatus-master" ]] && echo -e "${Error} SSRStatus 网页文件解压失败 !" && exit 1 - mv SSRStatus-master SSRStatus - [[ ! -e "${Web_file}" ]] && echo -e "${Error} SSRStatus 网页文件文件夹重命名失败 !" && rm -rf SSRStatus-master && exit 1 -} -Install_Web(){ - [[ -e "${Web_file}" ]] && echo -e "${Error} 检测到 SSRStatus 网页文件已安装 !" && exit 1 - check_sys - echo -e "${Info} 开始安装/配置 依赖..." - Installation_dependency - echo -e "${Info} 开始部署HTTP服务(Caddy)..." - Install_caddy - echo -e "${Info} 开始下载/安装..." - Download_SSRStatus - echo -e "${Info} 开始配置定时任务..." - Set_crontab - echo -e "${Info} 所有步骤 安装完毕... 请打开本脚本并修改开头的 SSR_folder 变量引号内的ShadowsocksR子目录绝对路径,方可使用。" -} -Uninstall_Web(){ - check_installed_server_status - echo "确定要卸载 SSRStatus 网页文件(自动部署的Caddy并不会删除) ? [y/N]" - echo - stty erase '^H' && read -p "(默认: n):" unyn - [[ -z ${unyn} ]] && unyn="n" - if [[ ${unyn} == [Yy] ]]; then - /etc/init.d/caddy stop - Del_Crontab - rm -rf "${Web_file}" - echo && echo "SSRStatus 网页文件卸载完成 !" && echo - else - echo && echo "卸载已取消..." && echo - fi -} -Add_Crontab(){ - crontab -l > "$file/crontab.bak" - sed -i "/ssrstatus.sh/d" "$file/crontab.bak" - echo -e "\n${Crontab_time} /bin/bash $file/ssrstatus.sh t" >> "$file/crontab.bak" - crontab "$file/crontab.bak" - rm -r "$file/crontab.bak" - cron_config=$(crontab -l | grep "ssrstatus.sh") - if [[ -z ${cron_config} ]]; then - echo -e "${Error} 添加 Crontab 定时任务失败 !" && exit 1 - else - echo -e "${Info} 添加 Crontab 定时任务成功 !" - fi -} -Del_Crontab(){ - crontab -l > "$file/crontab.bak" - sed -i "/ssrstatus.sh/d" "$file/crontab.bak" - crontab "$file/crontab.bak" - rm -r "$file/crontab.bak" - cron_config=$(crontab -l | grep "ssrstatus.sh") - if [[ ! -z ${cron_config} ]]; then - echo -e "${Error} 删除 Crontab 定时任务失败 !" && exit 1 - else - echo -e "${Info} 删除 Crontab 定时任务成功 !" - fi -} -Update_Shell(){ - echo -e "当前版本为 [ ${sh_ver} ],开始检测最新版本..." - sh_new_ver=$(wget --no-check-certificate -qO- "https://softs.fun/Bash/ssrstatus.sh"|grep 'sh_ver="'|awk -F "=" '{print $NF}'|sed 's/\"//g'|head -1) && sh_new_type="softs" - [[ -z ${sh_new_ver} ]] && sh_new_ver=$(wget --no-check-certificate -qO- "https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ssrstatus.sh"|grep 'sh_ver="'|awk -F "=" '{print $NF}'|sed 's/\"//g'|head -1) && sh_new_type="github" - [[ -z ${sh_new_ver} ]] && echo -e "${Error} 检测最新版本失败 !" && exit 0 - if [[ ${sh_new_ver} != ${sh_ver} ]]; then - echo -e "发现新版本[ ${sh_new_ver} ],是否更新?[Y/n]" - stty erase '^H' && read -p "(默认: y):" yn - [[ -z "${yn}" ]] && yn="y" - if [[ ${yn} == [Yy] ]]; then - if [[ $sh_new_type == "softs" ]]; then - wget -N --no-check-certificate https://softs.fun/Bash/ssrstatus.sh && chmod +x ssrstatus.sh - else - wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ssrstatus.sh && chmod +x ssrstatus.sh - fi - echo -e "脚本已更新为最新版本[ ${sh_new_ver} ] !" - else - echo && echo " 已取消..." && echo - fi - else - echo -e "当前已是最新版本[ ${sh_new_ver} ] !" - fi -} -menu(){ -echo && echo -e " SSRStatus 一键安装管理脚本 ${Red_font_prefix}[v${sh_ver}]${Font_color_suffix} - -- Toyo | doub.io/shell-jc5 -- - - ${Green_font_prefix}0.${Font_color_suffix} 升级脚本 - ———————————— - ${Green_font_prefix}1.${Font_color_suffix} 安装 依赖及Web网页 - ${Green_font_prefix}2.${Font_color_suffix} 卸载 依赖及Web网页 -———————————— - ${Green_font_prefix}3.${Font_color_suffix} 测试 所有账号 - ${Green_font_prefix}4.${Font_color_suffix} 测试 单独账号 - ${Green_font_prefix}5.${Font_color_suffix} 测试 自定义账号 -———————————— - ${Green_font_prefix}6.${Font_color_suffix} 设置 配置信息 - ${Green_font_prefix}7.${Font_color_suffix} 查看 配置信息 - ${Green_font_prefix}8.${Font_color_suffix} 查看 运行日志 - ${Green_font_prefix}9.${Font_color_suffix} 设置 定时间隔 -————————————" && echo -if [[ -e ${Web_file} ]]; then - echo -e " 当前状态: Web网页 ${Green_font_prefix}已安装${Font_color_suffix}" -else - echo -e " 当前状态: Web网页 ${Red_font_prefix}未安装${Font_color_suffix}" -fi -echo -stty erase '^H' && read -p " 请输入数字 [0-9]:" num -case "$num" in - 0) - Update_Shell - ;; - 1) - Install_Web - ;; - 2) - Uninstall_Web - ;; - 3) - Test - ;; - 4) - Test_one - ;; - 5) - Test_add - ;; - 6) - Set_SSRStatus - ;; - 7) - List_SSRStatus - ;; - 8) - View_log - ;; - 9) - Set_crontab - ;; - *) - echo "请输入正确数字 [0-9]" - ;; -esac -} -action=$1 -if [[ ${1} == "t" ]]; then - Test -elif [[ ${1} == "a" ]]; then - Test_add -elif [[ ${1} == "o" ]]; then - Test_one -elif [[ ${1} == "log" ]]; then - View_log -else - menu -fi \ No newline at end of file diff --git a/ZBench-CN.sh b/ZBench-CN.sh new file mode 100644 index 0000000..3ceb8f3 --- /dev/null +++ b/ZBench-CN.sh @@ -0,0 +1,410 @@ +# Check if user is root +[ $(id -u) != "0" ] && { echo "${CFAILURE}Error: You must be root to run this script${CEND}"; exit 1; } + +# Check if wget installed +if [ ! -e '/usr/bin/wget' ]; then + echo "Error: wget command not found. You must be install wget command at first." + exit 1 +fi +read -p "请输入你的服务器提供商: " Provider + +# Check release +if [ -f /etc/redhat-release ]; then + release="centos" +elif cat /etc/issue | grep -Eqi "debian"; then + release="debian" +elif cat /etc/issue | grep -Eqi "ubuntu"; then + release="ubuntu" +elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then + release="centos" +elif cat /proc/version | grep -Eqi "debian"; then + release="debian" +elif cat /proc/version | grep -Eqi "ubuntu"; then + release="ubuntu" +elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then + release="centos" +fi + + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +SKYBLUE='\033[0;36m' +PLAIN='\033[0m' + +rm -rf /tmp/report && mkdir /tmp/report + +# Install locales + +if [ "${release}" != "centos" ]; then + apt-get update > /dev/null 2>&1 + apt-get -y install locales > /dev/null 2>&1 +fi + +# Install Virt-what +if [ ! -e '/usr/sbin/virt-what' ]; then + echo "Installing Virt-What......" + if [ "${release}" == "centos" ]; then + yum update > /dev/null 2>&1 + yum -y install virt-what > /dev/null 2>&1 + else + apt-get -y install virt-what > /dev/null 2>&1 + fi +fi + +echo "正在安装必要的依赖,请耐心等待..." + +# Install ca-certificates +echo "Installing ca-certificates......" +if [ "${release}" == "centos" ]; then + yum -y install ca-certificates > /dev/null 2>&1 +else + apt-get -y install ca-certificates > /dev/null 2>&1 +fi + +# Install uuid +echo "Installing uuid......" +if [ "${release}" == "centos" ]; then + yum -y install uuid > /dev/null 2>&1 +else + apt-get -y install uuid > /dev/null 2>&1 +fi + + +# Install curl +echo "Installing curl......" +if [ "${release}" == "centos" ]; then + yum -y install curl > /dev/null 2>&1 +else + apt-get -y install curl > /dev/null 2>&1 +fi + + +# Install Besttrace +if [ ! -e '/tmp/besttrace' ]; then + echo "Installing Besttrace......" + dir=$(pwd) + cd /tmp/ + wget -N --no-check-certificate https://raw.githubusercontent.com/FunctionClub/ZBench/master/besttrace > /dev/null 2>&1 + cd $dir +fi +chmod a+rx /tmp/besttrace + +# Check Python +if [ ! -e '/usr/bin/python' ]; then + echo "Installing Python......" + if [ "${release}" == "centos" ]; then + yum update > /dev/null 2>&1 + yum -y install python + else + apt-get update > /dev/null 2>&1 + apt-get -y install python + fi +fi + +# Install Speedtest +if [ ! -e '/tmp/speedtest.py' ]; then + echo "Installing SpeedTest......" + dir=$(pwd) + cd /tmp/ + wget -N --no-check-certificate https://raw.github.com/sivel/speedtest-cli/master/speedtest.py > /dev/null 2>&1 + cd $dir +fi +chmod a+rx /tmp/speedtest.py + + +# Install Zping-CN +if [ ! -e '/tmp/ZPing-CN.py' ]; then + echo "Installing ZPing-CN.py......" + dir=$(pwd) + cd /tmp/ + wget -N --no-check-certificate https://raw.githubusercontent.com/FunctionClub/ZBench/master/ZPing-CN.py > /dev/null 2>&1 + cd $dir +fi +chmod a+rx /tmp/ZPing-CN.py + +#"TraceRoute to Shanghai Telecom" +/tmp/besttrace 61.129.42.6 > /tmp/sht.txt 2>&1 & +#"TraceRoute to Shanghai Mobile" +/tmp/besttrace speedtest2.sh.chinamobile.com > /tmp/shm.txt 2>&1 & +#"TraceRoute to Shanghai Unicom" +/tmp/besttrace 210.22.80.1 > /tmp/shu.txt 2>&1 & +#"TraceRoute to Guangdong Telecom" +/tmp/besttrace 121.14.220.240 > /tmp/gdt.txt 2>&1 & +#"TraceRoute to Guangdong Mobile" +/tmp/besttrace 211.136.192.6 > /tmp/gdm.txt 2>&1 & +#"TraceRoute to Guangdong Unicom" +/tmp/besttrace 221.5.88.88 > /tmp/gdu.txt 2>&1 & + + + +get_opsy() { + [ -f /etc/redhat-release ] && awk '{print ($1,$3~/^[0-9]/?$3:$4)}' /etc/redhat-release && return + [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return + [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return +} + +next() { + printf "%-74s\n" "-" | sed 's/\s/-/g' +} + +speed_test() { + local speedtest=$(wget -4O /dev/null -T300 $1 2>&1 | awk '/\/dev\/null/ {speed=$3 $4} END {gsub(/\(|\)/,"",speed); print speed}') + local ipaddress=$(ping -c1 -n `awk -F'/' '{print $3}' <<< $1` | awk -F'[()]' '{print $2;exit}') + local nodeName=$2 + local latency=$(ping $ipaddress -c 3 | grep avg | awk -F / '{print $5}')" ms" + printf "${YELLOW}%-26s${GREEN}%-18s${RED}%-20s${SKYBLUE}%-12s${PLAIN}\n" "${nodeName}" "${ipaddress}" "${speedtest}" "${latency}" + + #Record Speed Data + echo ${ipaddress} >> /tmp/speed.txt + echo ${speedtest} >> /tmp/speed.txt + echo ${latency} >> /tmp/speed.txt +} + +speed() { + speed_test 'http://cachefly.cachefly.net/100mb.test' 'CacheFly' + speed_test 'http://speedtest.tokyo.linode.com/100MB-tokyo.bin' 'Linode, Tokyo, JP' + speed_test 'http://speedtest.singapore.linode.com/100MB-singapore.bin' 'Linode, Singapore, SG' + speed_test 'http://speedtest.london.linode.com/100MB-london.bin' 'Linode, London, UK' + speed_test 'http://speedtest.frankfurt.linode.com/100MB-frankfurt.bin' 'Linode, Frankfurt, DE' + speed_test 'http://speedtest.fremont.linode.com/100MB-fremont.bin' 'Linode, Fremont, CA' + speed_test 'http://speedtest.dal05.softlayer.com/downloads/test100.zip' 'Softlayer, Dallas, TX' + speed_test 'http://speedtest.sea01.softlayer.com/downloads/test100.zip' 'Softlayer, Seattle, WA' + speed_test 'http://speedtest.fra02.softlayer.com/downloads/test100.zip' 'Softlayer, Frankfurt, DE' + speed_test 'http://speedtest.sng01.softlayer.com/downloads/test100.zip' 'Softlayer, Singapore, SG' + speed_test 'http://speedtest.hkg02.softlayer.com/downloads/test100.zip' 'Softlayer, HongKong, CN' +} + +speed_test_cn(){ + if [[ $1 == '' ]]; then + temp=$(python /tmp/speedtest.py --share 2>&1) + is_down=$(echo "$temp" | grep 'Download') + if [[ ${is_down} ]]; then + local REDownload=$(echo "$temp" | awk -F ':' '/Download/{print $2}') + local reupload=$(echo "$temp" | awk -F ':' '/Upload/{print $2}') + local relatency=$(echo "$temp" | awk -F ':' '/Hosted/{print $2}') + local nodeName=$2 + + printf "${YELLOW}%-29s${GREEN}%-18s${RED}%-20s${SKYBLUE}%-12s${PLAIN}\n" "${nodeName}" "${reupload}" "${REDownload}" "${relatency}" + else + local cerror="ERROR" + fi + else + temp=$(python /tmp/speedtest.py --server $1 --share 2>&1) + is_down=$(echo "$temp" | grep 'Download') + if [[ ${is_down} ]]; then + local REDownload=$(echo "$temp" | awk -F ':' '/Download/{print $2}') + local reupload=$(echo "$temp" | awk -F ':' '/Upload/{print $2}') + local relatency=$(echo "$temp" | awk -F ':' '/Hosted/{print $2}') + temp=$(echo "$relatency" | awk -F '.' '{print $1}') + if [[ ${temp} -gt 1000 ]]; then + relatency=" 000.000 ms" + fi + local nodeName=$2 + + printf "${YELLOW}%-29s${GREEN}%-18s${RED}%-20s${SKYBLUE}%-12s${PLAIN}\n" "${nodeName}" "${reupload}" "${REDownload}" "${relatency}" + else + local cerror="ERROR" + fi + fi + + #Record Speed_cn Data + echo ${reupload} >> /tmp/speed_cn.txt + echo ${REDownload} >> /tmp/speed_cn.txt + echo ${relatency} >> /tmp/speed_cn.txt +} + +speed_cn() { + + speed_test_cn '12637' '襄阳电信' + speed_test_cn '3633' '上海电信' + speed_test_cn '4624' '成都电信' + speed_test_cn '4863' "西安电信" + speed_test_cn '5083' '上海联通' + speed_test_cn '5726' '重庆联通' + speed_test_cn '5192' "西安移动" + speed_test_cn '4665' '上海移动' + speed_test_cn '4575' '成都移动' + + rm -rf /tmp/speedtest.py +} + + +io_test() { + (LANG=C dd if=/dev/zero of=test_$$ bs=64k count=16k conv=fdatasync && rm -f test_$$ ) 2>&1 | awk -F, '{io=$NF} END { print io}' | sed 's/^[ \t]*//;s/[ \t]*$//' +} + +calc_disk() { + local total_size=0 + local array=$@ + for size in ${array[@]} + do + [ "${size}" == "0" ] && size_t=0 || size_t=`echo ${size:0:${#size}-1}` + [ "`echo ${size:(-1)}`" == "K" ] && size=0 + [ "`echo ${size:(-1)}`" == "M" ] && size=$( awk 'BEGIN{printf "%.1f", '$size_t' / 1024}' ) + [ "`echo ${size:(-1)}`" == "T" ] && size=$( awk 'BEGIN{printf "%.1f", '$size_t' * 1024}' ) + [ "`echo ${size:(-1)}`" == "G" ] && size=${size_t} + total_size=$( awk 'BEGIN{printf "%.1f", '$total_size' + '$size'}' ) + done + echo ${total_size} +} + +cname=$( awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' ) +cores=$( awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo ) +freq=$( awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' ) +tram=$( free -m | awk '/Mem/ {print $2}' ) +uram=$( free -m | awk '/Mem/ {print $3}' ) +swap=$( free -m | awk '/Swap/ {print $2}' ) +uswap=$( free -m | awk '/Swap/ {print $3}' ) +up=$( awk '{a=$1/86400;b=($1%86400)/3600;c=($1%3600)/60} {printf("%d days, %d hour %d min\n",a,b,c)}' /proc/uptime ) +load=$( w | head -1 | awk -F'load average:' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//' ) +opsy=$( get_opsy ) +arch=$( uname -m ) +lbit=$( getconf LONG_BIT ) +kern=$( uname -r ) +ipv6=$( wget -qO- -t1 -T2 ipv6.icanhazip.com ) +disk_size1=($( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $2}' )) +disk_size2=($( LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $3}' )) +disk_total_size=$( calc_disk ${disk_size1[@]} ) +disk_used_size=$( calc_disk ${disk_size2[@]} ) + + +clear +next +echo -e "CPU 型号 : ${SKYBLUE}$cname${PLAIN}" +echo -e "CPU 核心数 : ${SKYBLUE}$cores${PLAIN}" +echo -e "CPU 频率 : ${SKYBLUE}$freq MHz${PLAIN}" +echo -e "总硬盘大小 : ${SKYBLUE}$disk_total_size GB ($disk_used_size GB Used)${PLAIN}" +echo -e "总内存大小 : ${SKYBLUE}$tram MB ($uram MB Used)${PLAIN}" +echo -e "SWAP大小 : ${SKYBLUE}$swap MB ($uswap MB Used)${PLAIN}" +echo -e "开机时长 : ${SKYBLUE}$up${PLAIN}" +echo -e "系统负载 : ${SKYBLUE}$load${PLAIN}" +echo -e "系统 : ${SKYBLUE}$opsy${PLAIN}" +echo -e "架构 : ${SKYBLUE}$arch ($lbit Bit)${PLAIN}" +echo -e "内核 : ${SKYBLUE}$kern${PLAIN}" +echo -ne "虚拟化平台 : " +virtua=$(virt-what) 2>/dev/null + +if [[ ${virtua} ]]; then + echo -e "${SKYBLUE}$virtua${PLAIN}" +else + echo -e "${SKYBLUE}No Virt${PLAIN}" +fi + + +next +io1=$( io_test ) +echo -e "硬盘I/O (第一次测试) : ${YELLOW}$io1${PLAIN}" +io2=$( io_test ) +echo -e "硬盘I/O (第二次测试) : ${YELLOW}$io2${PLAIN}" +io3=$( io_test ) +echo -e "硬盘I/O (第三次测试) : ${YELLOW}$io3${PLAIN}" +next + +##Record All Test data +rm -rf /tmp/info.txt +touch /tmp/info.txt +echo $cname >> /tmp/info.txt +echo $cores >> /tmp/info.txt +echo $freq MHz >> /tmp/info.txt +echo "$disk_total_size GB ($disk_used_size GB 已使用) ">> /tmp/info.txt +echo "$tram MB ($uram MB 已使用) ">> /tmp/info.txt +echo "$swap MB ($uswap MB 已使用)" >> /tmp/info.txt +echo $up >> /tmp/info.txt +echo $load >> /tmp/info.txt +echo $opsy >> /tmp/info.txt +echo "$arch ($lbit 位) ">> /tmp/info.txt +echo $kern >> /tmp/info.txt +echo $virtua >> /tmp/info.txt +echo $io1 >> /tmp/info.txt +echo $io2 >> /tmp/info.txt +echo $io3 >> /tmp/info.txt +AKEY=$( uuid ) + +printf "%-30s%-20s%-24s%-12s\n" "节点名称" "IP地址" "下载速度" "延迟" +speed && next +printf "%-30s%-22s%-24s%-12s\n" "节点名称" "上传速度" "下载速度" "延迟" +speed_cn && next +python /tmp/ZPing-CN.py +next + +NetCFspeec=$( sed -n "2p" /tmp/speed.txt ) +NetCFping=$( sed -n "3p" /tmp/speed.txt ) +NetLJPspeed=$( sed -n "5p" /tmp/speed.txt ) +NetLJPping=$( sed -n "6p" /tmp/speed.txt ) +NetLSGspeed=$( sed -n "8p" /tmp/speed.txt ) +NetLSGping=$( sed -n "9p" /tmp/speed.txt ) +NetLUKspeed=$( sed -n "11p" /tmp/speed.txt ) +NetLUKping=$( sed -n "12p" /tmp/speed.txt ) +NetLDEspeed=$( sed -n "14p" /tmp/speed.txt ) +NetLDEping=$( sed -n "15p" /tmp/speed.txt ) +NetLCAspeed=$( sed -n "17p" /tmp/speed.txt ) +NetLCAping=$( sed -n "18p" /tmp/speed.txt ) +NetSTXspeed=$( sed -n "20p" /tmp/speed.txt ) +NetSTXping=$( sed -n "21p" /tmp/speed.txt ) +NetSWAspeed=$( sed -n "23p" /tmp/speed.txt ) +NetSWAping=$( sed -n "24p" /tmp/speed.txt ) +NetSDEspeed=$( sed -n "26p" /tmp/speed.txt ) +NetSDEping=$( sed -n "27p" /tmp/speed.txt ) +NetSSGspeed=$( sed -n "29p" /tmp/speed.txt ) +NetSSGping=$( sed -n "30p" /tmp/speed.txt ) +NetSCNspeed=$( sed -n "32p" /tmp/speed.txt ) +NetSCNping=$( sed -n "33p" /tmp/speed.txt ) + + +NetUPST=$( sed -n "4p" /tmp/speed_cn.txt ) +NetDWST=$( sed -n "5p" /tmp/speed_cn.txt ) +NetPiST=$( sed -n "6p" /tmp/speed_cn.txt ) +NetUPCT=$( sed -n "7p" /tmp/speed_cn.txt ) +NetDWCT=$( sed -n "8p" /tmp/speed_cn.txt ) +NetPiCT=$( sed -n "9p" /tmp/speed_cn.txt ) +NetUPXT=$( sed -n "10p" /tmp/speed_cn.txt ) +NetDWXT=$( sed -n "11p" /tmp/speed_cn.txt ) +NetPiXT=$( sed -n "12p" /tmp/speed_cn.txt ) +NetUPSU=$( sed -n "13p" /tmp/speed_cn.txt ) +NetDWSU=$( sed -n "14p" /tmp/speed_cn.txt ) +NetPiSU=$( sed -n "15p" /tmp/speed_cn.txt ) +NetUPCU=$( sed -n "16p" /tmp/speed_cn.txt ) +NetDWCU=$( sed -n "17p" /tmp/speed_cn.txt ) +NetPiCU=$( sed -n "18p" /tmp/speed_cn.txt ) +NetUPXM=$( sed -n "19p" /tmp/speed_cn.txt ) +NetDWXM=$( sed -n "20p" /tmp/speed_cn.txt ) +NetPiXM=$( sed -n "21p" /tmp/speed_cn.txt ) +NetUPSM=$( sed -n "22p" /tmp/speed_cn.txt ) +NetDWSM=$( sed -n "23p" /tmp/speed_cn.txt ) +NetPiSM=$( sed -n "24p" /tmp/speed_cn.txt ) +NetUPCM=$( sed -n "25p" /tmp/speed_cn.txt ) +NetDWCM=$( sed -n "26p" /tmp/speed_cn.txt ) +NetPiCM=$( sed -n "27p" /tmp/speed_cn.txt ) +wget -N --no-check-certificate https://raw.githubusercontent.com/FunctionClub/ZBench/master/Generate.py >> /dev/null 2>&1 +python Generate.py && rm -rf Generate.py && cp /root/report.html /tmp/report/index.html +TSM=$( cat /tmp/shm.txt_table ) +TST=$( cat /tmp/sht.txt_table ) +TSU=$( cat /tmp/shu.txt_table ) +TGM=$( cat /tmp/gdm.txt_table ) +TGT=$( cat /tmp/gdt.txt_table ) +TGU=$( cat /tmp/gdu.txt_table ) +curl 'http://api.zbench.kirito.moe/action.php' --data "CPUmodel=$cname &CPUspeed=$freq MHz &CPUcore=$cores &HDDsize=$disk_total_size GB ($disk_used_size GB 已使用) &RAMsize=$tram MB ($uram MB 已使用)&SWAPsize=$swap MB ($uswap MB 已使用)&UPtime= $up&Arch=1&systemload=$load&OS= $opsy &Arch=$arch ($lbit 位)&Kernel=$kern &Virmethod=$virtua &IOa=$io1&IOb=$io2&IOc=$io3&NetCFspeec=$NetCFspeec&NetCFping=$NetCFping&NetLJPspeed=$NetLJPspeed&NetLJPping=$NetLJPping&NetLSGspeed=$NetLSGspeed&NetLSGping=$NetLSGping&NetLUKspeed=$NetLUKspeed&NetLUKping=$NetLUKping&NetLDEspeed=$NetLDEspeed&NetLDEping=$NetLDEping&NetLCAspeed=$NetLCAspeed&NetLCAping=$NetLCAping&NetSTXspeed=$NetSTXspeed&NetSTXping=$NetSTXping&NetSWAspeed=$NetSWAspeed&NetSWAping=$NetSWAping&NetSDEspeed=$NetSDEspeed&NetSDEping=$NetSDEping&NetSSGspeed=$NetSSGspeed&NetSSGping=$NetSSGping&NetSCNspeed=$NetSCNspeed&NetSCNping=$NetSCNping&NetUPST=$NetUPST&NetDWST=$NetDWST&NetPiST=$NetPiST&NetUPCT=$NetUPCT&NetDWCT=$NetDWCT&NetPiCT=$NetPiCT&NetUPXT=$NetUPXT&NetDWXT=$NetDWXT&NetPiXT=$NetPiXT&NetUPSU=$NetUPSU&NetDWSU=$NetDWSU&NetPiSU=$NetPiSU&NetUPCU=$NetUPCU&NetDWCU=$NetDWCU&NetPiCU=$NetPiCU&NetUPXM=$NetUPXM&NetDWXM=$NetDWXM&NetPiXM=$NetPiXM&NetUPSM=$NetUPSM&NetDWSM=$NetDWSM&NetPiSM=$NetPiSM&NetUPCM=$NetUPCM&NetDWCM=$NetDWCM&NetPiCM=$NetPiCM&TSM=$TSM&TST=$TST&TSU=$TSU&TGM=$TGM&TGT=$TGT&TGU=$TGU&AKEY=$AKEY&Provider=$Provider" +IKEY=$(curl "http://api.zbench.kirito.moe/getkey.php?AKEY=$AKEY" 2>/dev/null) +echo "在线查看测评报告:https://zbench.kirito.moe/record-cn.php?IKEY=$IKEY" +echo "您的测评报告已保存在 /root/report.html" + +# If use simple http server +while :; do echo + read -p "你想现在查看您的测评报告吗? [y/n]: " ifreport + if [[ ! $ifreport =~ ^[y,n]$ ]]; then + echo "输入错误! 请确保你输入的是 'y' 或者 'n'" + else + break + fi +done + +if [[ $ifreport == 'y' ]];then + echo "" + myip=`curl -m 10 -s http://members.3322.org/dyndns/getip` + echo "访问 http://${myip}:8001/index.html 查看您的测试报告,按 Ctrl + C 退出" + cd /tmp/report + python -m SimpleHTTPServer 8001 + iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8001 -j ACCEPT +fi diff --git a/dev.sh b/dev.sh index 47000d4..23ab0e6 100644 --- a/dev.sh +++ b/dev.sh @@ -1,18 +1,84 @@ #!/bin/bash export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +#Check OS +if [ -n "$(grep 'Aliyun Linux release' /etc/issue)" -o -e /etc/redhat-release ];then + OS=CentOS + [ -n "$(grep ' 7\.' /etc/redhat-release)" ] && CentOS_RHEL_version=7 + [ -n "$(grep ' 6\.' /etc/redhat-release)" -o -n "$(grep 'Aliyun Linux release6 15' /etc/issue)" ] && CentOS_RHEL_version=6 + [ -n "$(grep ' 5\.' /etc/redhat-release)" -o -n "$(grep 'Aliyun Linux release5' /etc/issue)" ] && CentOS_RHEL_version=5 +elif [ -n "$(grep 'Amazon Linux AMI release' /etc/issue)" -o -e /etc/system-release ];then + OS=CentOS + CentOS_RHEL_version=6 +elif [ -n "$(grep bian /etc/issue)" -o "$(lsb_release -is 2>/dev/null)" == 'Debian' ];then + OS=Debian + [ ! -e "$(which lsb_release)" ] && { apt-get -y update; apt-get -y install lsb-release; clear; } + Debian_version=$(lsb_release -sr | awk -F. '{print $1}') +elif [ -n "$(grep Deepin /etc/issue)" -o "$(lsb_release -is 2>/dev/null)" == 'Deepin' ];then + OS=Debian + [ ! -e "$(which lsb_release)" ] && { apt-get -y update; apt-get -y install lsb-release; clear; } + Debian_version=$(lsb_release -sr | awk -F. '{print $1}') +elif [ -n "$(grep Ubuntu /etc/issue)" -o "$(lsb_release -is 2>/dev/null)" == 'Ubuntu' -o -n "$(grep 'Linux Mint' /etc/issue)" ];then + OS=Ubuntu + [ ! -e "$(which lsb_release)" ] && { apt-get -y update; apt-get -y install lsb-release; clear; } + Ubuntu_version=$(lsb_release -sr | awk -F. '{print $1}') + [ -n "$(grep 'Linux Mint 18' /etc/issue)" ] && Ubuntu_version=16 +else + echo "Does not support this OS, Please contact the author! " + kill -9 $$ +fi + #Check Root [ $(id -u) != "0" ] && { echo "Error: You must be root to run this script"; exit 1; } +AutoIptables(){ + rsum=`date +%s%N | md5sum | head -c 6` + echo "使用前请注意,该功能会重置防火墙配置,已有连接可能会被中断。" + echo -e "在下面输入\e[31;49m $rsum \e[0m表示您已知晓风险并同意继续" + read readsum + if [[ ${readsum} == ${rsum} ]];then + netstat -anlt | awk '{print $4}' | sed -e '1,2d' | awk -F : '{print $NF}' | sort -n | uniq >> ./port.conf + bash /usr/local/SSR-Bash-Python/iptables2.sh + if [[ ${OS} =~ ^Ubuntu$|^Debian$ ]];then + iptables-restore < /etc/iptables.up.rules + for port in `cat ./port.conf`; do iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport $port -j ACCEPT ; done + for port in `cat ./port.conf`; do iptables -I INPUT -m state --state NEW -m udp -p udp --dport $port -j ACCEPT ; done + iptables-save > /etc/iptables.up.rules + fi + if [[ ${OS} == CentOS ]];then + if [[ $CentOS_RHEL_version == 7 ]];then + iptables-restore < /etc/iptables.up.rules + for port in `cat ./port.conf`; do iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport $port -j ACCEPT ; done + for port in `cat ./port.conf`; do iptables -I INPUT -m state --state NEW -m udp -p udp --dport $port -j ACCEPT ; done + iptables-save > /etc/iptables.up.rules + else + for port in `cat ./port.conf`; do iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport $port -j ACCEPT ; done + for port in `cat ./port.conf`; do iptables -I INPUT -m state --state NEW -m udp -p udp --dport $port -j ACCEPT ; done + /etc/init.d/iptables save + /etc/init.d/iptables restart + fi + fi + rm -f ./port.conf + else + echo "输入错误,退出!" + bash /usr/local/SSR-Bash-Python/dev.sh + exit 0 + fi +} echo "测试区域,请勿随意使用" echo "1.更新SSR-Bsah" echo "2.一键封禁BT下载,SPAM邮件流量(无法撤销)" echo "3.防止暴力破解SS连接信息 (重启后失效)" - +echo "4.布署ss-panel(有风险!)" +echo "5.BBR 控制台" +echo "6.锐速 控制台" +echo "7.LotServer 控制台" +echo "8.UML-LKL(OpenVZ-BBR)安装" +echo "9.防火墙增强配置(有风险)" while :; do echo read -p "请选择: " devc [ -z "$devc" ] && ssr && break - if [[ ! $devc =~ ^[1-3]$ ]]; then + if [[ ! $devc =~ ^[1-9]$ ]]; then echo "输入错误! 请输入正确的数字!" else break @@ -23,16 +89,252 @@ if [[ $devc == 1 ]];then rm -rf /usr/local/bin/ssr cd /usr/local/SSR-Bash-Python/ git pull - wget -q -N --no-check-certificate -O /usr/local/bin/ssr https://raw.githubusercontent.com/readour/AR-B-P-B/master/ssr + wget -N --no-check-certificate -O /usr/local/bin/ssr https://raw.githubusercontent.com/readour/AR-B-P-B/develop/ssr chmod +x /usr/local/bin/ssr echo 'SSR-Bash升级成功!' ssr fi if [[ $devc == 2 ]];then - wget -4qO- softs.pw/Bash/Get_Out_Spam.sh|bash + wget -q -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/ban_iptables.sh && chmod +x ban_iptables.sh && bash ban_iptables.sh banall + rm -rf ban_iptables.sh fi if [[ $devc == 3 ]];then nohup tail -F /usr/local/shadowsocksr/ssserver.log | python autoban.py >log 2>log & -fi \ No newline at end of file +fi + +if [[ $devc == 4 ]];then + #代码来自:https://91vps.us/2017/08/24/ss-panel-v3-mod/ + rsum=`date +%s%N | md5sum | head -c 6` + echo "您即将部署ss-panel,整个过程时间较长,并且存在风险,请保证你的系统纯净" + echo "为避免意外断线导致安装中断,推荐在screen中运行" + echo "安装脚本非本人所写,来源:https://github.com/mmmwhy/ss-panel-and-ss-py-mu/blob/master/ss-panel-v3-mod.sh" + echo "默认账号:91vps 默认密码:91vps" + echo -e "在下面输入\e[31;49m $rsum \e[0m表示您已知晓风险并同意安装,输入其它内容将退出安装!" + read -n 6 -p "请输入: " choise + if [[ $choise == $rsum ]];then + wget -q -N --no-check-certificate https://raw.githubusercontent.com/mmmwhy/ss-panel-and-ss-py-mu/master/ss-panel-v3-mod.sh && chmod +x ss-panel-v3-mod.sh && bash ss-panel-v3-mod.sh + else + echo "输入错误,安装退出!" + sleep 2s + ssr + fi +fi +bbrcheck(){ +cd /usr/loca/SSR-Bash-Python +#GitHub:https://github.com/ToyoDAdoubi +if [[ ! -e bbr.sh ]]; then + echo "没有发现 BBR脚本,开始下载..." + if ! wget -N --no-check-certificate https://raw.githubusercontent.com/ToyoDAdoubi/doubi/master/bbr.sh; then + echo "BBR 脚本下载失败 !" && exit 1 + else + echo "BBR 脚本下载完成 !" + chmod +x bbr.sh + fi +fi +} +if [[ $devc == 5 ]];then + [[ $OS = "CentOS" ]] && echo "本脚本不支持 CentOS系统 BBR !" && exit 1 + echo "你要做什么?" + echo "1.安装 BBR" + echo "————————" + echo "2.启动 BBR" + echo "3.停止 BBR" + echo "4.查看 BBR 状态" + echo "" + while :; do echo + read -p "请选择: " ubbr + [ -z "$ubbr" ] && ssr && break + if [[ ! $ubbr =~ ^[1-4]$ ]]; then + echo "输入错误! 请输入正确的数字!" + else + break + fi + done + if [[ $ubbr == 1 ]];then + rsum=`date +%s%N | md5sum | head -c 6` + echo " [安装前 请注意]" + echo "1. 安装开启BBR,需要更换内核,存在更换失败等风险(重启后无法开机)" + echo "2. 本脚本仅支持 Debian / Ubuntu 系统更换内核,OpenVZ和Docker 不支持更换内核" + echo "3. Debian 更换内核过程中会提示 [ 是否终止卸载内核 ] ,请选择 NO " + echo "" + echo -e "在下面输入\e[31;49m $rsum \e[0m表示您已知晓风险并同意安装,输入其它内容将退出安装!" + read -n 6 -p "请输入: " choise + if [[ $choise == $rsum ]];then + bbrcheck + bash bbr.sh + else + echo "输入错误,安装退出!" + sleep 2s + ssr + fi + fi + if [[ $ubbr == 2 ]];then + bbrcheck + bash bbr.sh start + fi + if [[ $ubbr == 3 ]];then + bbrcheck + bash bbr.sh stop + fi + if [[ $ubbr == 4 ]];then + bbrcheck + bash bbr.sh status + fi +fi +install_rz(){ + [[ -e /serverspeeder/bin/serverSpeeder.sh ]] && echo "锐速(Server Speeder) 已安装 !" && ssr + cd /usr/local/SSR-Bash-Python + #借用91yun.rog的开心版锐速 + wget -N --no-check-certificate https://raw.githubusercontent.com/91yun/serverspeeder/master/serverspeeder.sh + [[ ! -e "serverspeeder.sh" ]] && echo "锐速安装脚本下载失败 !" && ssr + bash serverspeeder.sh + sleep 2s + PID=`ps -ef |grep -v grep |grep "serverspeeder" |awk '{print $2}'` + if [[ ! -z ${PID} ]]; then + rm -rf /usr/local/SSR-Bash-Python/serverspeeder.sh + rm -rf /usr/local/SSR-Bash-Python/91yunserverspeeder + rm -rf /usr/local/SSR-Bash-Python/91yunserverspeeder.tar.gz + echo "锐速(Server Speeder) 安装完成 !" && exit 0 + else + echo "锐速(Server Speeder) 安装失败 !" && exit 1 + fi +} +if [[ $devc == 6 ]];then + echo "你要做什么?" + echo "1.安装 锐速" + echo "2.卸载 锐速" + echo "————————" + echo "3.启动 锐速" + echo "4.停止 锐速" + echo "5.重启 锐速" + echo "6.查看 锐速 状态" + echo "注意: 锐速和LotServer不能同时安装/启动!" + while :; do echo + read -p "请选择: " urz + [ -z "$urz" ] && ssr && break + if [[ ! $urz =~ ^[1-6]$ ]]; then + echo "输入错误! 请输入正确的数字!" + else + break + fi + done + if [[ $urz == 1 ]];then + install_rz + fi + if [[ $urz == 2 ]];then + [[ ! -e /serverspeeder/bin/serverSpeeder.sh ]] && echo "没有安装 锐速(Server Speeder),请检查 !" && exit 1 + echo "确定要卸载 锐速(Server Speeder)?[y/N]" && echo + stty erase '^H' && read -p "(默认: n):" unyn + [[ -z ${unyn} ]] && echo && echo "已取消..." && exit 1 + if [[ ${unyn} == [Yy] ]]; then + chattr -i /serverspeeder/etc/apx* + /serverspeeder/bin/serverSpeeder.sh uninstall -f + echo && echo "锐速(Server Speeder) 卸载完成 !" && echo + fi + fi + if [[ $urz == 3 ]];then + [[ ! -e /serverspeeder/bin/serverSpeeder.sh ]] && echo "没有安装 锐速(Server Speeder),请检查 !" && exit 1 + /serverspeeder/bin/serverSpeeder.sh start + /serverspeeder/bin/serverSpeeder.sh status + fi + if [[ $urz == 4 ]];then + [[ ! -e /serverspeeder/bin/serverSpeeder.sh ]] && echo "没有安装 锐速(Server Speeder),请检查 !" && exit 1 + /serverspeeder/bin/serverSpeeder.sh stop + fi + if [[ $urz == 5 ]];then + [[ ! -e /serverspeeder/bin/serverSpeeder.sh ]] && echo "没有安装 锐速(Server Speeder),请检查 !" && exit 1 + /serverspeeder/bin/serverSpeeder.sh restart + /serverspeeder/bin/serverSpeeder.sh status + fi + if [[ $urz == 6 ]];then + [[ ! -e /serverspeeder/bin/serverSpeeder.sh ]] && echo "没有安装 锐速(Server Speeder),请检查 !" && exit 1 + /serverspeeder/bin/serverSpeeder.sh status + fi +fi +install_ls(){ + [[ -e /appex/bin/serverSpeeder.sh ]] && echo "LotServer 已安装 !" && exit 1 + #Github: https://github.com/0oVicero0/serverSpeeder_Install + wget --no-check-certificate -qO /tmp/appex.sh "https://raw.githubusercontent.com/0oVicero0/serverSpeeder_Install/master/appex.sh" + [[ ! -e "/tmp/appex.sh" ]] && echo "LotServer 安装脚本下载失败 !" && exit 1 + bash /tmp/appex.sh 'install' + sleep 2s + PID=`ps -ef |grep -v grep |grep "appex" |awk '{print $2}'` + if [[ ! -z ${PID} ]]; then + echo "LotServer 安装完成 !" && exit 1 + else + echo "LotServer 安装失败 !" && exit 1 + fi +} +if [[ $devc == 7 ]];then + echo "你要做什么?" + echo "1.安装 LotServer" + echo "2.卸载 LotServer" + echo "————————" + echo "3.启动 LotServer" + echo "4.停止 LotServer" + echo "5.重启 LotServer" + echo "6.查看 LotServer 状态" + echo "注意: 锐速和LotServer不能同时安装/启动!" + while :; do echo + read -p "请选择: " uls + [ -z "$uls" ] && ssr && break + if [[ ! $uls =~ ^[1-6]$ ]]; then + echo "输入错误! 请输入正确的数字!" + else + break + fi + done + if [[ $uls == 1 ]];then + install_ls + fi + if [[ $uls == 2 ]];then + echo "确定要卸载 LotServer?[y/N]" && echo + stty erase '^H' && read -p "(默认: n):" unyn + [[ -z ${unyn} ]] && echo && echo "已取消..." && exit 1 + if [[ ${unyn} == [Yy] ]]; then + wget --no-check-certificate -qO /tmp/appex.sh "https://raw.githubusercontent.com/0oVicero0/serverSpeeder_Install/master/appex.sh" && bash /tmp/appex.sh 'uninstall' + echo && echo "LotServer 卸载完成 !" && echo + fi + fi + if [[ $uls == 3 ]];then + [[ ! -e /appex/bin/serverSpeeder.sh ]] && echo "没有安装 LotServer,请检查 !" && exit 1 + /appex/bin/serverSpeeder.sh start + /appex/bin/serverSpeeder.sh status + fi + if [[ $uls == 4 ]];then + [[ ! -e /appex/bin/serverSpeeder.sh ]] && echo "没有安装 LotServer,请检查 !" && exit 1 + /appex/bin/serverSpeeder.sh stop + fi + if [[ $uls == 5 ]];then + [[ ! -e /appex/bin/serverSpeeder.sh ]] && echo "没有安装 LotServer,请检查 !" && exit 1 + /appex/bin/serverSpeeder.sh restart + /appex/bin/serverSpeeder.sh status + fi + if [[ $uls == 6 ]];then + [[ ! -e /appex/bin/serverSpeeder.sh ]] && echo "没有安装 LotServer,请检查 !" && exit 1 + /appex/bin/serverSpeeder.sh status + fi +fi +if [[ $devc == 8 ]];then + cd /usr/local/SSR-Bash-Python + if [[ -e /root/lkl/run.sh ]];then + echo "你已安装过LKL" + else + echo "开始安装LKL" + wget -q -N --no-check-certificate https://raw.githubusercontent.com/Huiaini/UML-LKL/master/lkl-install.sh && bash lkl-install.sh + rm -f lkl-install.sh + fi + if [[ -d $PWD/uml-ssr-64 ]];then + echo "你已安装过UML" + else + echo "开始安装UML" + wget -q -N --no-check-certificate https://raw.githubusercontent.com/Huiaini/UML-LKL/master/uml.sh && bash uml.sh + fi +fi +if [[ $devc == 9 ]];then + AutoIptables + bash /usr/local/SSR-Bash-Python/dev.sh + exit 0 +fi diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index f0f7e43..0000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -ssr.fdos.xin \ No newline at end of file diff --git a/docs/QA.html b/docs/QA.html deleted file mode 100644 index 259264c..0000000 --- a/docs/QA.html +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - -AR-B-P-B常用问答界面 - - - - - -
-

AR-B-P-B 常见问题

-
- -
-
-
我该如何安装这个脚本?
-
-

在本项目的GitHub主页中提供了安装命令,你只需要选择你需要安装的版本(标准版/开发版),之后使用ssh登录到你的服务器执行对应的指令,然后根据提示操作就行,没有任何难度!

-
-
标准版和开发版有什么区别?
-
-

标准版的优化较少,基本上为“雨落”大神的原版,没有做太多修改,也较为完善;开发版即为我的魔改版,功能较多,推荐使用,但是由于开发周期比较短,可能难免会出现漏洞,欢迎反馈到stackzhao@gmail.com或者报告信息到官方issues里,我将迅速修复!

-

当然,如果你安装了开发版之后就后悔了,脚本内给了你吃后悔药的机会,只需要在程序里进入 程序管理->切换到普通版 同样的如果想从标准版升级到开发版也是如此!

-
-
我是否可以通过原版升级到你的版本呢?
-
-

答案当然是可以的,而且可以为你保留你之前的用户数据,同样很简单,你只需要使用本项目的GitHub主页中提供的安装命令,安装即可,需要注意的是,当安装脚本询问你“是否从其它版本迁移而来”时,迅速按下Y键,否则,可能会安装失败。不过安装失败了也不要紧,回过头来,重新来过就是.

-
-
我的这台主机到期了,我要怎样迅速迁移到另外一台主机呢?
-
-

哈。我考虑到了,你只需要在程序里进入 程序管理->备份配置 对数据进行备份,然后使用WinScp工具,连接到你的服务器,进入/root/backup中,将里面的ssrconf.tar.gz文件复制到你的电脑上,用同样的方法再将其复制到另一台主机的/root/backup文件夹里(如果不存在,可以建立该文件夹),然后通过常规的方法安装到开发版,再在程序里进入 程序管理->还原配置 ,按默认还原就行,防火墙全部为你搞定。

-

当然此功能也不是只为了此,没事备份一下,防止意外!!

-
-
我能不能让ShadowsocksR在出问题时自动重启呢?
-
-

可以的,你只需要在安装的时候设置了“服务器自动巡检”功能,错过了?没关系,你可以在 服务器控制->服务器自动巡检系统 中重新配置后再启动服务就行。

-
-
我能不能使用此脚本配置单端口多用户?
-
-

这个是不能的哦,因为你一旦配置了单端口多用户,那么现在的多端口多用户脚本将会没有任何卵用,真的想这样的话,你可以参照破娃的博客进行配置(什么?上不去?麻烦先挂下代理好吧)

-
-
写在最后!
-
-

请仔细阅读本项目的github主页,它足矣解决你的大多数问题。还有,不管任何时候,Google都是最好的老师,善用搜索引擎,如果搜索引擎无法解决你的问题,欢迎发邮件到stackzhao@gmail.com中,如果不知道怎么提问,请先阅读:提问的智慧再发邮件,任何本文档提到的问题以及官方主页可以解决的问题一概不予回复!请谅解!!

-
-
-
- - - - - - \ No newline at end of file diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index c741881..0000000 --- a/docs/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-slate \ No newline at end of file diff --git a/docs/css/reset.css b/docs/css/reset.css deleted file mode 100644 index 896592e..0000000 --- a/docs/css/reset.css +++ /dev/null @@ -1,8 +0,0 @@ -html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{ - margin: 0; - padding: 0; - border: 0; - vertical-align: baseline; - font-family: inherit; - font-size: 100%; -}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0} diff --git a/docs/css/style.css b/docs/css/style.css deleted file mode 100644 index 51ba05f..0000000 --- a/docs/css/style.css +++ /dev/null @@ -1,86 +0,0 @@ -@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,300,600); - -body { - background-color: #27AE60; -} - -.container { - width: 600px; - font: 14px/21px "Open Sans", Arial, sans-serif; - color: #666; - background-color: white; - padding: 20px; - margin: 40px auto; - border-radius: 5px; - -} - -p { - margin-bottom: 10px; - font-weight: bold; - font-size: 100%; -} - - -.hide { - display: none; -} - -dt { - font-size: 19px; - color: #669933; - margin-bottom: 20px; - margin-left: 26px; - cursor: pointer; -} - -/* Triangle list item */ -dt:before { - content: ""; - border-color: transparent #ccc; - border-style: solid; - border-width: 5px 0 5px 8px; - display: block; - height: 0; - width: 0; - left: -16px; - top: 17px; - position: relative; -} - -dd { - padding: 20px; - background: #FDFCFA; - border-radius: 5px; - border: 1px solid #F2EEE6; - margin: 20px 0 30px; - position: relative; -} - -/* Triangle in definition container */ -dd:after, dd:before { - bottom: 100%; - left: 6%; - border: solid transparent; - content: ""; - height: 0; - width: 0; - position: absolute; - pointer-events: none; -} - -dd:after { - border-color: rgba(136, 183, 213, 0); - border-color: transparent; - border-bottom-color: #FDFCFA; - border-width: 15px; - margin-left: -15px; -} - -dd:before { - border-color: rgba(194, 225, 245, 0); - border-color: transparent; - border-bottom-color: #F2EEE6; - border-width: 17px; - margin-left: -17px; -} diff --git a/docs/css/zzsc.css b/docs/css/zzsc.css deleted file mode 100644 index 66d96ff..0000000 --- a/docs/css/zzsc.css +++ /dev/null @@ -1,12 +0,0 @@ -body{ - background: #494A5F; - color: #D5D6E2; - font-weight: 500; - font-size: 1.05em; - font-family: "Microsoft YaHei","宋体","Segoe UI", "Lucida Grande", Helvetica, Arial,sans-serif, FreeSans, Arimo; -} -a{color: #2fa0ec;text-decoration: none;outline: none;} -a:hover,a:focus{ - color: #000000; -} -.center{text-align: center;} diff --git a/docs/googledb91dc19845aa061.html b/docs/googledb91dc19845aa061.html deleted file mode 100644 index 3e654cb..0000000 --- a/docs/googledb91dc19845aa061.html +++ /dev/null @@ -1 +0,0 @@ -google-site-verification: googledb91dc19845aa061.html diff --git a/docs/inde b/docs/inde deleted file mode 100644 index eda73f0..0000000 --- a/docs/inde +++ /dev/null @@ -1,8 +0,0 @@ - -404 Not Found - -

404 Not Found

-
nginx/1.6.2
- - - diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 0abbb45..0000000 --- a/docs/index.md +++ /dev/null @@ -1,147 +0,0 @@ -# SSR多用户管理脚本(基于官方mujson版本) -稳定版V1.7.2:[![Build Status](https://travis-ci.org/Readour/AR-B-P-B.svg?branch=master)](https://travis-ci.org/Readour/AR-B-P-B) [![Code Climate](https://codeclimate.com/github/Readour/AR-B-P-B/badges/gpa.svg)](https://codeclimate.com/github/Readour/AR-B-P-B) - -开发版V1.9.8:[![Build Status](https://travis-ci.org/Readour/AR-B-P-B.svg?branch=develop)](https://travis-ci.org/Readour/AR-B-P-B) - -## 介绍 ## - -一个Shell脚本,集成SSR多用户管理,流量限制,加密更改等基本操作。是一个基于ShadowsocksR官方的mujson的辅助脚本。方便用户操作,并且支持快速构建SSR服务环境。 - -- 请谨慎使用,出问题概不负责!!!! -- 如果发现脚本bug,请及时发issues,非常感谢 - -## 系统支持 ## -* Ubuntu 14 -* Ubuntu 16 -* Debian 7 -* Debian 8 -* CentOS 6 -* CentOS 7 - -## 功能 ## -- 全自动无人值守安装,服务端部署只需一条命令,您和SSR都是如此的优雅:) -- 一键开启、关闭SSR服务 -- 添加、删除、修改用户端口、密码和连接数限制 -- 支持傻瓜式用户添加,小白也可以用 -- 自由限制用户端口流量使用及端口网速 -- 自动修改防火墙规则 -- 自助修改SSR加密方式、协议、混淆等参数 -- 自动统计,方便查询每个用户端口的流量使用情况 -- 自动安装Libsodium库以支持Chacha20等加密方式 -- 支持用户二维码生成(仅开发版可用) -- 支持一键构建ss-panel-V3-mod,前端后端自动对接,无需额外操作(仅开发版可用) -- 傻瓜式的BBR、锐速、LotServer一键构建(有风险,仅开发版可用) -- 可自定义的服务器巡检,故障自动重启服务,确保链接稳定有效 -- 可对配置进行备份、还原,迁移服务器只需在新服务器上还原配置,无需麻烦设置 -- 允许针对不同用户设置帐号有效期,到期自动删除! - -不如看图: - -![](https://github.com/zyh001/zyh001.github.com/raw/master/images/now1.png) ![](https://github.com/zyh001/zyh001.github.com/raw/master/images/now2.png) - -未来可能的交互界面(吊下胃口): -![](https://github.com/zyh001/zyh001.github.com/raw/master/images/future.png) - -## 脚本安全性声明 ## -**本脚本采用Shell和Python语言编写,所有代码完全开源。不存在所谓的后台或挖矿代码,不会对您的任何信息进行上传,并在各个方面充分考虑到数据安全性。关于二维码生成过程是通过pip安装[第三方软件包](https://github.com/lincolnloop/python-qrcode),由第三方软件在服务器本地生成,生成的二维码链接也会自动销毁,不会上传任何信息。您的IP被封,或者您服务器出现不正常的负荷增高,与脚本本身没有任何关系,请您自行做好服务器安全维护工作,例如:不要使用弱密码、不要使用默认SSH端口,等等,防止被闲人爆破。_本着人与人之间的互信原则,请确认您相信我和我的脚本,否则请不要使用,不懂请不要喷,容易伤和气!!!_** - -## 缺点 ## -- 默认未设置开机启动 - -## 安装或更新到最新开发版(支持新特性,推荐使用) ## - wget -q -N --no-check-certificate https://raw.githubusercontent.com/Readour/AR-B-P-B/master/install.sh && bash install.sh develop - -## 安装&更新 ## - wget -q -N --no-check-certificate https://raw.githubusercontent.com/Readour/AR-B-P-B/master/install.sh && bash install.sh - -## 自检(没有卵用😝) ## - wget -q -N --no-check-certificate https://raw.githubusercontent.com/Readour/AR-B-P-B/master/self-check.sh && bash self-check.sh - -## 卸载 ## - wget -q -N --no-check-certificate https://raw.githubusercontent.com/Readour/AR-B-P-B/master/install.sh && bash install.sh uninstall - -## 离线安装 ## - #此方法可用于网络情况不好,导致缺少文件的情况.亦可下载该脚本,用于备份 - wget -q -N --no-check-certificate https://github.com/Readour/AR-B-P-B/releases/download/1.9.8/install.sh && bash install.sh - -## 客户端下载 ## -常用平台:[Android](https://github.com/shadowsocksrr/shadowsocksr-latest-bin-backup/raw/master/Shadowsocksr-android-3.4.0.5.apk)、[MacOS](https://github.com/qinyuhang/ShadowsocksX-NG-R/releases/download/1.4.3-R8/ShadowsocksX-NG-R8.dmg)、[Windows](https://github.com/Readour/ShadowsocksR-Csharp/releases/download/4.7.0/ShadowsocksR-4.7.0-win.CONCISE.7z)、[Linux](https://github.com/shadowsocks/shadowsocks-qt5/releases/download/v2.9.0/Shadowsocks-Qt5-x86_64.AppImage)、[OpenWrt/LEDE](https://github.com/bettermanbao/openwrt-shadowsocksR-libev-full/releases)、[iOS](https://github.com/Readour/breakwa11.github.io/raw/master/download/Shadowrocket%202.1.14.ipa) - -## 常见问题解答 ## -[戳这里~戳这里~戳这里](/QA.html) - -## 写在最后 ## -**关于该脚本的停更说明:**由于本人个人原因,没有精力继续对该脚本进行维护。但并不是不管,脚本现在已经非常臃肿,不会再新加入功能,如果发现版本bug,请及时发E-mail:,本人会尽快修复。此外,~~本人将在下个月进行V2ray一键脚本的开发~~,欢迎关注 - -## 赞助我 ## - - -__XMR(门罗币):__ - - 47LiGQz6VPGe23g1MtuPEcUAyki5A8BEpF6ViGv7WkQvGpaztSANVzzjXqrT3anyZ22j7DEE74GkbVcQFyH2nNiC3ea8z7g - -__ETH(以太坊):__ - -    [0x133743A8A6D33a04CdaC57C9c497094FC333b8eb](https://etherscan.io/address/0x133743A8A6D33a04CdaC57C9c497094FC333b8eb) - -__BTC(比特币):__ - -    [1KCSpD3XakscqgUXdCrTfr56xerrpY9kbw](https://blockchain.info/address/1KCSpD3XakscqgUXdCrTfr56xerrpY9kbw) - -__BCH(比特现金):__ - -    [1HsB88an66MYrCqb4qUhPWT2gwRfNi8QxL](https://blockdozer.com/insight/address/1HsB88an66MYrCqb4qUhPWT2gwRfNi8QxL) - -__Google Paly礼品卡:__ - - stackzhao@gmail.com - -__PayPal:__ - -[![给我捐赠](https://s1.ax1x.com/2017/12/23/jbclD.jpg)](https://paypal.me/stackzhao/5) - -__支付宝红包:__ - - - - - - - - - diff --git a/docs/js/clipboard.js b/docs/js/clipboard.js deleted file mode 100644 index 45221b9..0000000 --- a/docs/js/clipboard.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * clipboard.js v1.7.1 - * https://zenorocha.github.io/clipboard.js - * - * Licensed MIT © Zeno Rocha - */ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function i(a,c){if(!n[a]){if(!e[a]){var l="function"==typeof require&&require;if(!c&&l)return l(a,!0);if(r)return r(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var u=n[a]={exports:{}};e[a][0].call(u.exports,function(t){var n=e[a][1][t];return i(n||t)},u,u.exports,t,e,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function t(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function t(){var e=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px";var o=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=o+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,i.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function t(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function t(){this.selectedText=(0,i.default)(this.target),this.copyText()}},{key:"copyText",value:function t(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function t(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function t(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function t(){this.removeFake()}},{key:"action",set:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function t(){return this._action}},{key:"target",set:function t(e){if(void 0!==e){if(!e||"object"!==(void 0===e?"undefined":r(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function t(){return this._target}}]),t}();t.exports=c})},{select:5}],8:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if(void 0!==o)r(n,e("./clipboard-action"),e("tiny-emitter"),e("good-listener"));else{var a={exports:{}};r(a,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=a.exports}}(this,function(t,e,n,o){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function a(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function c(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function l(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}var s=i(e),u=i(n),f=i(o),d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},h=function(){function t(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===d(e.container)?e.container:document.body}},{key:"listenClick",value:function t(e){var n=this;this.listener=(0,f.default)(e,"click",function(t){return n.onClick(t)})}},{key:"onClick",value:function t(e){var n=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new s.default({action:this.action(n),target:this.target(n),text:this.text(n),container:this.container,trigger:n,emitter:this})}},{key:"defaultAction",value:function t(e){return l("action",e)}},{key:"defaultTarget",value:function t(e){var n=l("target",e);if(n)return document.querySelector(n)}},{key:"defaultText",value:function t(e){return l("text",e)}},{key:"destroy",value:function t(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],n="string"==typeof e?[e]:e,o=!!document.queryCommandSupported;return n.forEach(function(t){o=o&&!!document.queryCommandSupported(t)}),o}}]),e}(u.default);t.exports=p})},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8)}); diff --git a/docs/js/jquery-1.11.0.min.js b/docs/js/jquery-1.11.0.min.js deleted file mode 100644 index 046e93a..0000000 --- a/docs/js/jquery-1.11.0.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.11.0 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k="".trim,l={},m="1.11.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML="",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},z=b?function(a,b){if(a===b)return j=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=db.selectors={cacheLength:50,createPseudo:fb,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||db.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),t=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(t&&((l[s]||(l[s]={}))[a]=[u,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[u,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function sb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:z,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function E(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return E(a,"nextSibling")},prev:function(a){return E(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f -}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML="
a",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML="",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:l.htmlSerialize?[0,"",""]:[1,"X
","
"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?""!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=xb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(vb(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("