├── .travis.yml ├── LICENSE ├── README.md ├── create.php ├── css ├── addtohomescreen.css ├── bootstrap-theme.css ├── bootstrap-theme.css.map ├── bootstrap-theme.min.css ├── bootstrap.css ├── bootstrap.css.map ├── bootstrap.min.css ├── cover.css └── style.css ├── function ├── .htaccess └── sqllink.php ├── image.php ├── img ├── favicon.jpg └── noqrcode.png ├── index.html ├── js ├── bootstrap.js ├── bootstrap.min.js ├── fancybox │ ├── blank.gif │ ├── fancybox_loading.gif │ ├── fancybox_loading@2x.gif │ ├── fancybox_overlay.png │ ├── fancybox_sprite.png │ ├── fancybox_sprite@2x.png │ ├── helpers │ │ ├── fancybox_buttons.png │ │ ├── jquery.fancybox-buttons.css │ │ ├── jquery.fancybox-buttons.js │ │ ├── jquery.fancybox-media.js │ │ ├── jquery.fancybox-thumbs.css │ │ └── jquery.fancybox-thumbs.js │ ├── jquery.fancybox.css │ ├── jquery.fancybox.js │ └── jquery.fancybox.pack.js ├── html5shiv.js ├── html5shiv.min.js ├── jquery.fullbg.js ├── jquery.min.js ├── npm.js ├── pagination.js └── respond.min.js ├── killit.php ├── log.php ├── logdownload.php ├── qqbot ├── .htaccess ├── qqparking │ ├── HttpClient.py │ └── qqbot.py ├── qqrobot │ ├── HttpClient.py │ └── qqbot.py └── qzoneliker │ ├── HttpClient.py │ └── qqbot.py ├── qqparking.html ├── qqrobot.html ├── qwrap.sql ├── qzoneliker.html ├── status.php └── travis-ci.sh /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - '2.7' 4 | - '2.6' 5 | 6 | before_script: 7 | - sudo apt-get update 8 | - sudo apt-get install php5 9 | - mv function a 10 | 11 | script: 12 | - cd ./qqbot/qqparking 13 | - ls -l 14 | - python -m py_compile HttpClient.py 15 | - python -m py_compile qqbot.py 16 | - cd ../qqrobot 17 | - ls -l 18 | - python -m py_compile HttpClient.py 19 | - python -m py_compile qqbot.py 20 | - cd ../qzoneliker 21 | - ls -l 22 | - python -m py_compile HttpClient.py 23 | - python -m py_compile qqbot.py 24 | - cd ../../ 25 | - ls -l 26 | - sh travis-ci.sh ./ 27 | 28 | after_script: 29 | - cat myerrorfile 30 | 31 | - echo -e "zzy8200@gmail.com\nHELLO WORLD" > qqbot/qqparking/config.txt 32 | - echo -e "zzy8200@gmail.com" > qqbot/qqrobot/email.txt 33 | - echo -e "zzy8200@gmail.com" > qqbot/qzoneliker/email.txt 34 | - echo -e "1111111" > qqbot/qqrobot/groupfollow.txt 35 | 36 | - cd qqbot/qqparking 37 | - nohup python qqbot.py > ../../qqparking.txt & 38 | - cd ../qqrobot 39 | - nohup python qqbot.py > ../../qqrobot.txt & 40 | - cd ../qzoneliker 41 | - nohup python qqbot.py > ../../qzoneliker.txt & 42 | 43 | - cd ../../ 44 | - sleep 500s 45 | - echo "still waiting" 46 | - sleep 500s 47 | 48 | - cat qqparking.txt 49 | - cat qqrobot.txt 50 | - cat qzoneliker.txt 51 | 52 | - echo "qqparking log" 53 | - cd qqbot/qqparking && ls 54 | - cat log.log 55 | - echo "qqrobot log" 56 | - cd ../qqrobot && ls 57 | - cat log.log 58 | - echo "qzoneliker log" 59 | - cd ../qzoneliker && ls 60 | - cat log.log 61 | 62 | - killall python 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | QQ机器人WEB控制台 2 | ========= 3 | [![Build Status](https://travis-ci.org/zeruniverse/QBotWebWrap.svg)](https://travis-ci.org/zeruniverse/QBotWebWrap) 4 | [![Codacy Badge](https://api.codacy.com/project/badge/grade/ad8d129910134c2aa5591a99587aeb7c)](https://www.codacy.com/app/zzy8200/QBotWebWrap) 5 | ![Environment](https://img.shields.io/badge/PHP-5.2+-blue.svg) 6 | ![Environment](https://img.shields.io/badge/python-2.7-blue.svg) 7 | ![Environment](https://img.shields.io/badge/MySQL-required-ff69b4.svg) 8 | ![License](https://img.shields.io/github/license/zeruniverse/QBotWebWrap.svg) 9 | **该项目为QQRobot, QQParking, QzoneLiker提供一个网页版控制台,降低了使用门槛。** 10 | 有关[QQRobot](https://github.com/zeruniverse/QQRobot), [QQParking](https://github.com/zeruniverse/QQParking), [QzoneLiker](https://github.com/zeruniverse/QzoneLiker) 请见原项目。 11 | 用户输入基本参数后点击运行,然后等待网页中出现二维码用手机QQ(或安全中心)扫描登陆即可。该项目随以上三个项目一起更新,请不要使用RELEASE,直接下载[MASTER分支](https://github.com/zeruniverse/QBotWebWrap/archive/master.zip)使用。 12 | 13 | DEMO: [qqbot.jeffery.cc](http://qqbot.jeffery.cc) (仅供测试,自动定期杀死所有进程,限制10并发)   14 | 15 | This project is a Web-based console for [QQRobot](https://github.com/zeruniverse/QQRobot), [QQParking](https://github.com/zeruniverse/QQParking) and [QzoneLiker](https://github.com/zeruniverse/QzoneLiker). 16 | Users no longer need to type command in Terminal. They can now do it with a web browser! 17 | 18 | ## 如何使用(服务器端配置) 19 | + 确保安装有PHP 5.2+,MySQL与Python2.7(需要PyExecJS包)   20 | + 新建一个文件夹并将此作为网站根目录,将[QBotWebWrap](https://github.com/zeruniverse/QBotWebWrap/archive/master.zip)解压至文件夹内。 21 | + 新建一个数据库,导入[qwrap.sql](https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/master/qwrap.sql)。 22 | + 假设您刚刚建立的文件夹是qwrapweb. `cd qwrapweb` 23 | + 将里面的qqbot文件夹权限改为777 `sudo chmod -R 777 qqbot` 24 | + 将function/sqllink.php改为您自己的数据库用户名,数据库和密码。 `vim function/sqllink.php` 25 | 26 | 您可以改变qqbot文件夹内各项目的qqbot.py将tulingkey, SMTP邮箱等参数改为自己的参数。避免公用资源被耗尽引起错误。具体方案请参考3个原项目。 27 | 28 | ## 如何使用(客户端) 29 | 30 | + 打开浏览器,在主页选择需要启动的项目 31 | + 输入参数(如有必要),点击 RUN XXX 32 | + 浏览器稍候将自动跳转至状态页 33 | + 等待状态页QR CODE 出现 34 | + 用手机QQ/安全中心扫描QR CODE 35 | + 等待QR CODE消失 36 | + 记录SID并关闭页面(可用SID在首页重新进入状态页) 37 | + 使用SID从首页进入状态页检查状态,下载log 或结束自己的BOT(杀死进程) 38 | 39 | ## References 40 | + [QQParking](https://github.com/zeruniverse/QQParking): 自动回复私聊,留言转发邮箱 41 | + [QQRobot](https://github.com/zeruniverse/QQRobot): 群聊小黄鸡 42 | + [QzoneLiker](https://github.com/zeruniverse/QzoneLiker): QQ空间自动点赞机 43 | 44 | ## 可更改参数列表 45 | ### 必须更改 46 | + `function/sqllink.php` $dbname 数据库名 47 | + `function/sqllink.php` $dbusr 数据库用户名 48 | + `function/sqllink.php` $dbpwd 数据库密码 49 | 50 | ### 建议更改参数 51 | + `qqbot/(qqparking|qqrobot)/qqbot.py` tuling key (见references),smtp 服务器,用户名,密码 52 | + `qqbot/qzoneliker/qqbot.py` smtp 服务器,用户名,密码 53 | 54 | ### 可选更改参数 55 | + `qqbot/(qqparking|qqrobot|qzoneliker)/qqbot.py` 二维码重新获取次数 (默认6次获取均未扫描则结束程序) 56 | + `qqbot/qzoneliker/qqbot.py` QzoneLiker最多错误重试次数(默认5次) 57 | + `create.php` $MAXPROCESS 最多并行线程数(即最多挂几个机器人,默认10) 58 | + `sid`长度 (create.php `randomstr()`函数,默认6位大写字母,如大于10位请同时修改数据库SID的VARCHAR长度) 59 | + `qqbot/(qqparking|qqrobot)/qqbot.py` 轮询最多失败次数限制,默认5次 60 | 61 | ## 运行截图 62 | + 输入参数页面(以QQRobot举例) 63 | capture111 64 | 65 | + 点击运行(绿色按钮)后页面 (二维码获取中) 66 | capture222 67 | 68 | + 二维码成功获取后页面(获取二维码约需要5秒钟) 69 | capture333 70 | 71 | + 扫描二维码并成功登陆后,二维码消失,此时可以关闭页面 72 | capture444 73 | 74 | + DOWNLOAD LOG可下载完整LOG 75 | capture555 76 | 77 | ## 可扩展性/二次开发 78 | `qqbot`文件夹内各项目请参考References 79 | `create.php`是主要程序,负责产生一个进程ID,将对应的项目文件夹(qqbot|qqparking|qzoneliker)拷贝到这个ID命名的文件夹内,然后把用户输入的参数写进配置文件。最后执行shell命令启动python脚本并获取PID存入数据库。create.php创建新进程前会检查数据库内所有PID,并删除已经停止运行的PID,同时删除对应文件夹。如果删除后数据库内进程数量大于$MAXPROCESS,则拒绝添加线程请求 80 | `log.php` & `logdownload.php` 根据id找到qqbot/$id/log.log,并输出 81 | `image.php`根据id找到qqbot/$id/v.png,并输出 82 | `killit.php`杀死sid对应的进程 83 | 数据库中process表存有`id`,`pid`,`sid`。其中`pid`是对应BOT的进程号,`id`对应的是进程编号(对应文件夹名),`sid`是与前端交互的唯一标识码,用于解决`id`容易猜测的问题。用户不会得到`id`,只会得到`sid`。 84 | 85 | ### 举例:添加用户登录功能,限制每个用户最多只能开两个BOT 86 | + 数据库中加入user表,做好注册登陆模块 87 | + process表中加入user字段,将每个process对应到user 88 | + `create.php`检查该user是否超过限制,如果不是则创建进程时将user id同时写入process表对应的行 89 | + `status.php killit.php image.php log.php logdownload.php`检查SID同时必须检查该SID对应的行的user id与session里的user id是否一致 90 | + `index.html`改为`index.php`,输出数据库中该USER已经执行的BOT状态链接 91 | -------------------------------------------------------------------------------- /create.php: -------------------------------------------------------------------------------- 1 | read()){ 53 | if(($entry!='.')&&($entry!='..')){ 54 | if(is_dir($source."/".$entry)){ 55 | dcopy($source."/".$entry,$destination."/".$entry); 56 | } 57 | else{ 58 | copy($source."/".$entry,$destination."/".$entry); 59 | } 60 | } 61 | } 62 | return 1; 63 | } 64 | function delete_old_process($link){ 65 | $ret=sqlquery('SELECT * FROM `process` where 1',$link); 66 | while ($i = $ret->fetch(PDO::FETCH_ASSOC)){ 67 | if (!pstatus($i['pid'])){ 68 | sqlexec('DELETE FROM `process` where pid=?',array($i['pid']),$link); 69 | deldir('qqbot/'.$i['id']); 70 | } 71 | } 72 | } 73 | require_once('function/sqllink.php'); 74 | if(!isset($_POST['type'])) die('{"retcode":999,"msg":"INCOMPLETE POST DATA"}'); 75 | $link=sqllink(); 76 | if(!$link) die('{"retcode":999,"reason":"DATABASE ERROR"}'); 77 | delete_old_process($link); 78 | $res=sqlquery('SELECT count(*) FROM `process`',$link); 79 | $result=$res->fetch(PDO::FETCH_NUM); 80 | if((int)($result[0])>$MAXPROCESS) die('{"retcode":9,"msg":"TOO MANY simultaneous process. Try again later!"}');; 81 | 82 | if(!$link->beginTransaction()) die('{"retcode":999,"reason":"DATABASE ERROR"}'); 83 | $res=sqlquery('SELECT max(`id`) FROM `process`',$link); 84 | $result=$res->fetch(PDO::FETCH_NUM); 85 | $maxnum=($result==FALSE)?0:(int)($result[0]); 86 | $newid=$maxnum+1; 87 | 88 | switch ($_POST['type']) { 89 | case 'qzoneliker': 90 | if (dcopy('qqbot/qzoneliker', 'qqbot/'.$newid)==0) {$link->rollBack(); die('{"retcode":999,"msg":"UNABLE TO CREATE FOLDER!"}');} 91 | $myfile = fopen('qqbot/'.$newid."/email.txt", "w"); 92 | if(!$myfile) {$link->rollBack(); deldir('qqbot/'.$newid); die('{"retcode":996,"msg":"UNABLE TO CREATE GROUPFOLLOW.TXT!"}');} 93 | fwrite($myfile, $_POST['email']); 94 | fclose($myfile); 95 | break; 96 | case 'qqrobot': 97 | if (dcopy('qqbot/qqrobot', 'qqbot/'.$newid)==0) {$link->rollBack(); die('{"retcode":999,"msg":"UNABLE TO CREATE FOLDER!"}');} 98 | $myfile = fopen('qqbot/'.$newid."/groupfollow.txt", "w"); 99 | if(!$myfile) {$link->rollBack(); deldir('qqbot/'.$newid); die('{"retcode":996,"msg":"UNABLE TO CREATE GROUPFOLLOW.TXT!"}');} 100 | fwrite($myfile, $_POST['groups']); 101 | fclose($myfile); 102 | $myfile = fopen('qqbot/'.$newid."/email.txt", "w"); 103 | if(!$myfile) {$link->rollBack(); deldir('qqbot/'.$newid); die('{"retcode":996,"msg":"UNABLE TO CREATE GROUPFOLLOW.TXT!"}');} 104 | fwrite($myfile, $_POST['email']); 105 | fclose($myfile); 106 | break; 107 | case 'qqparking': 108 | if (dcopy('qqbot/qqparking', 'qqbot/'.$newid)==0) {$link->rollBack(); die('{"retcode":999,"msg":"UNABLE TO CREATE FOLDER!"}');} 109 | $myfile = fopen('qqbot/'.$newid."/config.txt", "w"); 110 | if(!$myfile) {$link->rollBack(); deldir('qqbot/'.$newid); die('{"retcode":996,"msg":"UNABLE TO CREATE GROUPFOLLOW.TXT!"}');} 111 | fwrite($myfile, $_POST['email']."\n"); 112 | fwrite($myfile, $_POST['welcome']."\n"); 113 | fclose($myfile); 114 | break; 115 | default: 116 | $link->rollBack(); 117 | die('{"retcode":996,"msg":"UNKNOWN TYPE SUBMITTED!"}'); 118 | break; 119 | } 120 | shell_exec('chmod -R +x qqbot/'.$newid); 121 | shell_exec('chmod -R +w qqbot/'.$newid); 122 | $command = 'cd qqbot/'.$newid.'; nohup python2 qqbot.py > /dev/null 2>&1 & echo $!'; 123 | exec($command ,$op); 124 | $pid = (int)$op[0]; 125 | 126 | while (true){ 127 | $sid=randomstr(); 128 | $sql="SELECT COUNT(*) FROM `process` WHERE `sid`=?"; 129 | $res=sqlexec($sql,array($sid),$link); 130 | $num= $res->fetch(PDO::FETCH_NUM); 131 | $num=$num[0]; 132 | if($num==0) break; 133 | } 134 | sqlexec('INSERT INTO `process` VALUES (?,?,?)',array($newid,$pid,$sid),$link); 135 | $link->commit(); 136 | die('{"retcode":0,"reason":"SUCCESS","id":"'.$sid.'"}'); 137 | ?> 138 | -------------------------------------------------------------------------------- /css/addtohomescreen.css: -------------------------------------------------------------------------------- 1 | .ath-viewport * { 2 | -webkit-box-sizing: border-box; 3 | -moz-box-sizing: border-box; 4 | box-sizing: border-box; 5 | } 6 | 7 | .ath-viewport { 8 | position: relative; 9 | z-index: 2147483641; 10 | pointer-events: none; 11 | 12 | -webkit-tap-highlight-color: rgba(0,0,0,0); 13 | -webkit-touch-callout: none; 14 | -webkit-user-select: none; 15 | -moz-user-select: none; 16 | -ms-user-select: none; 17 | user-select: none; 18 | -webkit-text-size-adjust: none; 19 | -moz-text-size-adjust: none; 20 | -ms-text-size-adjust: none; 21 | -o-text-size-adjust: none; 22 | text-size-adjust: none; 23 | } 24 | 25 | .ath-modal { 26 | pointer-events: auto !important; 27 | background: rgba(0,0,0,0.6); 28 | } 29 | 30 | .ath-mandatory { 31 | background: #000; 32 | } 33 | 34 | .ath-container { 35 | pointer-events: auto !important; 36 | position: absolute; 37 | z-index: 2147483641; 38 | padding: 0.7em 0.6em; 39 | width: 18em; 40 | 41 | background: #eee; 42 | background-size: 100% auto; 43 | 44 | box-shadow: 0 0.2em 0 #d1d1d1; 45 | 46 | font-family: sans-serif; 47 | font-size: 15px; 48 | line-height: 1.5em; 49 | text-align: center; 50 | } 51 | 52 | .ath-container small { 53 | font-size: 0.8em; 54 | line-height: 1.3em; 55 | display: block; 56 | margin-top: 0.5em; 57 | } 58 | 59 | .ath-ios.ath-phone { 60 | bottom: 1.8em; 61 | left: 50%; 62 | margin-left: -9em; 63 | } 64 | 65 | .ath-ios6.ath-tablet { 66 | left: 5em; 67 | top: 1.8em; 68 | } 69 | 70 | .ath-ios7.ath-tablet { 71 | left: 0.7em; 72 | top: 1.8em; 73 | } 74 | 75 | .ath-ios8.ath-tablet { 76 | right: 0.4em; 77 | top: 1.8em; 78 | } 79 | 80 | .ath-android { 81 | bottom: 1.8em; 82 | left: 50%; 83 | margin-left: -9em; 84 | } 85 | 86 | /* close icon */ 87 | .ath-container:before { 88 | content: ''; 89 | position: relative; 90 | display: block; 91 | float: right; 92 | margin: -0.7em -0.6em 0 0.5em; 93 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIQAAACECAMAAABmmnOVAAAAdVBMVEUAAAA5OTkzMzM7Ozs3NzdBQUFAQEA/Pz8+Pj5BQUFAQEA/Pz8+Pj5BQUFAQEA/Pz9BQUE+Pj4/Pz8/Pz8+Pj4/Pz8/Pz8/Pz8+Pj4/Pz8+Pj4/Pz8/Pz8/Pz8/Pz8/Pz8+Pj4/Pz8/Pz8/Pz8/Pz9AQEA/Pz+fdCaPAAAAJnRSTlMACQoNDjM4OTo7PEFCQ0RFS6ytsbS1tru8vcTFxu7x8vX19vf4+C5yomAAAAJESURBVHgBvdzLTsJAGEfxr4C2KBcVkQsIDsK8/yPaqIsPzVlyzrKrX/5p0kkXEz81L23otc9NpIbbWia2YVLqdnhlqFlhGWpSDHe1aopsSIpRb8gK0dC3G30b9rVmhWZIimTICsvQtx/FsuYOrWHoDjX3Gu31gzJxdki934WrAIOsAIOsAIOiAMPhPsJTgKGN0BVsYIVsYIVpYIVpYIVpYIVpYIVpYIVpYIVpYIVlAIVgEBRs8BRs8BRs8BRs8BRs8BRs8BRs8BRTNmgKNngKNngKNngKNngKNhiKGxgiOlZoBlaYBlaYBlaYBlaYBlaYBlaYBlaYBlZIBlBMfQMrVAMr2KAqBENSHFHhGEABhi5CV6gGUKgGUKgGUKgGUFwuqgEUvoEVsoEVpoEUpgEUggF+gKTKY+h1fxSlC7/Z+RrxOQ3fcEoAPPHZBlaYBlaYBlaYBlZYBlYIhvLBCstw7PgM7hkiWOEZWGEaWGEaWGEaIsakEAysmHkGVpxmvoEVqoEVpoEVpoEVpoEVpoEVpoEVkoEVgkFQsEFSsEFQsGEcoSvY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnY4CnmbNAUT2c2WAo2eAo2eAo2eAo2eAo2eArNEPFACjZ4CjZ4CjZ4CjaIird/rBvFH6llNCvewdli1URWCIakSIZesUaDoFg36dKFWk9zCZDei3TtwmCj7pC22AwikiIZPEU29IpFNliKxa/hC9DFITjQPYhcAAAAAElFTkSuQmCC); 94 | background-color: rgba(255,255,255,0.8); 95 | background-size: 50%; 96 | background-repeat: no-repeat; 97 | background-position: 50%; 98 | width: 2.7em; 99 | height: 2.7em; 100 | text-align: center; 101 | overflow: hidden; 102 | color: #a33; 103 | z-index: 2147483642; 104 | } 105 | 106 | .ath-container.ath-icon:before { 107 | position: absolute; 108 | top: 0; 109 | right: 0; 110 | margin: 0; 111 | float: none; 112 | } 113 | 114 | .ath-mandatory .ath-container:before { 115 | display: none; 116 | } 117 | 118 | .ath-container.ath-android:before { 119 | float: left; 120 | margin: -0.7em 0.5em 0 -0.6em; 121 | } 122 | 123 | .ath-container.ath-android.ath-icon:before { 124 | position: absolute; 125 | right: auto; 126 | left: 0; 127 | margin: 0; 128 | float: none; 129 | } 130 | 131 | 132 | /* applied only if the application icon is shown */ 133 | .ath-container.ath-icon { 134 | 135 | } 136 | 137 | .ath-action-icon { 138 | display: inline-block; 139 | vertical-align: middle; 140 | background-position: 50%; 141 | background-repeat: no-repeat; 142 | text-indent: -9999em; 143 | overflow: hidden; 144 | } 145 | 146 | .ath-ios7 .ath-action-icon, 147 | .ath-ios8 .ath-action-icon { 148 | width: 1.6em; 149 | height: 1.6em; 150 | background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAACtCAYAAAB7l7tOAAAF6UlEQVR4AezZWWxUZRiH8VcQEdxZEFFiUZBFUCIa1ABBDARDcCciYGKMqTEGww3SOcNSAwQTjOBiiIpEhRjAhRgXRC8MFxojEhAFZUGttVhaoSxlaW3n8W3yXZxm6vTrOMM5Q98n+V9MMu1pvl++uZhKuypghu49KaaTWGdZSYoVN6VD95nMpLNYZ9XNbdQR2od2k88O3Gm6Bh0t7H0p5Vwp2Ax3ajpu2tYbciFWwkTFO63DY6+JcI4USFaSyYpWp8N7SVZJKR3EinkBk9JxvZFXxhnZSjBaoWp1ZL0ES8WKYXMZp0AndORgy8WKFe5Yf1zvvSBWDEpys2LU6MjD5kmEWQlGKsJRHXlcqUSQVcItEnDEA6gAb7LhjvD9WO6yIEfICQI5A1nzGCYB1T4og5bBiFcyv2f6ujYhl4iVxwKG6qp8MK55HsqPwK0rMr9v/yEo3uCPrJstVh5KMER30Aeh31Ioq0FrHfjXw9CYghnrvYFTuqfEymFzGSwBlT4ARYr7u+K6GLmCVGvAGg2NMG0d/sgJnpScZLjXSkC5z8H3eQ72/k24Q8NfzvwFyK4qtuJSZKaubRPyE/K/Mtx+EvCHL+7uasId1t10w0scz/RzSzYzAfgKV30D3LPaG7lRkR8RK4tKKJKAMp+D7r0EfmmOe0x3m2itAc/ZxBjgAt1mXHWKPPkdb+QGSTJdrDaU5EoJ2OtzwD0WwY7KNNzbRfMFFg24WPdtGHnS221Cflgsj56hjwTs8TnY7oq7/QDhjutGicsb2AVcovsO18l6uPPNNiE/JFaGAq7Q7fY50G4LYVtz3FrdaNGyBXbIl+q24DqhyHes9EaulwR3SwtZs+ktAT/7HORliru1gnCndONFyx44Dfn7MPLYN7yR6yTJZAllJeguAT/4HOBFz8I3ZWm4E0TLFbBD7qn7EVdtHYx53R9ZN0ksrZRuErDN5+AuLIWvm+Oe1k0ULdfADrmX7idcR0/DyBXeyCdlLuMMOGCBz4F1ng+f7yFcve5e0fIFHELeiav6BAx70Rt5p0yhY3u/wR0kyarW/uX35b403PtFyzewQ75ctwtXzSkY8WqruHslSV8RscrL6TJ1bcvfWJ0/HzbtIdw/ugdFyzdwOOAq3T6fmzxwGQ3vbmO8iFioIWqYSsHMj9M/ljfuTsOdItoZBXYBfXX7cVXVwvXLm/8+fU3lcdCqdEMNGBbgUmRmfQISQKd5sGEn4VK6YtEiAXYBA3QVuA4q8hCHrDcafR1ul65jewfuovsCl7vJrNlOuEbdo6JFCuwCrtb9hqusBu56Cw4cI1y1briIWEBn3Ue0XKPuMdGiBg4H9NdV0HJ/6QZLOEPmPN0GmpfSPS5arIBdwHUtIFfoBsl/ZsgfhHCfFi2WwC5goO4AmvanbqBkzJA76tboZokWa2AXMEi3RTdAvDLkDqJFAhzB32xFD2wZsGXA0WfAlgFbBmwZsGXAlgFbBpzk04JaKb0iA9ZnF9x5SQAFtRKKIgPWZxfaeRmwAZ/BGbAB37eaG6MCbnq2Aed5czYyKirgpmcbsAHHZAZswN0Wwo7KeG1fFf2jAm56dtzOQ42yB+65mDhWFBUwUETMUiMDNmADbp/APRaTAh6I2bpGCNw1bufRZJQ1cPdF/NueHZsgDEBBGLbMGoIu4AZu5gLOZeEaYmEXeznF3jRPyEv4frgJvvJe3qTefY0AAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwYMGDBgwIABAwb8rwADBgwYMGDAgAEDBgwYMGDAgAEDBgwYMGDAgAEDBgz4/sz1Nia/9hizA7zgklwy3RYwYMBzBRjw4bPjxAbAAizAAtwgwAIswAIswAIMGDBgARZgARZgAS4FWIAFWIAFWIABAwYswAIswAIswIUAC7AAC7AACzBgwIAFWIAFWIAFuBBgARZgARZgAQYMGPApQ99ZCdgWtzqwATbABtgAG2DbnxNb7zbRimsMLMACrDf2wMWI/WasfQAAAABJRU5ErkJggg==); 151 | margin-top: -0.3em; 152 | background-size: auto 100%; 153 | } 154 | 155 | .ath-ios6 .ath-action-icon { 156 | width: 1.8em; 157 | height: 1.8em; 158 | background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAAB0CAQAAADAmnOnAAAAAnNCSVQICFXsRgQAAAAJcEhZcwAAWwEAAFsBAXkZiFwAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAF4klEQVR4Ae3a/a+XdR3H8ec5HM45HDmKICoVohkZsxESRRCzcZM/2JKkdGR5MrSkleA0Pd00O4u5IVuNM2yYc6XSzCExU4oUNRPCJFdMUAhsYZpUGhscOHA4N8/WZzsL6HBxvofvdV3fa3yer//gsV3vH659KHzncBsJxUYhDzOEhCKQbORs+ip2wzgM+wvj+P9i35qAGLaHGcQSgKSTrxBLABJppZpYApCspoFYApBsZjSxBCD5OxOJJQBJG1cQSwCSLpqJJQCJ3MvgCGTinuSMCJS8LZwfgZL3FtMiUPIOcU0ESl4PLRHoRPsJtREoeRsYGYGS9yrvo6RmpbLaigWSfzOdErLs6+bLUMFA0sF1+QF1cz1UNlBYK9V5AHXyWSgEkKyiIWOgGh829Ki1lLcaxjCVK7mJRSxjBY+zgRf/u9pXcMB7jhEZAg32EUP3O6hMKOP5Iq2sZQeHMZXt5KKMgOpcY+iHVnFyjeQKlrCBdsxge5ieAVC9vzLUelI8H+A7bKIHM10H81IGGuKvDf1ggDxVTKOV1zG3/Yia1ICG+ltD32MgNTKfP2HuW0VDKkCNrjfUTOm9i6XswwrZJkaVHeh0f2fodkrtfO6jAytqrzG+rEDDfVG1x1sprZEs5RBW4PZxeT+Bbrf5hPu9arfzKaU6WjiAFbseWvoF1GW/6vYGSmkyW7Dit4xB5QHq9Br6Xx2t9GAhtp6zkoHsfNp1J9wX6H+jeR4LtJc4LxGopZZyNpN/YcG2mw9nBTSPLizgOmjKAujGgvJID3ekD7QYi7nGzkvmQtpA38Vi7iJf0TedlC7QTVjMfcY2QyvSBPpUMW/PIBfbo9pls1XpAX2EdizeznStob3OJpQO0DB2YfE21q2GtnghpAm0Gou3T9tm6BGHQppA12HRVt17eboNlydNoLHsx2JtmL801OYcQmkC/QKLtQt9ydBW3wNpA30ci7Ur3WdolUMhbaBqNhf/8qQJ9Hkszs5wjaH9XkUobaAqtmFRdoGbDb3sWMgG6DIs5852knO82RaXer+P+qyb3eWeo7ZNBrRZvm1otY2QFdBjeHIb6hTne49Put12+9ObMoDdYmfy5UkF6AK6cCCr9aM2u9IddptcOYCG+FNDB5xLKCugO7G01TndFp/xgAntdYvrfdwVLnORt3q9Vx25F27DUjbGPxr6qxMgW6Cd2N+d6wLXedA+6nKbK73Lr/pJxzusvE/wZrvX0FOOgGyBxmF/dprXutYOj6nNdS6xyYnWp/dGcaGdhr5vDWQN9E1MXrUzfcA2j2qPj/l1J1uT9iPOeh8w1O7nCGUN9HzyGZ7ndo9qp0ucanU2r1xH+wdDu5wIeQDVVx0+/kd1i697RNv8thdn+Qz4Uv9p6DeOhHyApmBfq3OBu+3Nfd7nVELZAX3Nw4ZarYG8gG7GY1dlk6/Zm3/2Rk8jlB1QvT82dNAmQjkBVf8Mj957fdrefM7ZVhPKEuidvmDob06CXIGGbsX/bZDf8KAhfdbJhLIGmuZuQ084HHIGatiLvRvrRkP6qldbBXkAzbfD0N0OhryBGqrEMOd50FC7d1hPKGugBh8ydMh5hPIGGouI1d5lj6F1vptQ9kDvcKOhN5wMlQH0QcRGnzC03yZCeQDN9G1D6xwBFQI07FI8x02GdjgB8gJqttPQcmuhYoAumzvG7YZWejrkA1TrPYYO+SVCFQO0aM4bqj0uJJQH0LluSP7PkyeQU9QOmyAvoBm+Zegpz4LKA/qYB/wE5AXUe3m81zqoRKAPOYWcuvP9dxvqcD6h7IAKkaNU3eUlHLcI9EzS5YlAi62h/zUy89QCqqKUmvgHywsJlEHnsQYxAvXVIJo5gIhnPhiBju1iNmLvLn85Ah1ZPYs5jBGo72awEzEC9dVwHqQHI9DxWoAYgSLQQKteGIESu/qhCJTYtT+PQBEoAkWgCBSBkotAEehUWwSKQBEoAkWg/BeBIlAEikARKAJFoFmealu4gVLy1Gt5dkARKAL9BzujPSurTmu/AAAAAElFTkSuQmCC); 159 | margin-bottom: 0.4em; 160 | background-size: 100% auto; 161 | } 162 | 163 | .ath-android .ath-action-icon { 164 | width: 1.4em; 165 | height: 1.5em; 166 | background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAANlBMVEVmZmb///9mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZW6fJrAAAAEXRSTlMAAAYHG21ub8fLz9DR8/T4+RrZ9owAAAB3SURBVHja7dNLDoAgDATQWv4gKve/rEajJOJiWLgg6WzpSyB0aHqHiNj6nL1lovb4C+hYzkSNAT7mryQFAVOeGAj4CjwEtgrWXpD/uZKtwEJApXt+Vn0flzRhgNiFZQkOXY0aADQZCOCPlsZJ46Rx0jhp3IiN2wGDHhxtldrlwQAAAABJRU5ErkJggg==); 167 | background-size: 100% auto; 168 | } 169 | 170 | .ath-container p { 171 | margin: 0; 172 | padding: 0; 173 | position: relative; 174 | z-index: 2147483642; 175 | text-shadow: 0 0.1em 0 #fff; 176 | font-size: 1.1em; 177 | } 178 | 179 | .ath-ios.ath-phone:after { 180 | content: ''; 181 | background: #eee; 182 | position: absolute; 183 | width: 2em; 184 | height: 2em; 185 | bottom: -0.9em; 186 | left: 50%; 187 | margin-left: -1em; 188 | -webkit-transform: scaleX(0.9) rotate(45deg); 189 | transform: scaleX(0.9) rotate(45deg); 190 | box-shadow: 0.2em 0.2em 0 #d1d1d1; 191 | } 192 | 193 | .ath-ios.ath-tablet:after { 194 | content: ''; 195 | background: #eee; 196 | position: absolute; 197 | width: 2em; 198 | height: 2em; 199 | top: -0.9em; 200 | left: 50%; 201 | margin-left: -1em; 202 | -webkit-transform: scaleX(0.9) rotate(45deg); 203 | transform: scaleX(0.9) rotate(45deg); 204 | z-index: 2147483641; 205 | } 206 | 207 | .ath-application-icon { 208 | position: relative; 209 | padding: 0; 210 | border: 0; 211 | margin: 0 auto 0.2em auto; 212 | height: 6em; 213 | width: 6em; 214 | z-index: 2147483642; 215 | } 216 | 217 | .ath-container.ath-ios .ath-application-icon { 218 | border-radius: 1em; 219 | box-shadow: 0 0.2em 0.4em rgba(0,0,0,0.3), 220 | inset 0 0.07em 0 rgba(255,255,255,0.5); 221 | margin: 0 auto 0.4em auto; 222 | } 223 | 224 | @media only screen and (orientation: landscape) { 225 | .ath-container.ath-phone { 226 | width: 24em; 227 | } 228 | 229 | .ath-android.ath-phone { 230 | margin-left: -12em; 231 | } 232 | 233 | .ath-ios.ath-phone { 234 | margin-left: -12em; 235 | } 236 | 237 | .ath-ios6:after { 238 | left: 39%; 239 | } 240 | 241 | .ath-ios8.ath-phone { 242 | left: auto; 243 | bottom: auto; 244 | right: 0.4em; 245 | top: 1.8em; 246 | } 247 | 248 | .ath-ios8.ath-phone:after { 249 | bottom: auto; 250 | top: -0.9em; 251 | left: 68%; 252 | z-index: 2147483641; 253 | box-shadow: none; 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /css/bootstrap-theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.4 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | 7 | .btn-default, 8 | .btn-primary, 9 | .btn-success, 10 | .btn-info, 11 | .btn-warning, 12 | .btn-danger { 13 | text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); 14 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); 15 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); 16 | } 17 | .btn-default:active, 18 | .btn-primary:active, 19 | .btn-success:active, 20 | .btn-info:active, 21 | .btn-warning:active, 22 | .btn-danger:active, 23 | .btn-default.active, 24 | .btn-primary.active, 25 | .btn-success.active, 26 | .btn-info.active, 27 | .btn-warning.active, 28 | .btn-danger.active { 29 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 30 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 31 | } 32 | .btn-default .badge, 33 | .btn-primary .badge, 34 | .btn-success .badge, 35 | .btn-info .badge, 36 | .btn-warning .badge, 37 | .btn-danger .badge { 38 | text-shadow: none; 39 | } 40 | .btn:active, 41 | .btn.active { 42 | background-image: none; 43 | } 44 | .btn-default { 45 | text-shadow: 0 1px 0 #fff; 46 | background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); 47 | background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); 48 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); 49 | background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); 50 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); 51 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 52 | background-repeat: repeat-x; 53 | border-color: #dbdbdb; 54 | border-color: #ccc; 55 | } 56 | .btn-default:hover, 57 | .btn-default:focus { 58 | background-color: #e0e0e0; 59 | background-position: 0 -15px; 60 | } 61 | .btn-default:active, 62 | .btn-default.active { 63 | background-color: #e0e0e0; 64 | border-color: #dbdbdb; 65 | } 66 | .btn-default.disabled, 67 | .btn-default:disabled, 68 | .btn-default[disabled] { 69 | background-color: #e0e0e0; 70 | background-image: none; 71 | } 72 | .btn-primary { 73 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); 74 | background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); 75 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); 76 | background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); 77 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); 78 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 79 | background-repeat: repeat-x; 80 | border-color: #245580; 81 | } 82 | .btn-primary:hover, 83 | .btn-primary:focus { 84 | background-color: #265a88; 85 | background-position: 0 -15px; 86 | } 87 | .btn-primary:active, 88 | .btn-primary.active { 89 | background-color: #265a88; 90 | border-color: #245580; 91 | } 92 | .btn-primary.disabled, 93 | .btn-primary:disabled, 94 | .btn-primary[disabled] { 95 | background-color: #265a88; 96 | background-image: none; 97 | } 98 | .btn-success { 99 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); 100 | background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); 101 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); 102 | background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); 103 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); 104 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 105 | background-repeat: repeat-x; 106 | border-color: #3e8f3e; 107 | } 108 | .btn-success:hover, 109 | .btn-success:focus { 110 | background-color: #419641; 111 | background-position: 0 -15px; 112 | } 113 | .btn-success:active, 114 | .btn-success.active { 115 | background-color: #419641; 116 | border-color: #3e8f3e; 117 | } 118 | .btn-success.disabled, 119 | .btn-success:disabled, 120 | .btn-success[disabled] { 121 | background-color: #419641; 122 | background-image: none; 123 | } 124 | .btn-info { 125 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 126 | background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 127 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); 128 | background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); 129 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); 130 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 131 | background-repeat: repeat-x; 132 | border-color: #28a4c9; 133 | } 134 | .btn-info:hover, 135 | .btn-info:focus { 136 | background-color: #2aabd2; 137 | background-position: 0 -15px; 138 | } 139 | .btn-info:active, 140 | .btn-info.active { 141 | background-color: #2aabd2; 142 | border-color: #28a4c9; 143 | } 144 | .btn-info.disabled, 145 | .btn-info:disabled, 146 | .btn-info[disabled] { 147 | background-color: #2aabd2; 148 | background-image: none; 149 | } 150 | .btn-warning { 151 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 152 | background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 153 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); 154 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); 155 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); 156 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 157 | background-repeat: repeat-x; 158 | border-color: #e38d13; 159 | } 160 | .btn-warning:hover, 161 | .btn-warning:focus { 162 | background-color: #eb9316; 163 | background-position: 0 -15px; 164 | } 165 | .btn-warning:active, 166 | .btn-warning.active { 167 | background-color: #eb9316; 168 | border-color: #e38d13; 169 | } 170 | .btn-warning.disabled, 171 | .btn-warning:disabled, 172 | .btn-warning[disabled] { 173 | background-color: #eb9316; 174 | background-image: none; 175 | } 176 | .btn-danger { 177 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 178 | background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 179 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); 180 | background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); 181 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); 182 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 183 | background-repeat: repeat-x; 184 | border-color: #b92c28; 185 | } 186 | .btn-danger:hover, 187 | .btn-danger:focus { 188 | background-color: #c12e2a; 189 | background-position: 0 -15px; 190 | } 191 | .btn-danger:active, 192 | .btn-danger.active { 193 | background-color: #c12e2a; 194 | border-color: #b92c28; 195 | } 196 | .btn-danger.disabled, 197 | .btn-danger:disabled, 198 | .btn-danger[disabled] { 199 | background-color: #c12e2a; 200 | background-image: none; 201 | } 202 | .thumbnail, 203 | .img-thumbnail { 204 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 205 | box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 206 | } 207 | .dropdown-menu > li > a:hover, 208 | .dropdown-menu > li > a:focus { 209 | background-color: #e8e8e8; 210 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 211 | background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 212 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); 213 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 214 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 215 | background-repeat: repeat-x; 216 | } 217 | .dropdown-menu > .active > a, 218 | .dropdown-menu > .active > a:hover, 219 | .dropdown-menu > .active > a:focus { 220 | background-color: #2e6da4; 221 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 222 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 223 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 224 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 225 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 226 | background-repeat: repeat-x; 227 | } 228 | .navbar-default { 229 | background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); 230 | background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); 231 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); 232 | background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); 233 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); 234 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 235 | background-repeat: repeat-x; 236 | border-radius: 4px; 237 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); 238 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); 239 | } 240 | .navbar-default .navbar-nav > .open > a, 241 | .navbar-default .navbar-nav > .active > a { 242 | background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); 243 | background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); 244 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); 245 | background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); 246 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); 247 | background-repeat: repeat-x; 248 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); 249 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); 250 | } 251 | .navbar-brand, 252 | .navbar-nav > li > a { 253 | text-shadow: 0 1px 0 rgba(255, 255, 255, .25); 254 | } 255 | .navbar-inverse { 256 | background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); 257 | background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); 258 | background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); 259 | background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); 260 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); 261 | filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); 262 | background-repeat: repeat-x; 263 | } 264 | .navbar-inverse .navbar-nav > .open > a, 265 | .navbar-inverse .navbar-nav > .active > a { 266 | background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); 267 | background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); 268 | background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); 269 | background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); 270 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); 271 | background-repeat: repeat-x; 272 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); 273 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); 274 | } 275 | .navbar-inverse .navbar-brand, 276 | .navbar-inverse .navbar-nav > li > a { 277 | text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); 278 | } 279 | .navbar-static-top, 280 | .navbar-fixed-top, 281 | .navbar-fixed-bottom { 282 | border-radius: 0; 283 | } 284 | @media (max-width: 767px) { 285 | .navbar .navbar-nav .open .dropdown-menu > .active > a, 286 | .navbar .navbar-nav .open .dropdown-menu > .active > a:hover, 287 | .navbar .navbar-nav .open .dropdown-menu > .active > a:focus { 288 | color: #fff; 289 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 290 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 291 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 292 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 293 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 294 | background-repeat: repeat-x; 295 | } 296 | } 297 | .alert { 298 | text-shadow: 0 1px 0 rgba(255, 255, 255, .2); 299 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); 300 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); 301 | } 302 | .alert-success { 303 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 304 | background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 305 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); 306 | background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); 307 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); 308 | background-repeat: repeat-x; 309 | border-color: #b2dba1; 310 | } 311 | .alert-info { 312 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 313 | background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 314 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); 315 | background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); 316 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); 317 | background-repeat: repeat-x; 318 | border-color: #9acfea; 319 | } 320 | .alert-warning { 321 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 322 | background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 323 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); 324 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); 325 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); 326 | background-repeat: repeat-x; 327 | border-color: #f5e79e; 328 | } 329 | .alert-danger { 330 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 331 | background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 332 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); 333 | background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); 334 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); 335 | background-repeat: repeat-x; 336 | border-color: #dca7a7; 337 | } 338 | .progress { 339 | background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 340 | background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 341 | background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); 342 | background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); 343 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); 344 | background-repeat: repeat-x; 345 | } 346 | .progress-bar { 347 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); 348 | background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); 349 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); 350 | background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); 351 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); 352 | background-repeat: repeat-x; 353 | } 354 | .progress-bar-success { 355 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); 356 | background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); 357 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); 358 | background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); 359 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); 360 | background-repeat: repeat-x; 361 | } 362 | .progress-bar-info { 363 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 364 | background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 365 | background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); 366 | background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); 367 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); 368 | background-repeat: repeat-x; 369 | } 370 | .progress-bar-warning { 371 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 372 | background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 373 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); 374 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); 375 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); 376 | background-repeat: repeat-x; 377 | } 378 | .progress-bar-danger { 379 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); 380 | background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); 381 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); 382 | background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); 383 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); 384 | background-repeat: repeat-x; 385 | } 386 | .progress-bar-striped { 387 | background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); 388 | background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); 389 | background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); 390 | } 391 | .list-group { 392 | border-radius: 4px; 393 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 394 | box-shadow: 0 1px 2px rgba(0, 0, 0, .075); 395 | } 396 | .list-group-item.active, 397 | .list-group-item.active:hover, 398 | .list-group-item.active:focus { 399 | text-shadow: 0 -1px 0 #286090; 400 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); 401 | background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); 402 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); 403 | background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); 404 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); 405 | background-repeat: repeat-x; 406 | border-color: #2b669a; 407 | } 408 | .list-group-item.active .badge, 409 | .list-group-item.active:hover .badge, 410 | .list-group-item.active:focus .badge { 411 | text-shadow: none; 412 | } 413 | .panel { 414 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); 415 | box-shadow: 0 1px 2px rgba(0, 0, 0, .05); 416 | } 417 | .panel-default > .panel-heading { 418 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 419 | background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 420 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); 421 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 422 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 423 | background-repeat: repeat-x; 424 | } 425 | .panel-primary > .panel-heading { 426 | background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 427 | background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); 428 | background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); 429 | background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); 430 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); 431 | background-repeat: repeat-x; 432 | } 433 | .panel-success > .panel-heading { 434 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 435 | background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 436 | background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); 437 | background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); 438 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); 439 | background-repeat: repeat-x; 440 | } 441 | .panel-info > .panel-heading { 442 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 443 | background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 444 | background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); 445 | background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); 446 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); 447 | background-repeat: repeat-x; 448 | } 449 | .panel-warning > .panel-heading { 450 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 451 | background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 452 | background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); 453 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); 454 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); 455 | background-repeat: repeat-x; 456 | } 457 | .panel-danger > .panel-heading { 458 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 459 | background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 460 | background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); 461 | background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); 462 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); 463 | background-repeat: repeat-x; 464 | } 465 | .well { 466 | background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 467 | background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 468 | background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); 469 | background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); 470 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); 471 | background-repeat: repeat-x; 472 | border-color: #dcdcdc; 473 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); 474 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); 475 | } 476 | /*# sourceMappingURL=bootstrap-theme.css.map */ 477 | -------------------------------------------------------------------------------- /css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.3.4 (http://getbootstrap.com) 3 | * Copyright 2011-2015 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary:disabled,.btn-primary[disabled]{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} -------------------------------------------------------------------------------- /css/cover.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Globals 3 | */ 4 | 5 | /* Links */ 6 | a, 7 | a:focus, 8 | a:hover { 9 | color: #fff; 10 | } 11 | 12 | /* Custom default button */ 13 | .btn-default, 14 | .btn-default:hover, 15 | .btn-default:focus { 16 | color: #333; 17 | text-shadow: none; /* Prevent inheritence from `body` */ 18 | background-color: #fff; 19 | border: 1px solid #fff; 20 | } 21 | 22 | #navbtnshadow, 23 | #navbtnshadow:focus, 24 | #navbtnshadow:hover, 25 | #navbtnshadow:visited { 26 | background-color:rgba(0,0,0,0.6); 27 | border-color:rgba(0,0,0,1); 28 | color:#ffffff; 29 | 30 | } 31 | 32 | .shadowbox 33 | { 34 | background-color:rgba(0,0,0,0.6); 35 | border-color:rgba(0,0,0,1); 36 | padding: 10px 10px; 37 | } 38 | /* 39 | * Base structure 40 | */ 41 | 42 | html, 43 | body { 44 | height: 100%; 45 | background-color: rgba(0,0,0,.3); 46 | 47 | } 48 | body { 49 | color: #fff; 50 | text-align: center; 51 | text-shadow: 0 1px 3px rgba(0,0,0,.5); 52 | } 53 | 54 | /* Extra markup and styles for table-esque vertical and horizontal centering */ 55 | .site-wrapper { 56 | display: table; 57 | width: 100%; 58 | height: 100%; /* For at least Firefox */ 59 | min-height: 100%; 60 | -webkit-box-shadow: inset 0 0 150px rgba(0,0,0,1); 61 | box-shadow: inset 0 0 150px rgba(0,0,0,1); 62 | } 63 | .site-wrapper-inner { 64 | display: table-cell; 65 | vertical-align: top; 66 | } 67 | .cover-container { 68 | margin-right: auto; 69 | margin-left: auto; 70 | } 71 | 72 | /* Padding for spacing */ 73 | .inner { 74 | padding: 30px; 75 | } 76 | 77 | 78 | /* 79 | * Header 80 | */ 81 | .masthead-brand { 82 | margin-top: 10px; 83 | margin-bottom: 10px; 84 | } 85 | 86 | .masthead-nav > li { 87 | display: inline-block; 88 | } 89 | .masthead-nav > li + li { 90 | margin-left: 20px; 91 | } 92 | 93 | @media (min-width: 768px) { 94 | .masthead-brand { 95 | float: left; 96 | } 97 | .masthead-nav { 98 | float: right; 99 | } 100 | } 101 | 102 | 103 | /* 104 | * Cover 105 | */ 106 | 107 | .cover { 108 | padding: 0 20px; 109 | } 110 | .cover .btn-lg { 111 | padding: 10px 20px; 112 | font-weight: bold; 113 | } 114 | 115 | 116 | /* 117 | * Footer 118 | */ 119 | 120 | .mastfoot { 121 | color: #999; /* IE8 proofing */ 122 | color: rgba(255,255,255,.5); 123 | } 124 | 125 | 126 | /* 127 | * Affix and center 128 | */ 129 | 130 | @media (min-width: 768px) { 131 | /* Pull out the header and footer */ 132 | .masthead { 133 | position: fixed; 134 | top: 0; 135 | } 136 | .mastfoot { 137 | position: fixed; 138 | bottom: 0; 139 | } 140 | /* Start the vertical centering */ 141 | .site-wrapper-inner { 142 | vertical-align: middle; 143 | } 144 | /* Handle the widths */ 145 | .masthead, 146 | .mastfoot, 147 | .cover-container { 148 | width: 100%; /* Must be percentage or pixels for horizontal alignment */ 149 | } 150 | } 151 | 152 | @media (min-width: 992px) { 153 | .masthead, 154 | .mastfoot, 155 | .cover-container { 156 | width: 700px; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | color: #777; 3 | text-align: center; 4 | padding: 30px 0; 5 | margin-top: 70px; 6 | border-top: 1px solid #e5e5e5; 7 | background-color: #f5f5f5; 8 | } 9 | 10 | .theme-showcase 11 | { 12 | margin-top:50px !important; 13 | } -------------------------------------------------------------------------------- /function/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | -------------------------------------------------------------------------------- /function/sqllink.php: -------------------------------------------------------------------------------- 1 | 'SET NAMES utf8',); 11 | $dsn='mysql:host=' . $dbhost . ';dbname=' . $dbname.';charset=utf8'; 12 | try { 13 | $dbhdl = new PDO($dsn, $dbusr, $dbpwd, $opt); 14 | $dbhdl->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 15 | $dbhdl->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);//Display exception 16 | } 17 | catch (PDOExceptsddttrtion $e) {//return PDOException 18 | return NULL; 19 | } 20 | return $dbhdl; 21 | } 22 | function sqlexec($sql,$array,$link) 23 | { 24 | $stmt = $link->prepare($sql); 25 | $exeres = $stmt->execute($array); 26 | if($exeres) return $stmt; else return NULL; 27 | 28 | } 29 | function sqlquery($sql,$link) 30 | { 31 | return $link->query($sql); 32 | } 33 | ?> -------------------------------------------------------------------------------- /image.php: -------------------------------------------------------------------------------- 1 | fetch(PDO::FETCH_ASSOC); 8 | if ($result==FALSE) die('THIS PROCESS DOES NOT EXISTS OR ALREADY TERMINATED AND REMOVED FROM THE SERVER!'); 9 | header('Content-type: image/png'); 10 | //v.jpg is actually a png file. 11 | if(!file_exists('qqbot/'.$result['id'].'/v.png')) $filename='img/noqrcode.png'; else $filename='qqbot/'.$result['id'].'/v.png'; 12 | $image = @imagecreatefrompng($filename); 13 | imagepng($image); 14 | imageDestroy($image); 15 | exit; 16 | ?> -------------------------------------------------------------------------------- /img/favicon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/070ab3acc45ab204eaefc2bacd2f637f56fb339a/img/favicon.jpg -------------------------------------------------------------------------------- /img/noqrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/070ab3acc45ab204eaefc2bacd2f637f56fb339a/img/noqrcode.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | QBOT 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 61 |
62 | 65 |
66 |

Choose the type of QBot you want to run on the navigation bar! (在导航栏选择您要挂机的种类)

67 |


68 |

STEP 1: Input Necessary Information (输入必要信息)

69 |

STEP 2: Click Start button (点击开始按钮)

70 |

STEP 3: Scan QRCode (用手机QQ/安全中心扫描二维码登录)

71 |


72 |

Source Code (源代码): GitHub/zeruniverse/QBotWebWrap

73 |
74 | 77 |

If you already scanned QR Code, you can check your status here with your SID (the string you see on the QRCODE page)

78 |

您可以使用您的SID查询您的挂机状态。SID是您扫描二维码页面看到的字符串。

79 |

80 |

SID:

81 |

82 |
83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /js/fancybox/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/070ab3acc45ab204eaefc2bacd2f637f56fb339a/js/fancybox/blank.gif -------------------------------------------------------------------------------- /js/fancybox/fancybox_loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/070ab3acc45ab204eaefc2bacd2f637f56fb339a/js/fancybox/fancybox_loading.gif -------------------------------------------------------------------------------- /js/fancybox/fancybox_loading@2x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/070ab3acc45ab204eaefc2bacd2f637f56fb339a/js/fancybox/fancybox_loading@2x.gif -------------------------------------------------------------------------------- /js/fancybox/fancybox_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/070ab3acc45ab204eaefc2bacd2f637f56fb339a/js/fancybox/fancybox_overlay.png -------------------------------------------------------------------------------- /js/fancybox/fancybox_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/070ab3acc45ab204eaefc2bacd2f637f56fb339a/js/fancybox/fancybox_sprite.png -------------------------------------------------------------------------------- /js/fancybox/fancybox_sprite@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/070ab3acc45ab204eaefc2bacd2f637f56fb339a/js/fancybox/fancybox_sprite@2x.png -------------------------------------------------------------------------------- /js/fancybox/helpers/fancybox_buttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zeruniverse/QBotWebWrap/070ab3acc45ab204eaefc2bacd2f637f56fb339a/js/fancybox/helpers/fancybox_buttons.png -------------------------------------------------------------------------------- /js/fancybox/helpers/jquery.fancybox-buttons.css: -------------------------------------------------------------------------------- 1 | #fancybox-buttons { 2 | position: fixed; 3 | left: 0; 4 | width: 100%; 5 | z-index: 8050; 6 | } 7 | 8 | #fancybox-buttons.top { 9 | top: 10px; 10 | } 11 | 12 | #fancybox-buttons.bottom { 13 | bottom: 10px; 14 | } 15 | 16 | #fancybox-buttons ul { 17 | display: block; 18 | width: 166px; 19 | height: 30px; 20 | margin: 0 auto; 21 | padding: 0; 22 | list-style: none; 23 | border: 1px solid #111; 24 | border-radius: 3px; 25 | -webkit-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); 26 | -moz-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); 27 | box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); 28 | background: rgb(50,50,50); 29 | background: -moz-linear-gradient(top, rgb(68,68,68) 0%, rgb(52,52,52) 50%, rgb(41,41,41) 50%, rgb(51,51,51) 100%); 30 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgb(68,68,68)), color-stop(50%,rgb(52,52,52)), color-stop(50%,rgb(41,41,41)), color-stop(100%,rgb(51,51,51))); 31 | background: -webkit-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); 32 | background: -o-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); 33 | background: -ms-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); 34 | background: linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); 35 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#444444', endColorstr='#222222',GradientType=0 ); 36 | } 37 | 38 | #fancybox-buttons ul li { 39 | float: left; 40 | margin: 0; 41 | padding: 0; 42 | } 43 | 44 | #fancybox-buttons a { 45 | display: block; 46 | width: 30px; 47 | height: 30px; 48 | text-indent: -9999px; 49 | background-color: transparent; 50 | background-image: url('fancybox_buttons.png'); 51 | background-repeat: no-repeat; 52 | outline: none; 53 | opacity: 0.8; 54 | } 55 | 56 | #fancybox-buttons a:hover { 57 | opacity: 1; 58 | } 59 | 60 | #fancybox-buttons a.btnPrev { 61 | background-position: 5px 0; 62 | } 63 | 64 | #fancybox-buttons a.btnNext { 65 | background-position: -33px 0; 66 | border-right: 1px solid #3e3e3e; 67 | } 68 | 69 | #fancybox-buttons a.btnPlay { 70 | background-position: 0 -30px; 71 | } 72 | 73 | #fancybox-buttons a.btnPlayOn { 74 | background-position: -30px -30px; 75 | } 76 | 77 | #fancybox-buttons a.btnToggle { 78 | background-position: 3px -60px; 79 | border-left: 1px solid #111; 80 | border-right: 1px solid #3e3e3e; 81 | width: 35px 82 | } 83 | 84 | #fancybox-buttons a.btnToggleOn { 85 | background-position: -27px -60px; 86 | } 87 | 88 | #fancybox-buttons a.btnClose { 89 | border-left: 1px solid #111; 90 | width: 35px; 91 | background-position: -56px 0px; 92 | } 93 | 94 | #fancybox-buttons a.btnDisabled { 95 | opacity : 0.4; 96 | cursor: default; 97 | } -------------------------------------------------------------------------------- /js/fancybox/helpers/jquery.fancybox-buttons.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Buttons helper for fancyBox 3 | * version: 1.0.5 (Mon, 15 Oct 2012) 4 | * @requires fancyBox v2.0 or later 5 | * 6 | * Usage: 7 | * $(".fancybox").fancybox({ 8 | * helpers : { 9 | * buttons: { 10 | * position : 'top' 11 | * } 12 | * } 13 | * }); 14 | * 15 | */ 16 | (function ($) { 17 | //Shortcut for fancyBox object 18 | var F = $.fancybox; 19 | 20 | //Add helper object 21 | F.helpers.buttons = { 22 | defaults : { 23 | skipSingle : false, // disables if gallery contains single image 24 | position : 'top', // 'top' or 'bottom' 25 | tpl : '
' 26 | }, 27 | 28 | list : null, 29 | buttons: null, 30 | 31 | beforeLoad: function (opts, obj) { 32 | //Remove self if gallery do not have at least two items 33 | 34 | if (opts.skipSingle && obj.group.length < 2) { 35 | obj.helpers.buttons = false; 36 | obj.closeBtn = true; 37 | 38 | return; 39 | } 40 | 41 | //Increase top margin to give space for buttons 42 | obj.margin[ opts.position === 'bottom' ? 2 : 0 ] += 30; 43 | }, 44 | 45 | onPlayStart: function () { 46 | if (this.buttons) { 47 | this.buttons.play.attr('title', 'Pause slideshow').addClass('btnPlayOn'); 48 | } 49 | }, 50 | 51 | onPlayEnd: function () { 52 | if (this.buttons) { 53 | this.buttons.play.attr('title', 'Start slideshow').removeClass('btnPlayOn'); 54 | } 55 | }, 56 | 57 | afterShow: function (opts, obj) { 58 | var buttons = this.buttons; 59 | 60 | if (!buttons) { 61 | this.list = $(opts.tpl).addClass(opts.position).appendTo('body'); 62 | 63 | buttons = { 64 | prev : this.list.find('.btnPrev').click( F.prev ), 65 | next : this.list.find('.btnNext').click( F.next ), 66 | play : this.list.find('.btnPlay').click( F.play ), 67 | toggle : this.list.find('.btnToggle').click( F.toggle ), 68 | close : this.list.find('.btnClose').click( F.close ) 69 | } 70 | } 71 | 72 | //Prev 73 | if (obj.index > 0 || obj.loop) { 74 | buttons.prev.removeClass('btnDisabled'); 75 | } else { 76 | buttons.prev.addClass('btnDisabled'); 77 | } 78 | 79 | //Next / Play 80 | if (obj.loop || obj.index < obj.group.length - 1) { 81 | buttons.next.removeClass('btnDisabled'); 82 | buttons.play.removeClass('btnDisabled'); 83 | 84 | } else { 85 | buttons.next.addClass('btnDisabled'); 86 | buttons.play.addClass('btnDisabled'); 87 | } 88 | 89 | this.buttons = buttons; 90 | 91 | this.onUpdate(opts, obj); 92 | }, 93 | 94 | onUpdate: function (opts, obj) { 95 | var toggle; 96 | 97 | if (!this.buttons) { 98 | return; 99 | } 100 | 101 | toggle = this.buttons.toggle.removeClass('btnDisabled btnToggleOn'); 102 | 103 | //Size toggle button 104 | if (obj.canShrink) { 105 | toggle.addClass('btnToggleOn'); 106 | 107 | } else if (!obj.canExpand) { 108 | toggle.addClass('btnDisabled'); 109 | } 110 | }, 111 | 112 | beforeClose: function () { 113 | if (this.list) { 114 | this.list.remove(); 115 | } 116 | 117 | this.list = null; 118 | this.buttons = null; 119 | } 120 | }; 121 | 122 | }(jQuery)); 123 | -------------------------------------------------------------------------------- /js/fancybox/helpers/jquery.fancybox-media.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Media helper for fancyBox 3 | * version: 1.0.6 (Fri, 14 Jun 2013) 4 | * @requires fancyBox v2.0 or later 5 | * 6 | * Usage: 7 | * $(".fancybox").fancybox({ 8 | * helpers : { 9 | * media: true 10 | * } 11 | * }); 12 | * 13 | * Set custom URL parameters: 14 | * $(".fancybox").fancybox({ 15 | * helpers : { 16 | * media: { 17 | * youtube : { 18 | * params : { 19 | * autoplay : 0 20 | * } 21 | * } 22 | * } 23 | * } 24 | * }); 25 | * 26 | * Or: 27 | * $(".fancybox").fancybox({, 28 | * helpers : { 29 | * media: true 30 | * }, 31 | * youtube : { 32 | * autoplay: 0 33 | * } 34 | * }); 35 | * 36 | * Supports: 37 | * 38 | * Youtube 39 | * http://www.youtube.com/watch?v=opj24KnzrWo 40 | * http://www.youtube.com/embed/opj24KnzrWo 41 | * http://youtu.be/opj24KnzrWo 42 | * http://www.youtube-nocookie.com/embed/opj24KnzrWo 43 | * Vimeo 44 | * http://vimeo.com/40648169 45 | * http://vimeo.com/channels/staffpicks/38843628 46 | * http://vimeo.com/groups/surrealism/videos/36516384 47 | * http://player.vimeo.com/video/45074303 48 | * Metacafe 49 | * http://www.metacafe.com/watch/7635964/dr_seuss_the_lorax_movie_trailer/ 50 | * http://www.metacafe.com/watch/7635964/ 51 | * Dailymotion 52 | * http://www.dailymotion.com/video/xoytqh_dr-seuss-the-lorax-premiere_people 53 | * Twitvid 54 | * http://twitvid.com/QY7MD 55 | * Twitpic 56 | * http://twitpic.com/7p93st 57 | * Instagram 58 | * http://instagr.am/p/IejkuUGxQn/ 59 | * http://instagram.com/p/IejkuUGxQn/ 60 | * Google maps 61 | * http://maps.google.com/maps?q=Eiffel+Tower,+Avenue+Gustave+Eiffel,+Paris,+France&t=h&z=17 62 | * http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16 63 | * http://maps.google.com/?ll=48.859463,2.292626&spn=0.000965,0.002642&t=m&z=19&layer=c&cbll=48.859524,2.292532&panoid=YJ0lq28OOy3VT2IqIuVY0g&cbp=12,151.58,,0,-15.56 64 | */ 65 | (function ($) { 66 | "use strict"; 67 | 68 | //Shortcut for fancyBox object 69 | var F = $.fancybox, 70 | format = function( url, rez, params ) { 71 | params = params || ''; 72 | 73 | if ( $.type( params ) === "object" ) { 74 | params = $.param(params, true); 75 | } 76 | 77 | $.each(rez, function(key, value) { 78 | url = url.replace( '$' + key, value || '' ); 79 | }); 80 | 81 | if (params.length) { 82 | url += ( url.indexOf('?') > 0 ? '&' : '?' ) + params; 83 | } 84 | 85 | return url; 86 | }; 87 | 88 | //Add helper object 89 | F.helpers.media = { 90 | defaults : { 91 | youtube : { 92 | matcher : /(youtube\.com|youtu\.be|youtube-nocookie\.com)\/(watch\?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*)).*/i, 93 | params : { 94 | autoplay : 1, 95 | autohide : 1, 96 | fs : 1, 97 | rel : 0, 98 | hd : 1, 99 | wmode : 'opaque', 100 | enablejsapi : 1 101 | }, 102 | type : 'iframe', 103 | url : '//www.youtube.com/embed/$3' 104 | }, 105 | vimeo : { 106 | matcher : /(?:vimeo(?:pro)?.com)\/(?:[^\d]+)?(\d+)(?:.*)/, 107 | params : { 108 | autoplay : 1, 109 | hd : 1, 110 | show_title : 1, 111 | show_byline : 1, 112 | show_portrait : 0, 113 | fullscreen : 1 114 | }, 115 | type : 'iframe', 116 | url : '//player.vimeo.com/video/$1' 117 | }, 118 | metacafe : { 119 | matcher : /metacafe.com\/(?:watch|fplayer)\/([\w\-]{1,10})/, 120 | params : { 121 | autoPlay : 'yes' 122 | }, 123 | type : 'swf', 124 | url : function( rez, params, obj ) { 125 | obj.swf.flashVars = 'playerVars=' + $.param( params, true ); 126 | 127 | return '//www.metacafe.com/fplayer/' + rez[1] + '/.swf'; 128 | } 129 | }, 130 | dailymotion : { 131 | matcher : /dailymotion.com\/video\/(.*)\/?(.*)/, 132 | params : { 133 | additionalInfos : 0, 134 | autoStart : 1 135 | }, 136 | type : 'swf', 137 | url : '//www.dailymotion.com/swf/video/$1' 138 | }, 139 | twitvid : { 140 | matcher : /twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i, 141 | params : { 142 | autoplay : 0 143 | }, 144 | type : 'iframe', 145 | url : '//www.twitvid.com/embed.php?guid=$1' 146 | }, 147 | twitpic : { 148 | matcher : /twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i, 149 | type : 'image', 150 | url : '//twitpic.com/show/full/$1/' 151 | }, 152 | instagram : { 153 | matcher : /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i, 154 | type : 'image', 155 | url : '//$1/p/$2/media/?size=l' 156 | }, 157 | google_maps : { 158 | matcher : /maps\.google\.([a-z]{2,3}(\.[a-z]{2})?)\/(\?ll=|maps\?)(.*)/i, 159 | type : 'iframe', 160 | url : function( rez ) { 161 | return '//maps.google.' + rez[1] + '/' + rez[3] + '' + rez[4] + '&output=' + (rez[4].indexOf('layer=c') > 0 ? 'svembed' : 'embed'); 162 | } 163 | } 164 | }, 165 | 166 | beforeLoad : function(opts, obj) { 167 | var url = obj.href || '', 168 | type = false, 169 | what, 170 | item, 171 | rez, 172 | params; 173 | 174 | for (what in opts) { 175 | if (opts.hasOwnProperty(what)) { 176 | item = opts[ what ]; 177 | rez = url.match( item.matcher ); 178 | 179 | if (rez) { 180 | type = item.type; 181 | params = $.extend(true, {}, item.params, obj[ what ] || ($.isPlainObject(opts[ what ]) ? opts[ what ].params : null)); 182 | 183 | url = $.type( item.url ) === "function" ? item.url.call( this, rez, params, obj ) : format( item.url, rez, params ); 184 | 185 | break; 186 | } 187 | } 188 | } 189 | 190 | if (type) { 191 | obj.href = url; 192 | obj.type = type; 193 | 194 | obj.autoHeight = false; 195 | } 196 | } 197 | }; 198 | 199 | }(jQuery)); -------------------------------------------------------------------------------- /js/fancybox/helpers/jquery.fancybox-thumbs.css: -------------------------------------------------------------------------------- 1 | #fancybox-thumbs { 2 | position: fixed; 3 | left: 0; 4 | width: 100%; 5 | overflow: hidden; 6 | z-index: 8050; 7 | } 8 | 9 | #fancybox-thumbs.bottom { 10 | bottom: 2px; 11 | } 12 | 13 | #fancybox-thumbs.top { 14 | top: 2px; 15 | } 16 | 17 | #fancybox-thumbs ul { 18 | position: relative; 19 | list-style: none; 20 | margin: 0; 21 | padding: 0; 22 | } 23 | 24 | #fancybox-thumbs ul li { 25 | float: left; 26 | padding: 1px; 27 | opacity: 0.5; 28 | } 29 | 30 | #fancybox-thumbs ul li.active { 31 | opacity: 0.75; 32 | padding: 0; 33 | border: 1px solid #fff; 34 | } 35 | 36 | #fancybox-thumbs ul li:hover { 37 | opacity: 1; 38 | } 39 | 40 | #fancybox-thumbs ul li a { 41 | display: block; 42 | position: relative; 43 | overflow: hidden; 44 | border: 1px solid #222; 45 | background: #111; 46 | outline: none; 47 | } 48 | 49 | #fancybox-thumbs ul li img { 50 | display: block; 51 | position: relative; 52 | border: 0; 53 | padding: 0; 54 | max-width: none; 55 | } -------------------------------------------------------------------------------- /js/fancybox/helpers/jquery.fancybox-thumbs.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Thumbnail helper for fancyBox 3 | * version: 1.0.7 (Mon, 01 Oct 2012) 4 | * @requires fancyBox v2.0 or later 5 | * 6 | * Usage: 7 | * $(".fancybox").fancybox({ 8 | * helpers : { 9 | * thumbs: { 10 | * width : 50, 11 | * height : 50 12 | * } 13 | * } 14 | * }); 15 | * 16 | */ 17 | (function ($) { 18 | //Shortcut for fancyBox object 19 | var F = $.fancybox; 20 | 21 | //Add helper object 22 | F.helpers.thumbs = { 23 | defaults : { 24 | width : 50, // thumbnail width 25 | height : 50, // thumbnail height 26 | position : 'bottom', // 'top' or 'bottom' 27 | source : function ( item ) { // function to obtain the URL of the thumbnail image 28 | var href; 29 | 30 | if (item.element) { 31 | href = $(item.element).find('img').attr('src'); 32 | } 33 | 34 | if (!href && item.type === 'image' && item.href) { 35 | href = item.href; 36 | } 37 | 38 | return href; 39 | } 40 | }, 41 | 42 | wrap : null, 43 | list : null, 44 | width : 0, 45 | 46 | init: function (opts, obj) { 47 | var that = this, 48 | list, 49 | thumbWidth = opts.width, 50 | thumbHeight = opts.height, 51 | thumbSource = opts.source; 52 | 53 | //Build list structure 54 | list = ''; 55 | 56 | for (var n = 0; n < obj.group.length; n++) { 57 | list += '
  • '; 58 | } 59 | 60 | this.wrap = $('
    ').addClass(opts.position).appendTo('body'); 61 | this.list = $('').appendTo(this.wrap); 62 | 63 | //Load each thumbnail 64 | $.each(obj.group, function (i) { 65 | var href = thumbSource( obj.group[ i ] ); 66 | 67 | if (!href) { 68 | return; 69 | } 70 | 71 | $("").load(function () { 72 | var width = this.width, 73 | height = this.height, 74 | widthRatio, heightRatio, parent; 75 | 76 | if (!that.list || !width || !height) { 77 | return; 78 | } 79 | 80 | //Calculate thumbnail width/height and center it 81 | widthRatio = width / thumbWidth; 82 | heightRatio = height / thumbHeight; 83 | 84 | parent = that.list.children().eq(i).find('a'); 85 | 86 | if (widthRatio >= 1 && heightRatio >= 1) { 87 | if (widthRatio > heightRatio) { 88 | width = Math.floor(width / heightRatio); 89 | height = thumbHeight; 90 | 91 | } else { 92 | width = thumbWidth; 93 | height = Math.floor(height / widthRatio); 94 | } 95 | } 96 | 97 | $(this).css({ 98 | width : width, 99 | height : height, 100 | top : Math.floor(thumbHeight / 2 - height / 2), 101 | left : Math.floor(thumbWidth / 2 - width / 2) 102 | }); 103 | 104 | parent.width(thumbWidth).height(thumbHeight); 105 | 106 | $(this).hide().appendTo(parent).fadeIn(300); 107 | 108 | }).attr('src', href); 109 | }); 110 | 111 | //Set initial width 112 | this.width = this.list.children().eq(0).outerWidth(true); 113 | 114 | this.list.width(this.width * (obj.group.length + 1)).css('left', Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5))); 115 | }, 116 | 117 | beforeLoad: function (opts, obj) { 118 | //Remove self if gallery do not have at least two items 119 | if (obj.group.length < 2) { 120 | obj.helpers.thumbs = false; 121 | 122 | return; 123 | } 124 | 125 | //Increase bottom margin to give space for thumbs 126 | obj.margin[ opts.position === 'top' ? 0 : 2 ] += ((opts.height) + 15); 127 | }, 128 | 129 | afterShow: function (opts, obj) { 130 | //Check if exists and create or update list 131 | if (this.list) { 132 | this.onUpdate(opts, obj); 133 | 134 | } else { 135 | this.init(opts, obj); 136 | } 137 | 138 | //Set active element 139 | this.list.children().removeClass('active').eq(obj.index).addClass('active'); 140 | }, 141 | 142 | //Center list 143 | onUpdate: function (opts, obj) { 144 | if (this.list) { 145 | this.list.stop(true).animate({ 146 | 'left': Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5)) 147 | }, 150); 148 | } 149 | }, 150 | 151 | beforeClose: function () { 152 | if (this.wrap) { 153 | this.wrap.remove(); 154 | } 155 | 156 | this.wrap = null; 157 | this.list = null; 158 | this.width = 0; 159 | } 160 | } 161 | 162 | }(jQuery)); -------------------------------------------------------------------------------- /js/fancybox/jquery.fancybox.css: -------------------------------------------------------------------------------- 1 | /*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */ 2 | .fancybox-wrap, 3 | .fancybox-skin, 4 | .fancybox-outer, 5 | .fancybox-inner, 6 | .fancybox-image, 7 | .fancybox-wrap iframe, 8 | .fancybox-wrap object, 9 | .fancybox-nav, 10 | .fancybox-nav span, 11 | .fancybox-tmp 12 | { 13 | padding: 0; 14 | margin: 0; 15 | border: 0; 16 | outline: none; 17 | vertical-align: top; 18 | } 19 | 20 | .fancybox-wrap { 21 | position: absolute; 22 | top: 0; 23 | left: 0; 24 | z-index: 8020; 25 | } 26 | 27 | .fancybox-skin { 28 | position: relative; 29 | background: #f9f9f9; 30 | color: #444; 31 | text-shadow: none; 32 | -webkit-border-radius: 4px; 33 | -moz-border-radius: 4px; 34 | border-radius: 4px; 35 | } 36 | 37 | .fancybox-opened { 38 | z-index: 8030; 39 | } 40 | 41 | .fancybox-opened .fancybox-skin { 42 | -webkit-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); 43 | -moz-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); 44 | box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); 45 | } 46 | 47 | .fancybox-outer, .fancybox-inner { 48 | position: relative; 49 | } 50 | 51 | .fancybox-inner { 52 | overflow: hidden; 53 | } 54 | 55 | .fancybox-type-iframe .fancybox-inner { 56 | -webkit-overflow-scrolling: touch; 57 | } 58 | 59 | .fancybox-error { 60 | color: #444; 61 | font: 14px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; 62 | margin: 0; 63 | padding: 15px; 64 | white-space: nowrap; 65 | } 66 | 67 | .fancybox-image, .fancybox-iframe { 68 | display: block; 69 | width: 100%; 70 | height: 100%; 71 | } 72 | 73 | .fancybox-image { 74 | max-width: 100%; 75 | max-height: 100%; 76 | } 77 | 78 | #fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span { 79 | background-image: url('fancybox_sprite.png'); 80 | } 81 | 82 | #fancybox-loading { 83 | position: fixed; 84 | top: 50%; 85 | left: 50%; 86 | margin-top: -22px; 87 | margin-left: -22px; 88 | background-position: 0 -108px; 89 | opacity: 0.8; 90 | cursor: pointer; 91 | z-index: 8060; 92 | } 93 | 94 | #fancybox-loading div { 95 | width: 44px; 96 | height: 44px; 97 | background: url('fancybox_loading.gif') center center no-repeat; 98 | } 99 | 100 | .fancybox-close { 101 | position: absolute; 102 | top: -18px; 103 | right: -18px; 104 | width: 36px; 105 | height: 36px; 106 | cursor: pointer; 107 | z-index: 8040; 108 | } 109 | 110 | .fancybox-nav { 111 | position: absolute; 112 | top: 0; 113 | width: 40%; 114 | height: 100%; 115 | cursor: pointer; 116 | text-decoration: none; 117 | background: transparent url('blank.gif'); /* helps IE */ 118 | -webkit-tap-highlight-color: rgba(0,0,0,0); 119 | z-index: 8040; 120 | } 121 | 122 | .fancybox-prev { 123 | left: 0; 124 | } 125 | 126 | .fancybox-next { 127 | right: 0; 128 | } 129 | 130 | .fancybox-nav span { 131 | position: absolute; 132 | top: 50%; 133 | width: 36px; 134 | height: 34px; 135 | margin-top: -18px; 136 | cursor: pointer; 137 | z-index: 8040; 138 | visibility: hidden; 139 | } 140 | 141 | .fancybox-prev span { 142 | left: 10px; 143 | background-position: 0 -36px; 144 | } 145 | 146 | .fancybox-next span { 147 | right: 10px; 148 | background-position: 0 -72px; 149 | } 150 | 151 | .fancybox-nav:hover span { 152 | visibility: visible; 153 | } 154 | 155 | .fancybox-tmp { 156 | position: absolute; 157 | top: -99999px; 158 | left: -99999px; 159 | visibility: hidden; 160 | max-width: 99999px; 161 | max-height: 99999px; 162 | overflow: visible !important; 163 | } 164 | 165 | /* Overlay helper */ 166 | 167 | .fancybox-lock { 168 | overflow: hidden !important; 169 | width: auto; 170 | } 171 | 172 | .fancybox-lock body { 173 | overflow: hidden !important; 174 | } 175 | 176 | .fancybox-lock-test { 177 | overflow-y: hidden !important; 178 | } 179 | 180 | .fancybox-overlay { 181 | position: absolute; 182 | top: 0; 183 | left: 0; 184 | overflow: hidden; 185 | display: none; 186 | z-index: 8010; 187 | background: url('fancybox_overlay.png'); 188 | } 189 | 190 | .fancybox-overlay-fixed { 191 | position: fixed; 192 | bottom: 0; 193 | right: 0; 194 | } 195 | 196 | .fancybox-lock .fancybox-overlay { 197 | overflow: auto; 198 | overflow-y: scroll; 199 | } 200 | 201 | /* Title helper */ 202 | 203 | .fancybox-title { 204 | visibility: hidden; 205 | font: normal 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; 206 | position: relative; 207 | text-shadow: none; 208 | z-index: 8050; 209 | } 210 | 211 | .fancybox-opened .fancybox-title { 212 | visibility: visible; 213 | } 214 | 215 | .fancybox-title-float-wrap { 216 | position: absolute; 217 | bottom: 0; 218 | right: 50%; 219 | margin-bottom: -35px; 220 | z-index: 8050; 221 | text-align: center; 222 | } 223 | 224 | .fancybox-title-float-wrap .child { 225 | display: inline-block; 226 | margin-right: -100%; 227 | padding: 2px 20px; 228 | background: transparent; /* Fallback for web browsers that doesn't support RGBa */ 229 | background: rgba(0, 0, 0, 0.8); 230 | -webkit-border-radius: 15px; 231 | -moz-border-radius: 15px; 232 | border-radius: 15px; 233 | text-shadow: 0 1px 2px #222; 234 | color: #FFF; 235 | font-weight: bold; 236 | line-height: 24px; 237 | white-space: nowrap; 238 | } 239 | 240 | .fancybox-title-outside-wrap { 241 | position: relative; 242 | margin-top: 10px; 243 | color: #fff; 244 | } 245 | 246 | .fancybox-title-inside-wrap { 247 | padding-top: 10px; 248 | } 249 | 250 | .fancybox-title-over-wrap { 251 | position: absolute; 252 | bottom: 0; 253 | left: 0; 254 | color: #fff; 255 | padding: 10px; 256 | background: #000; 257 | background: rgba(0, 0, 0, .8); 258 | } 259 | 260 | /*Retina graphics!*/ 261 | @media only screen and (-webkit-min-device-pixel-ratio: 1.5), 262 | only screen and (min--moz-device-pixel-ratio: 1.5), 263 | only screen and (min-device-pixel-ratio: 1.5){ 264 | 265 | #fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span { 266 | background-image: url('fancybox_sprite@2x.png'); 267 | background-size: 44px 152px; /*The size of the normal image, half the size of the hi-res image*/ 268 | } 269 | 270 | #fancybox-loading div { 271 | background-image: url('fancybox_loading@2x.gif'); 272 | background-size: 24px 24px; /*The size of the normal image, half the size of the hi-res image*/ 273 | } 274 | } -------------------------------------------------------------------------------- /js/fancybox/jquery.fancybox.pack.js: -------------------------------------------------------------------------------- 1 | /*! fancyBox v2.1.5 fancyapps.com | fancyapps.com/fancybox/#license */ 2 | (function(r,G,f,v){var J=f("html"),n=f(r),p=f(G),b=f.fancybox=function(){b.open.apply(this,arguments)},I=navigator.userAgent.match(/msie/i),B=null,s=G.createTouch!==v,t=function(a){return a&&a.hasOwnProperty&&a instanceof f},q=function(a){return a&&"string"===f.type(a)},E=function(a){return q(a)&&0
    ',image:'',iframe:'",error:'

    The requested content cannot be loaded.
    Please try again later.

    ',closeBtn:'',next:'',prev:''},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0, 6 | openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:250,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",prevSpeed:250,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:!0,title:!0},onCancel:f.noop,beforeLoad:f.noop,afterLoad:f.noop,beforeShow:f.noop,afterShow:f.noop,beforeChange:f.noop,beforeClose:f.noop,afterClose:f.noop},group:{},opts:{},previous:null,coming:null,current:null,isActive:!1, 7 | isOpen:!1,isOpened:!1,wrap:null,skin:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(a,d){if(a&&(f.isPlainObject(d)||(d={}),!1!==b.close(!0)))return f.isArray(a)||(a=t(a)?f(a).get():[a]),f.each(a,function(e,c){var k={},g,h,j,m,l;"object"===f.type(c)&&(c.nodeType&&(c=f(c)),t(c)?(k={href:c.data("fancybox-href")||c.attr("href"),title:c.data("fancybox-title")||c.attr("title"),isDom:!0,element:c},f.metadata&&f.extend(!0,k, 8 | c.metadata())):k=c);g=d.href||k.href||(q(c)?c:null);h=d.title!==v?d.title:k.title||"";m=(j=d.content||k.content)?"html":d.type||k.type;!m&&k.isDom&&(m=c.data("fancybox-type"),m||(m=(m=c.prop("class").match(/fancybox\.(\w+)/))?m[1]:null));q(g)&&(m||(b.isImage(g)?m="image":b.isSWF(g)?m="swf":"#"===g.charAt(0)?m="inline":q(c)&&(m="html",j=c)),"ajax"===m&&(l=g.split(/\s+/,2),g=l.shift(),l=l.shift()));j||("inline"===m?g?j=f(q(g)?g.replace(/.*(?=#[^\s]+$)/,""):g):k.isDom&&(j=c):"html"===m?j=g:!m&&(!g&& 9 | k.isDom)&&(m="inline",j=c));f.extend(k,{href:g,type:m,content:j,title:h,selector:l});a[e]=k}),b.opts=f.extend(!0,{},b.defaults,d),d.keys!==v&&(b.opts.keys=d.keys?f.extend({},b.defaults.keys,d.keys):!1),b.group=a,b._start(b.opts.index)},cancel:function(){var a=b.coming;a&&!1!==b.trigger("onCancel")&&(b.hideLoading(),b.ajaxLoad&&b.ajaxLoad.abort(),b.ajaxLoad=null,b.imgPreload&&(b.imgPreload.onload=b.imgPreload.onerror=null),a.wrap&&a.wrap.stop(!0,!0).trigger("onReset").remove(),b.coming=null,b.current|| 10 | b._afterZoomOut(a))},close:function(a){b.cancel();!1!==b.trigger("beforeClose")&&(b.unbindEvents(),b.isActive&&(!b.isOpen||!0===a?(f(".fancybox-wrap").stop(!0).trigger("onReset").remove(),b._afterZoomOut()):(b.isOpen=b.isOpened=!1,b.isClosing=!0,f(".fancybox-item, .fancybox-nav").remove(),b.wrap.stop(!0,!0).removeClass("fancybox-opened"),b.transitions[b.current.closeMethod]())))},play:function(a){var d=function(){clearTimeout(b.player.timer)},e=function(){d();b.current&&b.player.isActive&&(b.player.timer= 11 | setTimeout(b.next,b.current.playSpeed))},c=function(){d();p.unbind(".player");b.player.isActive=!1;b.trigger("onPlayEnd")};if(!0===a||!b.player.isActive&&!1!==a){if(b.current&&(b.current.loop||b.current.index=c.index?"next":"prev"],b.router=e||"jumpto",c.loop&&(0>a&&(a=c.group.length+a%c.group.length),a%=c.group.length),c.group[a]!==v&&(b.cancel(),b._start(a)))},reposition:function(a,d){var e=b.current,c=e?e.wrap:null,k;c&&(k=b._getPosition(d),a&&"scroll"===a.type?(delete k.position,c.stop(!0,!0).animate(k,200)):(c.css(k),e.pos=f.extend({},e.dim,k)))},update:function(a){var d= 13 | a&&a.type,e=!d||"orientationchange"===d;e&&(clearTimeout(B),B=null);b.isOpen&&!B&&(B=setTimeout(function(){var c=b.current;c&&!b.isClosing&&(b.wrap.removeClass("fancybox-tmp"),(e||"load"===d||"resize"===d&&c.autoResize)&&b._setDimension(),"scroll"===d&&c.canShrink||b.reposition(a),b.trigger("onUpdate"),B=null)},e&&!s?0:300))},toggle:function(a){b.isOpen&&(b.current.fitToView="boolean"===f.type(a)?a:!b.current.fitToView,s&&(b.wrap.removeAttr("style").addClass("fancybox-tmp"),b.trigger("onUpdate")), 14 | b.update())},hideLoading:function(){p.unbind(".loading");f("#fancybox-loading").remove()},showLoading:function(){var a,d;b.hideLoading();a=f('
    ').click(b.cancel).appendTo("body");p.bind("keydown.loading",function(a){if(27===(a.which||a.keyCode))a.preventDefault(),b.cancel()});b.defaults.fixed||(d=b.getViewport(),a.css({position:"absolute",top:0.5*d.h+d.y,left:0.5*d.w+d.x}))},getViewport:function(){var a=b.current&&b.current.locked||!1,d={x:n.scrollLeft(), 15 | y:n.scrollTop()};a?(d.w=a[0].clientWidth,d.h=a[0].clientHeight):(d.w=s&&r.innerWidth?r.innerWidth:n.width(),d.h=s&&r.innerHeight?r.innerHeight:n.height());return d},unbindEvents:function(){b.wrap&&t(b.wrap)&&b.wrap.unbind(".fb");p.unbind(".fb");n.unbind(".fb")},bindEvents:function(){var a=b.current,d;a&&(n.bind("orientationchange.fb"+(s?"":" resize.fb")+(a.autoCenter&&!a.locked?" scroll.fb":""),b.update),(d=a.keys)&&p.bind("keydown.fb",function(e){var c=e.which||e.keyCode,k=e.target||e.srcElement; 16 | if(27===c&&b.coming)return!1;!e.ctrlKey&&(!e.altKey&&!e.shiftKey&&!e.metaKey&&(!k||!k.type&&!f(k).is("[contenteditable]")))&&f.each(d,function(d,k){if(1h[0].clientWidth||h[0].clientHeight&&h[0].scrollHeight>h[0].clientHeight),h=f(h).parent();if(0!==c&&!j&&1g||0>k)b.next(0>g?"up":"right");d.preventDefault()}}))},trigger:function(a,d){var e,c=d||b.coming||b.current;if(c){f.isFunction(c[a])&&(e=c[a].apply(c,Array.prototype.slice.call(arguments,1)));if(!1===e)return!1;c.helpers&&f.each(c.helpers,function(d,e){if(e&&b.helpers[d]&&f.isFunction(b.helpers[d][a]))b.helpers[d][a](f.extend(!0, 18 | {},b.helpers[d].defaults,e),c)});p.trigger(a)}},isImage:function(a){return q(a)&&a.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)},isSWF:function(a){return q(a)&&a.match(/\.(swf)((\?|#).*)?$/i)},_start:function(a){var d={},e,c;a=l(a);e=b.group[a]||null;if(!e)return!1;d=f.extend(!0,{},b.opts,e);e=d.margin;c=d.padding;"number"===f.type(e)&&(d.margin=[e,e,e,e]);"number"===f.type(c)&&(d.padding=[c,c,c,c]);d.modal&&f.extend(!0,d,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1, 19 | mouseWheel:!1,keys:null,helpers:{overlay:{closeClick:!1}}});d.autoSize&&(d.autoWidth=d.autoHeight=!0);"auto"===d.width&&(d.autoWidth=!0);"auto"===d.height&&(d.autoHeight=!0);d.group=b.group;d.index=a;b.coming=d;if(!1===b.trigger("beforeLoad"))b.coming=null;else{c=d.type;e=d.href;if(!c)return b.coming=null,b.current&&b.router&&"jumpto"!==b.router?(b.current.index=a,b[b.router](b.direction)):!1;b.isActive=!0;if("image"===c||"swf"===c)d.autoHeight=d.autoWidth=!1,d.scrolling="visible";"image"===c&&(d.aspectRatio= 20 | !0);"iframe"===c&&s&&(d.scrolling="scroll");d.wrap=f(d.tpl.wrap).addClass("fancybox-"+(s?"mobile":"desktop")+" fancybox-type-"+c+" fancybox-tmp "+d.wrapCSS).appendTo(d.parent||"body");f.extend(d,{skin:f(".fancybox-skin",d.wrap),outer:f(".fancybox-outer",d.wrap),inner:f(".fancybox-inner",d.wrap)});f.each(["Top","Right","Bottom","Left"],function(a,b){d.skin.css("padding"+b,w(d.padding[a]))});b.trigger("onReady");if("inline"===c||"html"===c){if(!d.content||!d.content.length)return b._error("content")}else if(!e)return b._error("href"); 21 | "image"===c?b._loadImage():"ajax"===c?b._loadAjax():"iframe"===c?b._loadIframe():b._afterLoad()}},_error:function(a){f.extend(b.coming,{type:"html",autoWidth:!0,autoHeight:!0,minWidth:0,minHeight:0,scrolling:"no",hasError:a,content:b.coming.tpl.error});b._afterLoad()},_loadImage:function(){var a=b.imgPreload=new Image;a.onload=function(){this.onload=this.onerror=null;b.coming.width=this.width/b.opts.pixelRatio;b.coming.height=this.height/b.opts.pixelRatio;b._afterLoad()};a.onerror=function(){this.onload= 22 | this.onerror=null;b._error("image")};a.src=b.coming.href;!0!==a.complete&&b.showLoading()},_loadAjax:function(){var a=b.coming;b.showLoading();b.ajaxLoad=f.ajax(f.extend({},a.ajax,{url:a.href,error:function(a,e){b.coming&&"abort"!==e?b._error("ajax",a):b.hideLoading()},success:function(d,e){"success"===e&&(a.content=d,b._afterLoad())}}))},_loadIframe:function(){var a=b.coming,d=f(a.tpl.iframe.replace(/\{rnd\}/g,(new Date).getTime())).attr("scrolling",s?"auto":a.iframe.scrolling).attr("src",a.href); 23 | f(a.wrap).bind("onReset",function(){try{f(this).find("iframe").hide().attr("src","//about:blank").end().empty()}catch(a){}});a.iframe.preload&&(b.showLoading(),d.one("load",function(){f(this).data("ready",1);s||f(this).bind("load.fb",b.update);f(this).parents(".fancybox-wrap").width("100%").removeClass("fancybox-tmp").show();b._afterLoad()}));a.content=d.appendTo(a.inner);a.iframe.preload||b._afterLoad()},_preloadImages:function(){var a=b.group,d=b.current,e=a.length,c=d.preload?Math.min(d.preload, 24 | e-1):0,f,g;for(g=1;g<=c;g+=1)f=a[(d.index+g)%e],"image"===f.type&&f.href&&((new Image).src=f.href)},_afterLoad:function(){var a=b.coming,d=b.current,e,c,k,g,h;b.hideLoading();if(a&&!1!==b.isActive)if(!1===b.trigger("afterLoad",a,d))a.wrap.stop(!0).trigger("onReset").remove(),b.coming=null;else{d&&(b.trigger("beforeChange",d),d.wrap.stop(!0).removeClass("fancybox-opened").find(".fancybox-item, .fancybox-nav").remove());b.unbindEvents();e=a.content;c=a.type;k=a.scrolling;f.extend(b,{wrap:a.wrap,skin:a.skin, 25 | outer:a.outer,inner:a.inner,current:a,previous:d});g=a.href;switch(c){case "inline":case "ajax":case "html":a.selector?e=f("
    ").html(e).find(a.selector):t(e)&&(e.data("fancybox-placeholder")||e.data("fancybox-placeholder",f('
    ').insertAfter(e).hide()),e=e.show().detach(),a.wrap.bind("onReset",function(){f(this).find(e).length&&e.hide().replaceAll(e.data("fancybox-placeholder")).data("fancybox-placeholder",!1)}));break;case "image":e=a.tpl.image.replace("{href}", 26 | g);break;case "swf":e='',h="",f.each(a.swf,function(a,b){e+='';h+=" "+a+'="'+b+'"'}),e+='"}(!t(e)||!e.parent().is(a.inner))&&a.inner.append(e);b.trigger("beforeShow");a.inner.css("overflow","yes"===k?"scroll": 27 | "no"===k?"hidden":k);b._setDimension();b.reposition();b.isOpen=!1;b.coming=null;b.bindEvents();if(b.isOpened){if(d.prevMethod)b.transitions[d.prevMethod]()}else f(".fancybox-wrap").not(a.wrap).stop(!0).trigger("onReset").remove();b.transitions[b.isOpened?a.nextMethod:a.openMethod]();b._preloadImages()}},_setDimension:function(){var a=b.getViewport(),d=0,e=!1,c=!1,e=b.wrap,k=b.skin,g=b.inner,h=b.current,c=h.width,j=h.height,m=h.minWidth,u=h.minHeight,n=h.maxWidth,p=h.maxHeight,s=h.scrolling,q=h.scrollOutside? 28 | h.scrollbarWidth:0,x=h.margin,y=l(x[1]+x[3]),r=l(x[0]+x[2]),v,z,t,C,A,F,B,D,H;e.add(k).add(g).width("auto").height("auto").removeClass("fancybox-tmp");x=l(k.outerWidth(!0)-k.width());v=l(k.outerHeight(!0)-k.height());z=y+x;t=r+v;C=E(c)?(a.w-z)*l(c)/100:c;A=E(j)?(a.h-t)*l(j)/100:j;if("iframe"===h.type){if(H=h.content,h.autoHeight&&1===H.data("ready"))try{H[0].contentWindow.document.location&&(g.width(C).height(9999),F=H.contents().find("body"),q&&F.css("overflow-x","hidden"),A=F.outerHeight(!0))}catch(G){}}else if(h.autoWidth|| 29 | h.autoHeight)g.addClass("fancybox-tmp"),h.autoWidth||g.width(C),h.autoHeight||g.height(A),h.autoWidth&&(C=g.width()),h.autoHeight&&(A=g.height()),g.removeClass("fancybox-tmp");c=l(C);j=l(A);D=C/A;m=l(E(m)?l(m,"w")-z:m);n=l(E(n)?l(n,"w")-z:n);u=l(E(u)?l(u,"h")-t:u);p=l(E(p)?l(p,"h")-t:p);F=n;B=p;h.fitToView&&(n=Math.min(a.w-z,n),p=Math.min(a.h-t,p));z=a.w-y;r=a.h-r;h.aspectRatio?(c>n&&(c=n,j=l(c/D)),j>p&&(j=p,c=l(j*D)),cz||y>r)&&(c>m&&j>u)&&!(19n&&(c=n,j=l(c/D)),g.width(c).height(j),e.width(c+x),a=e.width(),y=e.height();else c=Math.max(m,Math.min(c,c-(a-z))),j=Math.max(u,Math.min(j,j-(y-r)));q&&("auto"===s&&jz||y>r)&&c>m&&j>u;c=h.aspectRatio?cu&&j
    ').appendTo(b.coming?b.coming.parent:a.parent);this.fixed=!1;a.fixed&&b.defaults.fixed&&(this.overlay.addClass("fancybox-overlay-fixed"),this.fixed=!0)},open:function(a){var d=this;a=f.extend({},this.defaults,a);this.overlay?this.overlay.unbind(".overlay").width("auto").height("auto"):this.create(a);this.fixed||(n.bind("resize.overlay",f.proxy(this.update,this)),this.update());a.closeClick&&this.overlay.bind("click.overlay",function(a){if(f(a.target).hasClass("fancybox-overlay"))return b.isActive? 40 | b.close():d.close(),!1});this.overlay.css(a.css).show()},close:function(){var a,b;n.unbind("resize.overlay");this.el.hasClass("fancybox-lock")&&(f(".fancybox-margin").removeClass("fancybox-margin"),a=n.scrollTop(),b=n.scrollLeft(),this.el.removeClass("fancybox-lock"),n.scrollTop(a).scrollLeft(b));f(".fancybox-overlay").remove().hide();f.extend(this,{overlay:null,fixed:!1})},update:function(){var a="100%",b;this.overlay.width(a).height("100%");I?(b=Math.max(G.documentElement.offsetWidth,G.body.offsetWidth), 41 | p.width()>b&&(a=p.width())):p.width()>n.width()&&(a=p.width());this.overlay.width(a).height(p.height())},onReady:function(a,b){var e=this.overlay;f(".fancybox-overlay").stop(!0,!0);e||this.create(a);a.locked&&(this.fixed&&b.fixed)&&(e||(this.margin=p.height()>n.height()?f("html").css("margin-right").replace("px",""):!1),b.locked=this.overlay.append(b.wrap),b.fixed=!1);!0===a.showEarly&&this.beforeShow.apply(this,arguments)},beforeShow:function(a,b){var e,c;b.locked&&(!1!==this.margin&&(f("*").filter(function(){return"fixed"=== 42 | f(this).css("position")&&!f(this).hasClass("fancybox-overlay")&&!f(this).hasClass("fancybox-wrap")}).addClass("fancybox-margin"),this.el.addClass("fancybox-margin")),e=n.scrollTop(),c=n.scrollLeft(),this.el.addClass("fancybox-lock"),n.scrollTop(e).scrollLeft(c));this.open(a)},onUpdate:function(){this.fixed||this.update()},afterClose:function(a){this.overlay&&!b.coming&&this.overlay.fadeOut(a.speedOut,f.proxy(this.close,this))}};b.helpers.title={defaults:{type:"float",position:"bottom"},beforeShow:function(a){var d= 43 | b.current,e=d.title,c=a.type;f.isFunction(e)&&(e=e.call(d.element,d));if(q(e)&&""!==f.trim(e)){d=f('
    '+e+"
    ");switch(c){case "inside":c=b.skin;break;case "outside":c=b.wrap;break;case "over":c=b.inner;break;default:c=b.skin,d.appendTo("body"),I&&d.width(d.width()),d.wrapInner(''),b.current.margin[2]+=Math.abs(l(d.css("margin-bottom")))}d["top"===a.position?"prependTo":"appendTo"](c)}}};f.fn.fancybox=function(a){var d, 44 | e=f(this),c=this.selector||"",k=function(g){var h=f(this).blur(),j=d,k,l;!g.ctrlKey&&(!g.altKey&&!g.shiftKey&&!g.metaKey)&&!h.is(".fancybox-wrap")&&(k=a.groupAttr||"data-fancybox-group",l=h.attr(k),l||(k="rel",l=h.get(0)[k]),l&&(""!==l&&"nofollow"!==l)&&(h=c.length?f(c):e,h=h.filter("["+k+'="'+l+'"]'),j=h.index(this)),a.index=j,!1!==b.open(h,a)&&g.preventDefault())};a=a||{};d=a.index||0;!c||!1===a.live?e.unbind("click.fb-start").bind("click.fb-start",k):p.undelegate(c,"click.fb-start").delegate(c+ 45 | ":not('.fancybox-item, .fancybox-nav')","click.fb-start",k);this.filter("[data-fancybox-start=1]").trigger("click");return this};p.ready(function(){var a,d;f.scrollbarWidth===v&&(f.scrollbarWidth=function(){var a=f('
    ').appendTo("body"),b=a.children(),b=b.innerWidth()-b.height(99).innerWidth();a.remove();return b});if(f.support.fixedPosition===v){a=f.support;d=f('
    ').appendTo("body");var e=20=== 46 | d[0].offsetTop||15===d[0].offsetTop;d.remove();a.fixedPosition=e}f.extend(b.defaults,{scrollbarWidth:f.scrollbarWidth(),fixed:f.support.fixedPosition,parent:f("body")});a=f(r).width();J.addClass("fancybox-lock-test");d=f(r).width();J.removeClass("fancybox-lock-test");f("").appendTo("head")})})(window,document,jQuery); -------------------------------------------------------------------------------- /js/html5shiv.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); 8 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document); -------------------------------------------------------------------------------- /js/jquery.fullbg.js: -------------------------------------------------------------------------------- 1 | /*! Backstretch - v2.0.4 - 2013-06-19 2 | * http://srobbin.com/jquery-plugins/backstretch/ 3 | * Copyright (c) 2013 Scott Robbin; Licensed MIT */ 4 | (function(a,d,p){a.fn.backstretch=function(c,b){(c===p||0===c.length)&&a.error("No images were supplied for Backstretch");0===a(d).scrollTop()&&d.scrollTo(0,0);return this.each(function(){var d=a(this),g=d.data("backstretch");if(g){if("string"==typeof c&&"function"==typeof g[c]){g[c](b);return}b=a.extend(g.options,b);g.destroy(!0)}g=new q(this,c,b);d.data("backstretch",g)})};a.backstretch=function(c,b){return a("body").backstretch(c,b).data("backstretch")};a.expr[":"].backstretch=function(c){return a(c).data("backstretch")!==p};a.fn.backstretch.defaults={centeredX:!0,centeredY:!0,duration:5E3,fade:0};var r={left:0,top:0,overflow:"hidden",margin:0,padding:0,height:"100%",width:"100%",zIndex:-999999},s={position:"absolute",display:"none",margin:0,padding:0,border:"none",width:"auto",height:"auto",maxHeight:"none",maxWidth:"none",zIndex:-999999},q=function(c,b,e){this.options=a.extend({},a.fn.backstretch.defaults,e||{});this.images=a.isArray(b)?b:[b];a.each(this.images,function(){a("")[0].src=this});this.isBody=c===document.body;this.$container=a(c);this.$root=this.isBody?l?a(d):a(document):this.$container;c=this.$container.children(".backstretch").first();this.$wrap=c.length?c:a('
    ').css(r).appendTo(this.$container);this.isBody||(c=this.$container.css("position"),b=this.$container.css("zIndex"),this.$container.css({position:"static"===c?"relative":c,zIndex:"auto"===b?0:b,background:"none"}),this.$wrap.css({zIndex:-999998}));this.$wrap.css({position:this.isBody&&l?"fixed":"absolute"});this.index=0;this.show(this.index);a(d).on("resize.backstretch",a.proxy(this.resize,this)).on("orientationchange.backstretch",a.proxy(function(){this.isBody&&0===d.pageYOffset&&(d.scrollTo(0,1),this.resize())},this))};q.prototype={resize:function(){try{var a={left:0,top:0},b=this.isBody?this.$root.width():this.$root.innerWidth(),e=b,g=this.isBody?d.innerHeight?d.innerHeight:this.$root.height():this.$root.innerHeight(),j=e/this.$img.data("ratio"),f;j>=g?(f=(j-g)/2,this.options.centeredY&&(a.top="-"+f+"px")):(j=g,e=j*this.$img.data("ratio"),f=(e-b)/2,this.options.centeredX&&(a.left="-"+f+"px"));this.$wrap.css({width:b,height:g}).find("img:not(.deleteable)").css({width:e,height:j}).css(a)}catch(h){}return this},show:function(c){if(!(Math.abs(c)>this.images.length-1)){var b=this,e=b.$wrap.find("img").addClass("deleteable"),d={relatedTarget:b.$container[0]};b.$container.trigger(a.Event("backstretch.before",d),[b,c]);this.index=c;clearInterval(b.interval);b.$img=a("").css(s).bind("load",function(f){var h=this.width||a(f.target).width();f=this.height||a(f.target).height();a(this).data("ratio",h/f);a(this).fadeIn(b.options.speed||b.options.fade,function(){e.remove();b.paused||b.cycle();a(["after","show"]).each(function(){b.$container.trigger(a.Event("backstretch."+this,d),[b,c])})});b.resize()}).appendTo(b.$wrap);b.$img.attr("src",b.images[c]);return b}},next:function(){return this.show(this.indexe||d.operamini&&"[object OperaMini]"==={}.toString.call(d.operamini)||n&&7458>t||-1e||h&&6>h||"palmGetResource"in d&&e&&534>e||-1=k)})(jQuery,window); -------------------------------------------------------------------------------- /js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /js/pagination.js: -------------------------------------------------------------------------------- 1 | (function(e,d,a,f){var b=e.fn.twbsPagination;var c=function(h,g){this.$element=e(h);this.options=e.extend({},e.fn.twbsPagination.defaults,g);this.init(this.options)};c.prototype={constructor:c,init:function(g){this.options=e.extend({},this.options,g);if(this.options.startPage<1||this.options.startPage>this.options.totalPages){throw new Error("Start page option is incorrect")}if(this.options.totalPages<=0){throw new Error("Total pages option cannot be less 1 (one)!")}if(this.options.totalPages")}this.$listContainer.addClass(this.options.paginationClass);if(h!=="UL"){this.$element.append(this.$listContainer)}this.render(this.getPages(this.options.startPage));this.setupEvents();return this},destroy:function(){this.$element.empty();return this},show:function(g){if(g<1||g>this.options.totalPages){throw new Error("Page is incorrect.")}this.render(this.getPages(g));this.setupEvents();this.$element.trigger("page",g);return this},buildListItems:function(g){var j=e();if(this.options.first){j=j.add(this.buildItem("first",1))}if(this.options.prev){var l=g.currentPage>1?g.currentPage-1:1;j=j.add(this.buildItem("prev",l))}for(var h=0;h=this.options.totalPages?this.options.totalPages:g.currentPage+1;j=j.add(this.buildItem("next",k))}if(this.options.last){j=j.add(this.buildItem("last",this.options.totalPages))}return j},buildItem:function(i,j){var h=e("
  • "),k=e(""),g=null;h.addClass(i);h.data("page",j);switch(i){case"page":g=j;break;case"first":g=this.options.first;break;case"prev":g=this.options.prev;break;case"next":g=this.options.next;break;case"last":g=this.options.last;break;default:break}h.append(k.attr("href",this.href(j)).html(g));return h},getPages:function(j){var g=[];var k=Math.floor(this.options.visiblePages/2);var l=j-k+1-this.options.visiblePages%2;var h=j+k;if(l<=0){l=1;h=this.options.visiblePages}if(h>this.options.totalPages){l=this.options.totalPages-this.options.visiblePages+1;h=this.options.totalPages}var i=l;while(i<=h){g.push(i);i++}return{currentPage:j,numeric:g}},render:function(g){this.$listContainer.children().remove();this.$listContainer.append(this.buildListItems(g));this.$listContainer.find(".page").removeClass("active");this.$listContainer.find(".page").filter(function(){return e(this).data("page")===g.currentPage}).addClass("active");if(g.currentPage===1){this.$listContainer.find(".prev a,.first a").attr("href","javascript:void(0);")}if(g.currentPage===this.options.totalPages){this.$listContainer.find(".next a,.last a").attr("href","javascript:void(0);")}this.$listContainer.find(".first").toggleClass("disabled",g.currentPage===1);this.$listContainer.find(".last").toggleClass("disabled",g.currentPage===this.options.totalPages);this.$listContainer.find(".prev").toggleClass("disabled",g.currentPage===1);this.$listContainer.find(".next").toggleClass("disabled",g.currentPage===this.options.totalPages)},setupEvents:function(){var g=this;this.$listContainer.find("li").each(function(){var h=e(this);h.off();if(h.hasClass("disabled")||h.hasClass("active")){return}h.click(function(){g.show(parseInt(h.data("page"),10))})})},href:function(g){return this.options.href.replace(this.options.hrefVariable,g)}};e.fn.twbsPagination=function(i){var h=Array.prototype.slice.call(arguments,1);var k;var l=e(this);var j=l.data("twbs-pagination");var g=typeof i==="object"&&i;if(!j){l.data("twbs-pagination",(j=new c(this,g)))}if(typeof i==="string"){k=j[i].apply(j,h)}return(k===f)?l:k};e.fn.twbsPagination.defaults={totalPages:0,startPage:1,visiblePages:5,href:"javascript:void(0);",hrefVariable:"{{number}}",first:"First",prev:"Previous",next:"Next",last:"Last",paginationClass:"pagination",onPageClick:null};e.fn.twbsPagination.Constructor=c;e.fn.twbsPagination.noConflict=function(){e.fn.twbsPagination=b;return this}})(jQuery,window,document); -------------------------------------------------------------------------------- /js/respond.min.js: -------------------------------------------------------------------------------- 1 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 2 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 3 | window.matchMedia=window.matchMedia||function(a){"use strict";var c,d=a.documentElement,e=d.firstElementChild||d.firstChild,f=a.createElement("body"),g=a.createElement("div");return g.id="mq-test-1",g.style.cssText="position:absolute;top:-100em",f.style.background="none",f.appendChild(g),function(a){return g.innerHTML='­',d.insertBefore(f,e),c=42===g.offsetWidth,d.removeChild(f),{matches:c,media:a}}}(document); 4 | 5 | /*! Respond.js v1.3.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 6 | (function(a){"use strict";function x(){u(!0)}var b={};if(a.respond=b,b.update=function(){},b.mediaQueriesSupported=a.matchMedia&&a.matchMedia("only all").matches,!b.mediaQueriesSupported){var q,r,t,c=a.document,d=c.documentElement,e=[],f=[],g=[],h={},i=30,j=c.getElementsByTagName("head")[0]||d,k=c.getElementsByTagName("base")[0],l=j.getElementsByTagName("link"),m=[],n=function(){for(var b=0;l.length>b;b++){var c=l[b],d=c.href,e=c.media,f=c.rel&&"stylesheet"===c.rel.toLowerCase();d&&f&&!h[d]&&(c.styleSheet&&c.styleSheet.rawCssText?(p(c.styleSheet.rawCssText,d,e),h[d]=!0):(!/^([a-zA-Z:]*\/\/)/.test(d)&&!k||d.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&m.push({href:d,media:e}))}o()},o=function(){if(m.length){var b=m.shift();v(b.href,function(c){p(c,b.href,b.media),h[b.href]=!0,a.setTimeout(function(){o()},0)})}},p=function(a,b,c){var d=a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),g=d&&d.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+b+"$2$3")},i=!g&&c;b.length&&(b+="/"),i&&(g=1);for(var j=0;g>j;j++){var k,l,m,n;i?(k=c,f.push(h(a))):(k=d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,f.push(RegExp.$2&&h(RegExp.$2))),m=k.split(","),n=m.length;for(var o=0;n>o;o++)l=m[o],e.push({media:l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:f.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},s=function(){var a,b=c.createElement("div"),e=c.body,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",e||(e=f=c.createElement("body"),e.style.background="none"),e.appendChild(b),d.insertBefore(e,d.firstChild),a=b.offsetWidth,f?d.removeChild(e):e.removeChild(b),a=t=parseFloat(a)},u=function(b){var h="clientWidth",k=d[h],m="CSS1Compat"===c.compatMode&&k||c.body[h]||k,n={},o=l[l.length-1],p=(new Date).getTime();if(b&&q&&i>p-q)return a.clearTimeout(r),r=a.setTimeout(u,i),void 0;q=p;for(var v in e)if(e.hasOwnProperty(v)){var w=e[v],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?t||s():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?t||s():1)),w.hasquery&&(z&&A||!(z||m>=x)||!(A||y>=m))||(n[w.media]||(n[w.media]=[]),n[w.media].push(f[w.rules]))}for(var C in g)g.hasOwnProperty(C)&&g[C]&&g[C].parentNode===j&&j.removeChild(g[C]);for(var D in n)if(n.hasOwnProperty(D)){var E=c.createElement("style"),F=n[D].join("\n");E.type="text/css",E.media=D,j.insertBefore(E,o.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(c.createTextNode(F)),g.push(E)}},v=function(a,b){var c=w();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},w=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}();n(),b.update=n,a.addEventListener?a.addEventListener("resize",x,!1):a.attachEvent&&a.attachEvent("onresize",x)}})(this); -------------------------------------------------------------------------------- /killit.php: -------------------------------------------------------------------------------- 1 | fetch(PDO::FETCH_ASSOC); 14 | if ($result==FALSE) die('{"retcode":0,"msg":"SUCC"}'); //don't tell malicious person the id does not exist 15 | if(pstatus($result['pid'])) shell_exec("kill ".$result['pid']); 16 | die('{"retcode":0,"msg":"SUCC"}'); 17 | ?> 18 | -------------------------------------------------------------------------------- /log.php: -------------------------------------------------------------------------------- 1 | fetch(PDO::FETCH_ASSOC); 8 | if ($result==FALSE) die('THIS PROCESS DOES NOT EXISTS OR ALREADY TERMINATED AND REMOVED FROM THE SERVER!'); 9 | $results = ''; 10 | if(file_exists('qqbot/'.$result['id'].'/log.log')) $results = shell_exec('tail -n 30 qqbot/'.$result['id'].'/log.log'); 11 | echo $results; 12 | ?> -------------------------------------------------------------------------------- /logdownload.php: -------------------------------------------------------------------------------- 1 | fetch(PDO::FETCH_ASSOC); 8 | if ($result==FALSE) die('THIS PROCESS DOES NOT EXISTS OR ALREADY TERMINATED AND REMOVED FROM THE SERVER!'); 9 | if(!file_exists('qqbot/'.$result['id'].'/log.log')) die('No Such File'); 10 | header('Content-Type: text/plain'); 11 | header('Content-Disposition: inline; filename="Log.txt"'); 12 | if(file_exists('qqbot/'.$result['id'].'/log.log')) readfile('qqbot/'.$result['id'].'/log.log'); else die('No Such File'); 13 | exit; 14 | ?> -------------------------------------------------------------------------------- /qqbot/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | -------------------------------------------------------------------------------- /qqbot/qqparking/HttpClient.py: -------------------------------------------------------------------------------- 1 | # HttpClient.py is written by [xqin]: https://github.com/xqin/SmartQQ-for-Raspberry-Pi 2 | import cookielib, urllib, urllib2 3 | 4 | class HttpClient: 5 | __cookie = cookielib.CookieJar() 6 | __req = urllib2.build_opener(urllib2.HTTPCookieProcessor(__cookie)) 7 | __req.addheaders = [ 8 | ('Accept', 'application/javascript, */*;q=0.8'), 9 | ('User-Agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)') 10 | ] 11 | urllib2.install_opener(__req) 12 | 13 | def Get(self, url, refer=None): 14 | try: 15 | req = urllib2.Request(url) 16 | if not (refer is None): 17 | req.add_header('Referer', refer) 18 | return urllib2.urlopen(req).read() 19 | except urllib2.HTTPError, e: 20 | return e.read() 21 | 22 | def Post(self, url, data, refer=None): 23 | try: 24 | req = urllib2.Request(url, urllib.urlencode(data)) 25 | if not (refer is None): 26 | req.add_header('Referer', refer) 27 | return urllib2.urlopen(req).read() 28 | except urllib2.HTTPError, e: 29 | return e.read() 30 | 31 | def Download(self, url, file): 32 | output = open(file, 'wb') 33 | output.write(urllib2.urlopen(url).read()) 34 | output.close() 35 | 36 | # def urlencode(self, data): 37 | # return urllib.quote(data) 38 | 39 | def getCookie(self, key): 40 | for c in self.__cookie: 41 | if c.name == key: 42 | return c.value 43 | return '' 44 | 45 | def setCookie(self, key, val, domain): 46 | ck = cookielib.Cookie(version=0, name=key, value=val, port=None, port_specified=False, domain=domain, domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False) 47 | self.__cookie.set_cookie(ck) 48 | #self.__cookie.clear() clean cookie 49 | # vim : tabstop=2 shiftwidth=2 softtabstop=2 expandtab -------------------------------------------------------------------------------- /qqbot/qqrobot/HttpClient.py: -------------------------------------------------------------------------------- 1 | # HttpClient.py is written by [xqin]: https://github.com/xqin/SmartQQ-for-Raspberry-Pi 2 | import cookielib, urllib, urllib2 3 | 4 | class HttpClient: 5 | __cookie = cookielib.CookieJar() 6 | __req = urllib2.build_opener(urllib2.HTTPCookieProcessor(__cookie)) 7 | __req.addheaders = [ 8 | ('Accept', 'application/javascript, */*;q=0.8'), 9 | ('User-Agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)') 10 | ] 11 | urllib2.install_opener(__req) 12 | 13 | def Get(self, url, refer=None): 14 | try: 15 | req = urllib2.Request(url) 16 | if not (refer is None): 17 | req.add_header('Referer', refer) 18 | return urllib2.urlopen(req).read() 19 | except urllib2.HTTPError, e: 20 | return e.read() 21 | 22 | def Post(self, url, data, refer=None): 23 | try: 24 | req = urllib2.Request(url, urllib.urlencode(data)) 25 | if not (refer is None): 26 | req.add_header('Referer', refer) 27 | return urllib2.urlopen(req).read() 28 | except urllib2.HTTPError, e: 29 | return e.read() 30 | 31 | def Download(self, url, file): 32 | output = open(file, 'wb') 33 | output.write(urllib2.urlopen(url).read()) 34 | output.close() 35 | 36 | # def urlencode(self, data): 37 | # return urllib.quote(data) 38 | 39 | def getCookie(self, key): 40 | for c in self.__cookie: 41 | if c.name == key: 42 | return c.value 43 | return '' 44 | 45 | def setCookie(self, key, val, domain): 46 | ck = cookielib.Cookie(version=0, name=key, value=val, port=None, port_specified=False, domain=domain, domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False) 47 | self.__cookie.set_cookie(ck) 48 | #self.__cookie.clear() clean cookie 49 | # vim : tabstop=2 shiftwidth=2 softtabstop=2 expandtab -------------------------------------------------------------------------------- /qqbot/qqrobot/qqbot.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import re 4 | import random 5 | import json 6 | import os 7 | import sys 8 | import datetime 9 | import time 10 | import threading 11 | import logging 12 | import urllib 13 | import smtplib 14 | from HttpClient import HttpClient 15 | from email.Header import Header 16 | from email.mime.multipart import MIMEMultipart 17 | from email.mime.text import MIMEText 18 | 19 | reload(sys) 20 | sys.setdefaultencoding("utf-8") 21 | 22 | HttpClient_Ist = HttpClient() 23 | 24 | ClientID = 53999199 25 | PTWebQQ = '' 26 | APPID = 0 27 | msgId = 0 28 | ThreadList = [] 29 | GroupThreadList = [] 30 | GroupWatchList = [] 31 | GroupNameList = {} 32 | GroupCodeList = {} 33 | PSessionID = '' 34 | Referer = 'http://s.web2.qq.com/proxy.html?v=20130916001&callback=1&id=1' 35 | httpsReferer = 'https://d1.web2.qq.com/cfproxy.html?v=20151105001&callback=1' 36 | SmartQQUrl = 'https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&style=16&mibao_css=m_webqq&appid=501004106&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fw.qq.com%2Fproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&t=20131024001' 37 | VFWebQQ = '' 38 | AdminQQ = '0' 39 | MyUIN = '' 40 | 41 | #SET YOUR OWN PARAMETERS HERE 42 | tulingkey = 'c7c5abbc9ec9cad3a63bde71d17e3c2c' 43 | mailserver = 'smtp.126.com' 44 | mailsig = 'QQRobot Notification' 45 | mailuser = 'qqparking@126.com' 46 | mailpass = 'uyyxdrzrrxntidkh' 47 | #-----END OF SECTION------- 48 | 49 | sendtomail='' 50 | sendtoflag=0 51 | 52 | initTime = time.time() 53 | 54 | 55 | logging.basicConfig(filename='log.log', level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S') 56 | 57 | # ----------------- 58 | # 方法声明 59 | # ----------------- 60 | 61 | def sendfailmail(): 62 | try: 63 | SUBJECT = 'QQ小黄鸡下线提醒' 64 | TO = [sendtomail] 65 | msg = MIMEMultipart('alternative') 66 | msg['Subject'] = Header(SUBJECT, 'utf-8') 67 | msg['From'] = mailsig+'<'+mailuser+'>' 68 | msg['To'] = ', '.join(TO) 69 | part = MIMEText("Fatal error occured. Please go to the website and login again!", 'plain', 'utf-8') 70 | msg.attach(part) 71 | server = smtplib.SMTP(mailserver, 25) 72 | server.login(mailuser, mailpass) 73 | server.login(mailuser, mailpass) 74 | server.sendmail(mailuser, TO, msg.as_string()) 75 | server.quit() 76 | return True 77 | except Exception , e: 78 | logging.error("发送程序错误邮件失败:"+str(e)) 79 | return False 80 | 81 | def pass_time(): 82 | global initTime 83 | rs = (time.time() - initTime) 84 | initTime = time.time() 85 | return str(round(rs, 3)) 86 | 87 | def get_ts(): 88 | ts = time.time() 89 | while ts < 1000000000000: 90 | ts = ts * 10 91 | ts = int(ts) 92 | return ts 93 | 94 | def CProcess(content): 95 | return str(content.replace("\\", r"\\").replace("\n", r"\n").replace("\r", r"\r").replace("\t", r"\t").replace('"', r'\"')) 96 | 97 | def getQRtoken(qrsig): 98 | e = 0 99 | for i in qrsig: 100 | e += (e << 5) + ord(i) 101 | return 2147483647 & e; 102 | 103 | #Encryption Algorithm Used By QQ 104 | def gethash(selfuin, ptwebqq): 105 | selfuin += "" 106 | N=[0,0,0,0] 107 | for T in range(len(ptwebqq)): 108 | N[T%4]=N[T%4]^ord(ptwebqq[T]) 109 | U=["EC","OK"] 110 | V=[0, 0, 0, 0] 111 | V[0]=int(selfuin) >> 24 & 255 ^ ord(U[0][0]) 112 | V[1]=int(selfuin) >> 16 & 255 ^ ord(U[0][1]) 113 | V[2]=int(selfuin) >> 8 & 255 ^ ord(U[1][0]) 114 | V[3]=int(selfuin) & 255 ^ ord(U[1][1]) 115 | U=[0,0,0,0,0,0,0,0] 116 | U[0]=N[0] 117 | U[1]=V[0] 118 | U[2]=N[1] 119 | U[3]=V[1] 120 | U[4]=N[2] 121 | U[5]=V[2] 122 | U[6]=N[3] 123 | U[7]=V[3] 124 | N=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"] 125 | V="" 126 | for T in range(len(U)): 127 | V+= N[ U[T]>>4 & 15] 128 | V+= N[ U[T] & 15] 129 | return V 130 | 131 | def getReValue(html, rex, er, ex): 132 | v = re.search(rex, html) 133 | 134 | if v is None: 135 | logging.error(er) 136 | 137 | if ex: 138 | raise Exception, er 139 | return '' 140 | 141 | return v.group(1) 142 | 143 | 144 | def date_to_millis(d): 145 | return int(time.mktime(d.timetuple())) * 1000 146 | 147 | 148 | def msg_handler(msgObj): 149 | for msg in msgObj: 150 | msgType = msg['poll_type'] 151 | 152 | # QQ私聊消息 153 | if msgType == 'message' or msgType == 'sess_message': # 私聊 or 临时对话 154 | txt = combine_msg(msg['value']['content']) 155 | tuin = msg['value']['from_uin'] 156 | msg_id = msg['value']['msg_id'] 157 | 158 | # print "{0}:{1}".format(from_account, txt) 159 | targetThread = thread_exist(tuin) 160 | if targetThread: 161 | targetThread.push(txt, msg_id) 162 | else: 163 | try: 164 | service_type = 0 165 | isSess = 0 166 | group_sig = '' 167 | if msgType == 'sess_message': 168 | isSess = 1 169 | service_type = msg['value']['service_type'] 170 | myid = msg['value']['id'] 171 | info = json.loads(HttpClient_Ist.Get('http://d1.web2.qq.com/channel/get_c2cmsg_sig2?id={0}&to_uin={1}&clientid={2}&psessionid={3}&service_type={4}&t={5}'.format(myid, tuin, ClientID, PSessionID, service_type, get_ts()), Referer)) 172 | logging.info("Get group sig:" + str(info)) 173 | if info['retcode'] != 0: 174 | raise ValueError, info 175 | info = info['result'] 176 | group_sig = info['value'] 177 | tmpThread = pmchat_thread(tuin,isSess,group_sig,service_type) 178 | tmpThread.start() 179 | ThreadList.append(tmpThread) 180 | tmpThread.push(txt,msg_id) 181 | except Exception, e: 182 | logging.info("error"+str(e)) 183 | 184 | # print "{0}:{1}".format(self.FriendList.get(tuin, 0), txt) 185 | 186 | # if FriendList.get(tuin, 0) == AdminQQ:#如果消息的发送者与AdminQQ不相同, 则忽略本条消息不往下继续执行 187 | # if txt[0] == '#': 188 | # thread.start_new_thread(self.runCommand, (tuin, txt[1:].strip(), msgId)) 189 | # msgId += 1 190 | 191 | # if txt[0:4] == 'exit': 192 | # logging.info(self.Get('http://d1.web2.qq.com/channel/logout2?ids=&clientid={0}&psessionid={1}'.format(self.ClientID, self.PSessionID), Referer)) 193 | # exit(0) 194 | 195 | # 群消息 196 | if msgType == 'group_message': 197 | global GroupWatchList 198 | txt = combine_msg(msg['value']['content']) 199 | guin = msg['value']['from_uin'] 200 | gid = GroupCodeList[int(guin)] 201 | tuin = msg['value']['send_uin'] 202 | seq = msg['value']['msg_id'] 203 | if str(guin) in GroupWatchList: 204 | g_exist = group_thread_exist(gid) 205 | if g_exist: 206 | g_exist.handle(tuin, txt, seq) 207 | else: 208 | tmpThread = group_thread(guin, gid) 209 | tmpThread.start() 210 | GroupThreadList.append(tmpThread) 211 | tmpThread.handle(tuin, txt, seq) 212 | logging.info("群线程已生成") 213 | else: 214 | logging.info(str(gid) + "群有动态,但是没有被监控") 215 | 216 | # QQ号在另一个地方登陆, 被挤下线 217 | if msgType == 'kick_message': 218 | logging.error(msg['value']['reason']) 219 | raise Exception, msg['value']['reason'] # 抛出异常, 重新启动WebQQ, 需重新扫描QRCode来完成登陆 220 | 221 | 222 | def combine_msg(content): 223 | msgTXT = "" 224 | for part in content: 225 | # print type(part) 226 | if type(part) == type(u'\u0000'): 227 | msgTXT += part 228 | elif len(part) > 1: 229 | # 如果是图片 230 | if str(part[0]) == "offpic" or str(part[0]) == "cface": 231 | msgTXT += "[图片]" 232 | 233 | return msgTXT 234 | 235 | 236 | def send_msg(tuin, content, isSess, group_sig, service_type): 237 | if isSess == 0: 238 | reqURL = "https://d1.web2.qq.com/channel/send_buddy_msg2" 239 | data = ( 240 | ('r', '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}"}}'.format(tuin, ClientID, msgId, PSessionID, CProcess(content))), 241 | ('clientid', ClientID), 242 | ('psessionid', PSessionID) 243 | ) 244 | rsp = HttpClient_Ist.Post(reqURL, data, httpsReferer) 245 | rspp = json.loads(rsp) 246 | if rspp['errCode']!= 0: 247 | logging.error("reply pmchat error"+str(rspp['errCode'])) 248 | else: 249 | reqURL = "https://d1.web2.qq.com/channel/send_sess_msg2" 250 | data = ( 251 | ('r', '{{"to":{0}, "face":594, "content":"[\\"{4}\\", [\\"font\\", {{\\"name\\":\\"Arial\\", \\"size\\":\\"10\\", \\"style\\":[0, 0, 0], \\"color\\":\\"000000\\"}}]]", "clientid":{1}, "msg_id":{2}, "psessionid":"{3}", "group_sig":"{5}", "service_type":{6}}}'.format(tuin, ClientID, msgId, PSessionID, CProcess(content), group_sig, service_type)), 252 | ('clientid', ClientID), 253 | ('psessionid', PSessionID), 254 | ('group_sig', group_sig), 255 | ('service_type',service_type) 256 | ) 257 | rsp = HttpClient_Ist.Post(reqURL, data, httpsReferer) 258 | rspp = json.loads(rsp) 259 | if rspp['errCode']!= 0: 260 | logging.error("reply temp pmchat error"+str(rspp['errCode'])) 261 | 262 | return rsp 263 | 264 | 265 | def thread_exist(tuin): 266 | for t in ThreadList: 267 | if t.isAlive(): 268 | if t.tuin == tuin: 269 | t.check() 270 | return t 271 | else: 272 | ThreadList.remove(t) 273 | return False 274 | 275 | 276 | def group_thread_exist(gid): 277 | for t in GroupThreadList: 278 | if str(t.gid) == str(gid): 279 | return t 280 | return False 281 | 282 | # ----------------- 283 | # 类声明 284 | # ----------------- 285 | 286 | 287 | class Login(HttpClient): 288 | MaxTryTime = 5 289 | 290 | def __init__(self, vpath, qq=0): 291 | global APPID, AdminQQ, PTWebQQ, VFWebQQ, PSessionID, msgId, MyUIN, GroupNameList, tmpUserName, GroupCodeList, sendtoflag, sendtomail 292 | 293 | f=open('email.txt','rt') 294 | sendtomail=f.readline().replace("\n","").replace("\r","") 295 | f.close() 296 | if sendtomail!='': 297 | sendtoflag=1 298 | 299 | self.VPath = vpath # QRCode保存路径 300 | AdminQQ = int(qq) 301 | logging.critical("正在获取登陆页面") 302 | self.Get('http://w.qq.com/') 303 | html = self.Get(SmartQQUrl,'http://w.qq.com/') 304 | logging.critical("正在获取appid") 305 | APPID = getReValue(html, r'', 'Get AppId Error', 1) 306 | logging.critical("正在获取login_sig") 307 | sign = getReValue(html, r'g_login_sig\s*=\s*encodeURIComponent\s*\("(.*?)"\)', 'Get Login Sign Error', 0) 308 | logging.info('get sign : %s', sign) 309 | logging.critical("正在获取pt_version") 310 | JsVer = getReValue(html, r'g_pt_version\s*=\s*encodeURIComponent\s*\("(\d+)"\)', 'Get g_pt_version Error', 1) 311 | logging.info('get g_pt_version : %s', JsVer) 312 | logging.critical("正在获取mibao_css") 313 | MiBaoCss = getReValue(html, r'g_mibao_css\s*=\s*encodeURIComponent\s*\("(.*?)"\)', 'Get g_mibao_css Error', 1) 314 | logging.info('get g_mibao_css : %s', sign) 315 | StarTime = date_to_millis(datetime.datetime.utcnow()) 316 | T = 0 317 | while True: 318 | T = T + 1 319 | self.Download('https://ssl.ptlogin2.qq.com/ptqrshow?appid={0}&e=0&l=M&s=5&d=72&v=4&t=0.0836106{1}4250{2}6653'.format(APPID,random.randint(0,9),random.randint(0,9)), self.VPath) 320 | 321 | logging.info('[{0}] Get QRCode Picture Success.'.format(T)) 322 | 323 | QRSig = self.getCookie('qrsig') 324 | while True: 325 | html = self.Get('https://ssl.ptlogin2.qq.com/ptqrlogin?ptqrtoken={0}&webqq_type=10&remember_uin=1&login2qq=1&aid={1}&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-{2}&mibao_css={3}&t=1&g=1&js_type=0&js_ver={4}&login_sig={5}&pt_randsalt=2'.format(getQRtoken(QRSig),APPID, date_to_millis(datetime.datetime.utcnow()) - StarTime, MiBaoCss, JsVer, sign), 326 | SmartQQUrl) 327 | # logging.info(html) 328 | ret = html.split("'") 329 | if ret[1] == '65' or ret[1] == '0': # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中 330 | break 331 | time.sleep(2) 332 | if ret[1] == '0' or T > self.MaxTryTime: 333 | break 334 | 335 | logging.info(ret) 336 | if ret[1] != '0': 337 | raise ValueError, "RetCode = "+ret['retcode'] 338 | return 339 | logging.critical("二维码已扫描,正在登陆") 340 | pass_time() 341 | # 删除QRCode文件 342 | if os.path.exists(self.VPath): 343 | os.remove(self.VPath) 344 | 345 | # 记录登陆账号的昵称 346 | tmpUserName = ret[11] 347 | 348 | html = self.Get(ret[5]) 349 | url = getReValue(html, r' src="(.+?)"', 'Get mibao_res Url Error.', 0) 350 | if url != '': 351 | html = self.Get(url.replace('&', '&')) 352 | url = getReValue(html, r'location\.href="(.+?)"', 'Get Redirect Url Error', 1) 353 | html = self.Get(url) 354 | 355 | PTWebQQ = self.getCookie('ptwebqq') 356 | 357 | logging.info('PTWebQQ: {0}'.format(PTWebQQ)) 358 | 359 | LoginError = 3 360 | while LoginError > 0: 361 | try: 362 | html = self.Post('http://d1.web2.qq.com/channel/login2', { 363 | 'r': '{{"ptwebqq":"{0}","clientid":{1},"psessionid":"{2}","status":"online"}}'.format(PTWebQQ, ClientID, PSessionID) 364 | }, 'http://d1.web2.qq.com/proxy.html?v=20151105001&callback=1&id=2') 365 | ret = json.loads(html) 366 | html2 = self.Get("http://s.web2.qq.com/api/getvfwebqq?ptwebqq={0}&clientid={1}&psessionid={2}&t={3}".format(PTWebQQ, ClientID, PSessionID, get_ts()), Referer) 367 | logging.info("getvfwebqq html: " + str(html2)) 368 | ret2 = json.loads(html2) 369 | LoginError = 0 370 | except: 371 | LoginError -= 1 372 | logging.critical("登录失败,正在重试") 373 | 374 | if ret['retcode'] != 0 or ret2['retcode'] != 0: 375 | raise ValueError, "Login Retcode="+str(ret['retcode']) 376 | return 377 | 378 | VFWebQQ = ret2['result']['vfwebqq'] 379 | PSessionID = ret['result']['psessionid'] 380 | MyUIN = ret['result']['uin'] 381 | logging.critical("QQ号:{0} 登陆成功, 用户名:{1}".format(ret['result']['uin'], tmpUserName)) 382 | logging.info('Login success') 383 | logging.critical("登陆二维码用时" + pass_time() + "秒") 384 | 385 | msgId = int(random.uniform(20000, 50000)) 386 | html = self.Post('http://s.web2.qq.com/api/get_group_name_list_mask2', { 387 | 'r': '{{"vfwebqq":"{0}","hash":"{1}"}}'.format(str(VFWebQQ),gethash(str(MyUIN),str(PTWebQQ))) 388 | }, Referer) 389 | ret = json.loads(html) 390 | if ret['retcode']!= 0: 391 | raise ValueError, "retcode error when getting group list: retcode="+str(ret['retcode']) 392 | for t in ret['result']['gnamelist']: 393 | GroupNameList[str(t["name"])]=t["gid"] 394 | GroupCodeList[int(t["gid"])]=int(t["code"]) 395 | self.Get('http://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq={0}&clientid={1}&psessionid={2}&t={3}'.format(VFWebQQ,ClientID,PSessionID,get_ts()),Referer) 396 | 397 | class check_msg(threading.Thread): 398 | # try: 399 | # pass 400 | # except KeybordInterrupt: 401 | # try: 402 | # user_input = (raw_input("回复系统:(输入格式:{群聊2or私聊1}, {群号or账号}, {内容})\n")).split(",") 403 | # if (user_input[0] == 1): 404 | 405 | # for kv in self.FriendList : 406 | # if str(kv[1]) == str(user_input[1]): 407 | # tuin == kv[0] 408 | 409 | # self.send_msg(tuin, user_input[2]) 410 | 411 | # except KeybordInterrupt: 412 | # exit(0) 413 | # except Exception, e: 414 | # print Exception, e 415 | 416 | def __init__(self): 417 | threading.Thread.__init__(self) 418 | 419 | def run(self): 420 | global PTWebQQ 421 | E = 0 422 | # 心跳包轮询 423 | while 1: 424 | if E > 5: 425 | break 426 | try: 427 | ret = self.check() 428 | except: 429 | E += 1 430 | continue 431 | # logging.info(ret) 432 | 433 | # 返回数据有误 434 | if ret == "": 435 | E += 1 436 | continue 437 | 438 | # POST数据有误 439 | if ret['retcode'] == 100006: 440 | break 441 | 442 | # 无消息 443 | if ret['retcode'] == 102: 444 | E = 0 445 | continue 446 | 447 | # 更新PTWebQQ值 448 | if ret['retcode'] == 116: 449 | PTWebQQ = ret['p'] 450 | E = 0 451 | continue 452 | 453 | if ret['retcode'] == 0: 454 | # 信息分发 455 | if 'result' in ret: 456 | msg_handler(ret['result']) 457 | E = 0 458 | continue 459 | 460 | # Other retcode e.g.: 103 461 | E += 1 462 | HttpClient_Ist.Get('http://d1.web2.qq.com/channel/get_online_buddies2?vfwebqq={0}&clientid={1}&psessionid={2}&t={3}'.format(VFWebQQ,ClientID,PSessionID,get_ts()),Referer) 463 | 464 | logging.critical("轮询错误超过五次") 465 | 466 | # 向服务器查询新消息 467 | def check(self): 468 | 469 | html = HttpClient_Ist.Post('https://d1.web2.qq.com/channel/poll2', { 470 | 'r': '{{"ptwebqq":"{1}","clientid":{2},"psessionid":"{0}","key":""}}'.format(PSessionID, PTWebQQ, ClientID) 471 | }, httpsReferer) 472 | logging.info("Check html: " + str(html)) 473 | try: 474 | ret = json.loads(html) 475 | except Exception as e: 476 | logging.error(str(e)) 477 | logging.critical("Check error occured, retrying.") 478 | return self.check() 479 | 480 | return ret 481 | 482 | 483 | class pmchat_thread(threading.Thread): 484 | 485 | 486 | # con = threading.Condition() 487 | # newIp = '' 488 | 489 | def __init__(self, tuin, isSess, group_sig, service_type): 490 | threading.Thread.__init__(self) 491 | self.tuin = tuin 492 | self.isSess = isSess 493 | self.group_sig=group_sig 494 | self.service_type=service_type 495 | self.lastcheck = time.time() 496 | self.lastseq=0 497 | self.replystreak = 0 498 | logging.info("私聊线程生成,私聊对象UIN:"+str(self.tuin)) 499 | def check(self): 500 | self.lastcheck = time.time() 501 | def run(self): 502 | while 1: 503 | time.sleep(199) 504 | if time.time() - self.lastcheck > 300: 505 | break 506 | 507 | def reply(self, content): 508 | send_msg(self.tuin, str(content), self.isSess, self.group_sig, self.service_type) 509 | logging.info("Reply to " + str(self.tuin) + ":" + str(content)) 510 | 511 | def push(self, ipContent, seq): 512 | if seq == self.lastseq: 513 | return True 514 | else: 515 | self.lastseq=seq 516 | #防止机器人对聊 517 | if self.replystreak>30: 518 | self.replystreak = 0 519 | return True 520 | try: 521 | self.replystreak = self.replystreak + 1 522 | logging.info("PM get info from AI: "+ipContent) 523 | paraf={ 'userid' : str(self.tuin), 'key' : tulingkey, 'info' : ipContent} 524 | info = HttpClient_Ist.Get('http://www.tuling123.com/openapi/api?'+urllib.urlencode(paraf)) 525 | logging.info("AI REPLY:"+str(info)) 526 | info = json.loads(info) 527 | if info["code"] in [40001, 40003, 40004]: 528 | self.reply("我今天累了,不聊了") 529 | logging.warning("Reach max AI call") 530 | elif info["code"] in [40002, 40005, 40006, 40007]: 531 | self.reply("我遇到了一点问题,请稍后@我") 532 | logging.warning("PM AI return error, code:"+str(info["code"])) 533 | else: 534 | rpy = str(info["text"]).replace('<主人>','你').replace('
    ',"\n") 535 | self.reply(rpy) 536 | return True 537 | except Exception, e: 538 | logging.error("ERROR:"+str(e)) 539 | return False 540 | 541 | 542 | 543 | class group_thread(threading.Thread): 544 | last1 = '' 545 | lastseq = 0 546 | replyList = {} 547 | followList = [] 548 | NickList = {} 549 | 550 | # 属性 551 | repeatPicture = True 552 | 553 | def __init__(self, guin, gcode): 554 | threading.Thread.__init__(self) 555 | self.guin = guin 556 | self.gid = gcode 557 | self.load() 558 | self.lastreplytime=0 559 | ret = HttpClient_Ist.Get('http://s.web2.qq.com/api/get_group_info_ext2?gcode={0}&vfwebqq={1}&t={2}'.format(gcode,VFWebQQ,get_ts()),Referer) 560 | ret = json.loads(ret) 561 | for t in ret['result']['minfo']: 562 | self.NickList[str(t["nick"])]=int(t["uin"]) 563 | 564 | def learn(self, key, value, needreply=True): 565 | if key in self.replyList: 566 | self.replyList[key].append(value) 567 | else: 568 | self.replyList[key] = [value] 569 | 570 | if needreply: 571 | self.reply("我记住" + str(key) + "的回复了") 572 | self.save() 573 | 574 | def delete(self, key, value, needreply=True): 575 | if key in self.replyList and self.replyList[key].count(value): 576 | self.replyList[key].remove(value) 577 | if needreply: 578 | self.reply("我已经不会说" + str(value) + "了") 579 | self.save() 580 | 581 | else: 582 | if needreply: 583 | self.reply("没找到你说的那句话哦") 584 | 585 | def reply(self, content): 586 | if time.time() - self.lastreplytime < 3.0: 587 | logging.info("REPLY TOO FAST, ABANDON:"+content) 588 | return False 589 | self.lastreplytime = time.time() 590 | reqURL = "https://d1.web2.qq.com/channel/send_qun_msg2" 591 | data = ( 592 | ('r', '{{"group_uin":{0}, "face":564,"content":"[\\"{4}\\",[\\"font\\",{{\\"name\\":\\"Arial\\",\\"size\\":\\"10\\",\\"style\\":[0,0,0],\\"color\\":\\"000000\\"}}]]","clientid":{1},"msg_id":{2},"psessionid":"{3}"}}'.format(self.guin, ClientID, msgId, PSessionID, CProcess(content))), 593 | ('clientid', ClientID), 594 | ('psessionid', PSessionID) 595 | ) 596 | logging.info("Reply package: " + str(data)) 597 | rsp = HttpClient_Ist.Post(reqURL, data, httpsReferer) 598 | try: 599 | rspp = json.loads(rsp) 600 | if rspp['errCode'] == 0: 601 | logging.info("[Reply to group " + str(self.gid) + "]:" + str(content)) 602 | return True 603 | except: 604 | pass 605 | logging.error("[Fail to reply group " + str(self.gid)+ "]:" + str(rsp)) 606 | return rsp 607 | 608 | def handle(self, send_uin, content, seq): 609 | # 避免重复处理相同信息 610 | if seq != self.lastseq: 611 | pattern = re.compile(r'^(?:!|!)(learn|delete) {(.+)}{(.+)}') 612 | match = pattern.match(content) 613 | if match: 614 | if match.group(1) == 'learn': 615 | self.learn(str(match.group(2)).decode('UTF-8'), str(match.group(3)).decode('UTF-8')) 616 | logging.debug(self.replyList) 617 | if match.group(1) == 'delete': 618 | self.delete(str(match.group(2)).decode('UTF-8'), str(match.group(3)).decode('UTF-8')) 619 | logging.debug(self.replyList) 620 | 621 | else: 622 | # if not self.follow(send_uin, content): 623 | # if not self.tucao(content): 624 | # if not self.repeat(content): 625 | # if not self.callout(content): 626 | # pass 627 | if self.aboutme(content): 628 | return 629 | if self.deleteall(content): 630 | return 631 | if self.callout(send_uin, content): 632 | return 633 | if self.follow(send_uin, content): 634 | return 635 | if self.tucao(content): 636 | return 637 | if self.repeat(content): 638 | return 639 | 640 | else: 641 | logging.warning("message seq repeat detected.") 642 | self.lastseq = seq 643 | 644 | def tucao(self, content): 645 | for key in self.replyList: 646 | if str(key) in content and self.replyList[key]: 647 | rd = random.randint(0, len(self.replyList[key]) - 1) 648 | self.reply(self.replyList[key][rd]) 649 | logging.info('Group Reply'+str(self.replyList[key][rd])) 650 | return True 651 | return False 652 | 653 | def repeat(self, content): 654 | if self.last1 == str(content) and content != '' and content != ' ': 655 | if self.repeatPicture or "[图片]" not in content: 656 | self.reply(content) 657 | logging.info("已复读:{" + str(content) + "}") 658 | return True 659 | self.last1 = content 660 | 661 | return False 662 | 663 | def follow(self, send_uin, content): 664 | pattern = re.compile(r'^(?:!|!)(follow|unfollow) (.*)!') 665 | match = pattern.match(content) 666 | 667 | if match: 668 | target1 = str(match.group(2)) 669 | if target1 == 'me': 670 | target = send_uin 671 | target1 = '你' 672 | else: 673 | if target1 in self.NickList: 674 | target = self.NickList[target1] 675 | else: 676 | self.reply("找不到成员:"+target1) 677 | return True 678 | 679 | if match.group(1) == 'follow' and target not in self.followList: 680 | self.followList.append(target) 681 | self.reply("正在关注" + target1) 682 | return True 683 | if match.group(1) == 'unfollow' and target in self.followList: 684 | self.followList.remove(target) 685 | self.reply("我不关注" + target1 + "了!") 686 | return True 687 | else: 688 | if send_uin in self.followList: 689 | self.reply(content) 690 | return True 691 | return False 692 | 693 | def save(self): 694 | try: 695 | with open("database."+str(self.gid)+".save", "w+") as savefile: 696 | savefile.write(json.dumps(self.replyList)) 697 | savefile.close() 698 | except Exception, e: 699 | logging.error("写存档出错:"+str(e)) 700 | def load(self): 701 | try: 702 | with open("database."+str(self.gid)+".save", "r") as savefile: 703 | saves = savefile.read() 704 | if saves: 705 | self.replyList = json.loads(saves) 706 | savefile.close() 707 | except Exception, e: 708 | logging.info("读取存档出错:"+str(e)) 709 | 710 | def callout(self, send_uin, content): 711 | pattern = re.compile(r'^(?:!|!)(ai) (.+)') 712 | match = pattern.match(content) 713 | try: 714 | if match: 715 | logging.info("get info from AI: "+str(match.group(2)).decode('UTF-8')) 716 | usr = str(send_uin) 717 | paraf={ 'userid' : usr+'g', 'key' : tulingkey, 'info' : str(match.group(2)).decode('UTF-8')} 718 | 719 | info = HttpClient_Ist.Get('http://www.tuling123.com/openapi/api?'+urllib.urlencode(paraf)) 720 | logging.info("AI REPLY:"+str(info)) 721 | info = json.loads(info) 722 | if info["code"] in [40001, 40003, 40004]: 723 | self.reply("我今天累了,不聊了") 724 | logging.warning("Reach max AI call") 725 | elif info["code"] in [40002, 40005, 40006, 40007]: 726 | self.reply("我遇到了一点问题,请稍后@我") 727 | logging.warning("AI return error, code:"+str(info["code"])) 728 | else: 729 | self.reply(str(info["text"]).replace('<主人>','你').replace('
    ',"\n")) 730 | return True 731 | except Exception, e: 732 | logging.error("ERROR"+str(e)) 733 | return False 734 | 735 | def aboutme(self, content): 736 | pattern = re.compile(r'^(?:!|!)(about)') 737 | match = pattern.match(content) 738 | try: 739 | if match: 740 | logging.info("output about info") 741 | info="小黄鸡3.8 By Jeffery 详细说明见github.com/zeruniverse/QQRobot" 742 | self.reply(info) 743 | return True 744 | except Exception, e: 745 | logging.error("ERROR"+str(e)) 746 | return False 747 | 748 | def deleteall(self, content): 749 | pattern = re.compile(r'^(?:!|!)(deleteall)') 750 | match = pattern.match(content) 751 | try: 752 | if match: 753 | logging.info("Delete all learned data for group:"+str(self.gid)) 754 | info="已删除所有学习内容" 755 | self.replyList.clear() 756 | self.save() 757 | self.reply(info) 758 | return True 759 | except Exception, e: 760 | logging.error("ERROR:"+str(e)) 761 | return False 762 | # ----------------- 763 | # 主程序 764 | # ----------------- 765 | 766 | if __name__ == "__main__": 767 | vpath = './v.png' 768 | qq = 0 769 | if len(sys.argv) > 1: 770 | vpath = sys.argv[1] 771 | if len(sys.argv) > 2: 772 | qq = sys.argv[2] 773 | 774 | try: 775 | pass_time() 776 | qqLogin = Login(vpath, qq) 777 | except Exception, e: 778 | logging.critical(str(e)) 779 | os._exit(1) 780 | 781 | try: 782 | with open('groupfollow.txt','r') as f: 783 | for line in f: 784 | tmp = line.strip('\n').strip('\r') 785 | if str(tmp) in GroupNameList: 786 | GroupWatchList.append(str(GroupNameList[str(tmp)])) 787 | logging.info("关注:"+str(tmp)) 788 | else: 789 | logging.error("无法找到群:"+str(tmp)) 790 | except Exception, e: 791 | logging.error("读取组存档出错:"+str(e)) 792 | 793 | try: 794 | t_check = check_msg() 795 | t_check.setDaemon(True) 796 | t_check.start() 797 | t_check.join() 798 | except: 799 | pass 800 | if sendtoflag!=0: 801 | logging.info("发送下线邮件...") 802 | errortime=0 803 | while errortime<5: 804 | errortime=errortime+1 805 | if sendfailmail(): 806 | break -------------------------------------------------------------------------------- /qqbot/qzoneliker/HttpClient.py: -------------------------------------------------------------------------------- 1 | # HttpClient.py is written by [xqin]: https://github.com/xqin/SmartQQ-for-Raspberry-Pi 2 | import cookielib, urllib, urllib2 3 | 4 | class HttpClient: 5 | __cookie = cookielib.CookieJar() 6 | __req = urllib2.build_opener(urllib2.HTTPCookieProcessor(__cookie)) 7 | __req.addheaders = [ 8 | ('Accept', 'application/javascript, */*;q=0.8'), 9 | ('User-Agent', 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)') 10 | ] 11 | urllib2.install_opener(__req) 12 | 13 | def Get(self, url, refer=None): 14 | try: 15 | req = urllib2.Request(url) 16 | if not (refer is None): 17 | req.add_header('Referer', refer) 18 | return urllib2.urlopen(req).read() 19 | except urllib2.HTTPError, e: 20 | return e.read() 21 | 22 | def Post(self, url, data, refer=None): 23 | try: 24 | req = urllib2.Request(url, urllib.urlencode(data)) 25 | if not (refer is None): 26 | req.add_header('Referer', refer) 27 | return urllib2.urlopen(req).read() 28 | except urllib2.HTTPError, e: 29 | return e.read() 30 | 31 | def Download(self, url, file): 32 | output = open(file, 'wb') 33 | output.write(urllib2.urlopen(url).read()) 34 | output.close() 35 | 36 | # def urlencode(self, data): 37 | # return urllib.quote(data) 38 | 39 | def getCookie(self, key): 40 | for c in self.__cookie: 41 | if c.name == key: 42 | return c.value 43 | return '' 44 | 45 | def setCookie(self, key, val, domain): 46 | ck = cookielib.Cookie(version=0, name=key, value=val, port=None, port_specified=False, domain=domain, domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False) 47 | self.__cookie.set_cookie(ck) 48 | #self.__cookie.clear() clean cookie 49 | # vim : tabstop=2 shiftwidth=2 softtabstop=2 expandtab 50 | -------------------------------------------------------------------------------- /qqbot/qzoneliker/qqbot.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import re 4 | import random 5 | import json 6 | import os 7 | import sys 8 | import datetime 9 | import time 10 | import threading 11 | import logging 12 | import execjs 13 | import urllib 14 | import smtplib 15 | from HttpClient import HttpClient 16 | from email.Header import Header 17 | from email.mime.multipart import MIMEMultipart 18 | from email.mime.text import MIMEText 19 | 20 | reload(sys) 21 | sys.setdefaultencoding("utf-8") 22 | 23 | # CONFIGURATION FIELD 24 | #check every k seconds 25 | checkFrequency = 180 26 | 27 | #SET YOUR OWN PARAMETERS HERE 28 | mailserver = 'smtp.126.com' 29 | mailsig = 'QzoneLiker Notification' 30 | mailuser = 'qqparking@126.com' 31 | mailpass = 'uyyxdrzrrxntidkh' 32 | #-----END OF SECTION------- 33 | 34 | # STOP EDITING HERE 35 | HttpClient_Ist = HttpClient() 36 | UIN = 0 37 | skey = '' 38 | Referer = 'https://user.qzone.qq.com/' 39 | QzoneLoginUrl = 'https://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=https%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=https%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=https%3A//z.qzone.com/download.html&self_regurl=https%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=https%3A//z.qzone.com/download.html&pt_no_auth=0' 40 | 41 | sendtomail='' 42 | sendtoflag=0 43 | 44 | initTime = time.time() 45 | 46 | 47 | logging.basicConfig(filename='log.log', level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S') 48 | def sendfailmail(): 49 | try: 50 | SUBJECT = 'QQ点赞机下线提醒' 51 | TO = [sendtomail] 52 | msg = MIMEMultipart('alternative') 53 | msg['Subject'] = Header(SUBJECT, 'utf-8') 54 | msg['From'] = mailsig+'<'+mailuser+'>' 55 | msg['To'] = ', '.join(TO) 56 | part = MIMEText("Fatal error occured. Please go to the website and login again!", 'plain', 'utf-8') 57 | msg.attach(part) 58 | server = smtplib.SMTP(mailserver, 25) 59 | server.login(mailuser, mailpass) 60 | server.login(mailuser, mailpass) 61 | server.sendmail(mailuser, TO, msg.as_string()) 62 | server.quit() 63 | return True 64 | except Exception , e: 65 | logging.error("发送程序错误邮件失败:"+str(e)) 66 | return False 67 | 68 | def getAbstime(): 69 | return int(time.time()) 70 | 71 | def date_to_millis(d): 72 | return int(time.mktime(d.timetuple())) * 1000 73 | 74 | def getReValue(html, rex, er, ex): 75 | v = re.search(rex, html) 76 | 77 | if v is None: 78 | logging.error(er) 79 | 80 | if ex: 81 | raise Exception, er 82 | return '' 83 | 84 | return v.group(1) 85 | 86 | def getQRtoken(qrsig): 87 | e = 0 88 | for i in qrsig: 89 | e += (e << 5) + ord(i) 90 | return 2147483647 & e; 91 | 92 | # ----------------- 93 | # 登陆 94 | # ----------------- 95 | class Login(HttpClient): 96 | MaxTryTime = 5 97 | 98 | def __init__(self, vpath, qq=0): 99 | global UIN, Referer, skey, sendtoflag, sendtomail 100 | 101 | f=open('email.txt','rt') 102 | sendtomail=f.readline().replace("\n","").replace("\r","") 103 | f.close() 104 | if sendtomail!='': 105 | sendtoflag=1 106 | 107 | self.VPath = vpath # QRCode保存路径 108 | AdminQQ = int(qq) 109 | logging.critical("正在获取登陆页面") 110 | self.setCookie('_qz_referrer','qzone.qq.com','qq.com') 111 | self.Get(QzoneLoginUrl,'https://qzone.qq.com/') 112 | StarTime = date_to_millis(datetime.datetime.utcnow()) 113 | T = 0 114 | while True: 115 | T = T + 1 116 | 117 | self.Download('https://ssl.ptlogin2.qq.com/ptqrshow?appid=549000912&e=2&l=M&s=3&d=72&v=4&t=0.{0}6252926{1}2285{2}86&daid=5'.format(random.randint(0,9),random.randint(0,9),random.randint(0,9)), self.VPath) 118 | LoginSig = self.getCookie('pt_login_sig') 119 | QRSig = self.getCookie('qrsig') 120 | logging.info('[{0}] Get QRCode Picture Success.'.format(T)) 121 | while True: 122 | html = self.Get('https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&ptqrtoken={0}&ptredirect=0&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-0-{1}&js_ver=10220&js_type=1&login_sig={2}&pt_uistyle=40&aid=549000912&daid=5&'.format(getQRtoken(QRSig),date_to_millis(datetime.datetime.utcnow()) - StarTime, LoginSig), QzoneLoginUrl) 123 | # logging.info(html) 124 | ret = html.split("'") 125 | if ret[1] == '65' or ret[1] == '0': # 65: QRCode 失效, 0: 验证成功, 66: 未失效, 67: 验证中 126 | break 127 | time.sleep(2) 128 | if ret[1] == '0' or T > self.MaxTryTime: 129 | break 130 | 131 | if ret[1] != '0': 132 | raise ValueError, "RetCode = "+ret[1] 133 | return 134 | logging.critical("二维码已扫描,正在登陆") 135 | 136 | # 删除QRCode文件 137 | if os.path.exists(self.VPath): 138 | os.remove(self.VPath) 139 | 140 | # 记录登陆账号的昵称 141 | tmpUserName = ret[11] 142 | 143 | self.Get(ret[5]) 144 | UIN = getReValue(ret[5], r'uin=([0-9]+?)&', 'Fail to get QQ number', 1) 145 | Referer = Referer+str(UIN) 146 | skey = self.getCookie('p_skey') 147 | logging.critical("Successfully Login, Username: "+str(tmpUserName)) 148 | 149 | # ----------------- 150 | # 计算g_tk 151 | # ----------------- 152 | def utf8_unicode(c): 153 | if len(c)==1: 154 | return ord(c) 155 | elif len(c)==2: 156 | n = (ord(c[0]) & 0x3f) << 6 157 | n += ord(c[1]) & 0x3f 158 | return n 159 | elif len(c)==3: 160 | n = (ord(c[0]) & 0x1f) << 12 161 | n += (ord(c[1]) & 0x3f) << 6 162 | n += ord(c[2]) & 0x3f 163 | return n 164 | else: 165 | n = (ord(c[0]) & 0x0f) << 18 166 | n += (ord(c[1]) & 0x3f) << 12 167 | n += (ord(c[2]) & 0x3f) << 6 168 | n += ord(c[3]) & 0x3f 169 | return n 170 | 171 | def getGTK(skey): 172 | hash = 5381 173 | for i in range(0,len(skey)): 174 | hash += (hash << 5) + utf8_unicode(skey[i]) 175 | return hash & 0x7fffffff 176 | # ----------------- 177 | # LIKE 178 | # ----------------- 179 | def like(unikey,curkey,dataid,time,qztoken): 180 | reqURL = 'https://h5.qzone.qq.com/proxy/domain/w.qzone.qq.com/cgi-bin/likes/internal_dolike_app?g_tk={0}&qzonetoken={1}'.format(str(getGTK(skey)),str(qztoken)) 181 | data = ( 182 | ('qzreferrer', Referer), 183 | ('opuin', UIN), 184 | ('unikey', str(unikey)), 185 | ('curkey', str(curkey)), 186 | ('from', '1'), 187 | ('appid', '311'), 188 | ('typeid', '0'), 189 | ('abstime', str(time)), 190 | ('fid', str(dataid)), 191 | ('active', '0'), 192 | ('fupdate', '1') 193 | ) 194 | rsp = HttpClient_Ist.Post(reqURL, data, Referer) 195 | getReValue(rsp, r'"code":(0)', 'Fail to like unikey='+str(unikey)+';curkey='+str(curkey)+';fid='+str(dataid), 0) 196 | 197 | # ----------------- 198 | # 主函数 199 | # ----------------- 200 | def MsgHandler(): 201 | html=HttpClient_Ist.Get(Referer+'/infocenter?via=toolbar',Referer) 202 | fkey=re.findall(r'
    ', split_string[i+1]) 213 | if btn_string is None: 214 | continue 215 | abstime = re.search(r'data-abstime="(\d*?)"',split_string[i+1]) 216 | if abstime is None: 217 | continue 218 | like(btn_string.group(1),btn_string.group(2),fkey[i],abstime.group(1),qztoken) 219 | logging.info('已点赞'+btn_string.group(2)) 220 | except Exception, e: 221 | logging.error(str(e)) 222 | 223 | # ----------------- 224 | # 主程序 225 | # ----------------- 226 | 227 | if __name__ == "__main__": 228 | vpath = './v.png' 229 | qq = 0 230 | if len(sys.argv) > 1: 231 | vpath = sys.argv[1] 232 | if len(sys.argv) > 2: 233 | qq = sys.argv[2] 234 | 235 | try: 236 | qqLogin = Login(vpath, qq) 237 | except Exception, e: 238 | logging.critical(str(e)) 239 | os._exit(1) 240 | errtime=0 241 | while True: 242 | try: 243 | if errtime > 5: 244 | break 245 | MsgHandler() 246 | time.sleep(checkFrequency) 247 | errtime = 0 248 | except Exception, e: 249 | logging.error(str(e)) 250 | errtime = errtime + 1 251 | if sendtoflag!=0: 252 | logging.info("发送下线邮件...") 253 | errortime=0 254 | while errortime<5: 255 | errortime=errortime+1 256 | if sendfailmail(): 257 | break 258 | -------------------------------------------------------------------------------- /qqparking.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | QBOT 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 61 |
    62 | 65 |
    66 |

    See Usage: https://github.com/zeruniverse/QQParking

    67 |

    QQ挂机,私聊自动回复离开信息并调用人工智能库与对方聊天。对方留言记录并发送至您的邮箱

    68 |


    69 |

    Email to Receive Notification:

    70 |

    Welcome Message:

    71 |
    72 |
    73 |
    74 | 93 |
    94 |

    © Jeffery

    95 |
    96 | 97 | 98 | -------------------------------------------------------------------------------- /qqrobot.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | QBOT 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 61 |
    62 | 65 |
    66 |

    See Usage: https://github.com/zeruniverse/QQRobot

    67 |

    QQ小黄鸡,私聊智能回复,群聊功能见上面的网址

    68 |


    69 |

    Groups to Follow (需要关注的群群名,每个群占一行,不要有多余的空格和回车):

    70 |

    71 |

    Please Split group names with newline (Don't add extra space or Enter)

    72 |

    73 |

    Email to receive kick-off message (下线提醒邮箱,如不需要提醒请留空):

    74 |

    75 |
    76 |
    77 |
    78 | 97 |
    98 |

    © Jeffery

    99 |
    100 | 101 | 102 | -------------------------------------------------------------------------------- /qwrap.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.0.10.4 3 | -- http://www.phpmyadmin.net 4 | -- 5 | -- Host: localhost 6 | -- Generation Time: Sep 10, 2015 at 03:01 AM 7 | -- Server version: 5.5.41-MariaDB 8 | -- PHP Version: 5.4.16 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | SET time_zone = "+00:00"; 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8 */; 18 | 19 | -- 20 | -- Database: `qwrap` 21 | -- 22 | 23 | -- -------------------------------------------------------- 24 | 25 | -- 26 | -- Table structure for table `process` 27 | -- 28 | 29 | CREATE TABLE IF NOT EXISTS `process` ( 30 | `id` int(11) NOT NULL DEFAULT '0', 31 | `pid` int(11) DEFAULT NULL, 32 | `sid` varchar(10) NOT NULL, 33 | PRIMARY KEY (`id`) 34 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 35 | 36 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 37 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 38 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 39 | -------------------------------------------------------------------------------- /qzoneliker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | QBOT 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 61 |
    62 | 65 |
    66 |

    See Usage: https://github.com/zeruniverse/QzoneLiker

    67 |

    QQ空间点赞机,如需掉线邮件提醒请填入邮箱,否则请留空

    68 |


    69 |

    Email to receive kick-off message (下线提醒邮箱,如不需要提醒请留空):

    70 |

    71 |
    72 |
    73 |
    74 | 93 |
    94 |

    © Jeffery

    95 |
    96 | 97 | 98 | -------------------------------------------------------------------------------- /status.php: -------------------------------------------------------------------------------- 1 | fetch(PDO::FETCH_ASSOC); 8 | if ($result==FALSE) die('THIS PROCESS DOES NOT EXISTS OR ALREADY TERMINATED AND REMOVED FROM THE SERVER!'); 9 | ?> 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | QBOT 19 | 20 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 41 | 42 | 43 | 44 | 70 |
    71 | 74 |
    75 |

    1. Stay on this page until the QR Code is ready.

    76 |

    2. When QR Code is ready, you will see it in the QR Code part.

    77 |

    3. Scan QR Code with your mobile QQ or QQ security center.

    78 |

    4. Confirm that you successfully Login in Log.

    79 |

    5. Close this page and have a coffee!

    80 |


    81 |

    Please keep your session ID (SID): . You can go back to check the log, download the log file or terminate your bot. (keep SID confidential)

    82 |

    The QR Code and Log refreshes every 5 seconds.

    83 |

    The last few lines of log will be on the screen. If you want all log, please download the log (at the bottom of the log field).

    84 |


    85 |

    请等待二维码生成,当二维码生成后,下面的QR CODE部分会自动显示生成的二维码,在这以前请不要离开此页!

    86 |

    用手机QQ/安全中心扫描二维码,成功登陆后二维码会消失。二维码消失后即可关闭此页!

    87 |

    如果您需要返回检查LOG,请记住本次挂机的SID: (6位大写字母),在首页输入这个SID可以返回本页!(不要告诉别人SID,否则LOG会被偷看,bot可能被他人终止)

    88 |
    89 | 90 | 93 |
    94 | 97 |
    98 | 99 |
    100 | 101 | 104 |

    There is no go back! After click the following button, you have to login again! 结束机器人(不可逆操作)

    105 |

    106 | 107 |
    108 | 147 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /travis-ci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # check php syntax 3 | if [ $# -lt 1 ];then 4 | echo 'Usage: ' $0 'directory'; 5 | exit 1 6 | fi 7 | if [ ! -d $1 ];then 8 | echo $1 'not a directory,please check!'; 9 | exit 1 10 | fi 11 | directory=$1 12 | temp_file="myerrorfile" 13 | ls -R $directory | awk ' 14 | BEGIN{ 15 | FS="n" 16 | folder="'$directory'" 17 | logname="'$temp_file'" 18 | } 19 | { 20 | if($0~/.php$/){ 21 | system("php -l " folder "/" $0 " >> " logname " 2>&1") 22 | } 23 | if($0~/:$/){ 24 | folder=substr($1,1,length($1)-1) 25 | print folder 26 | } 27 | } 28 | ' 29 | if [ -e $temp_file ];then 30 | cat $temp_file | awk ' 31 | BEGIN{ 32 | error = 0 33 | } 34 | { 35 | if($0~/Parse/) { 36 | error++ 37 | print $0 38 | } 39 | } 40 | END{ 41 | print "Total Error:" error 42 | if(error>0) exit 1 43 | exit 0 44 | } 45 | ' 46 | else 47 | echo "php file not found." 48 | exit 1; 49 | fi 50 | --------------------------------------------------------------------------------