├── .babelrc ├── .gitignore ├── views ├── script.pug ├── index.pug ├── head.pug └── unauthorized.pug ├── static ├── favicon.png ├── index.css └── index.js ├── screenshots └── node-web-console.jpg ├── client ├── css │ └── index.css └── js │ └── index.js ├── config └── index.js ├── server ├── app.js └── RPCServer.js ├── package.json ├── README.zh-CN.md ├── README.md └── LICENSE /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/** 2 | .eslintignore 3 | .eslintrc.js 4 | .cache 5 | .vscode 6 | -------------------------------------------------------------------------------- /views/script.pug: -------------------------------------------------------------------------------- 1 | script. 2 | var NO_LOGIN = #{NO_LOGIN} 3 | script(src="/static/index.js") 4 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisCindy/node-web-console/HEAD/static/favicon.png -------------------------------------------------------------------------------- /screenshots/node-web-console.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ChrisCindy/node-web-console/HEAD/screenshots/node-web-console.jpg -------------------------------------------------------------------------------- /views/index.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | include head.pug 5 | body 6 | .shell 7 | include script.pug 8 | -------------------------------------------------------------------------------- /views/head.pug: -------------------------------------------------------------------------------- 1 | meta(charset="utf-8") 2 | meta(http-equiv="X-UA-Compatible", content="IE=edge") 3 | title Node Web Console 4 | meta(name="viewport", content="width=device-width, initial-scale=1") 5 | meta(name="description", content="Node Web Console") 6 | meta(name="author", content="chriscindy (http://www.fecoding.cn)") 7 | meta(name="robots", content="none") 8 | //- style 9 | link(rel="stylesheet", href="/static/index.css") 10 | link(rel="icon", type="image/png", sizes="16x16" href="/static/favicon.png") 11 | -------------------------------------------------------------------------------- /client/css/index.css: -------------------------------------------------------------------------------- 1 | body { background-color: #000000; } 2 | 3 | body, .terminal, .cmd, .terminal .terminal-output div div, .terminal .prompt { 4 | color: #cccccc; 5 | font-family: monospace, fixed; 6 | font-size: 15px; 7 | line-height: 18px; 8 | } 9 | 10 | a, a:hover, .terminal a, .terminal a:hover { color: #6c71c4; } 11 | 12 | .spaced { margin: 15px 0; } 13 | .spaced-top { margin: 15px 0 0 0; } 14 | .spaced-bottom { margin: 0 0 15px 0; } 15 | 16 | .configure { margin: 20px; } 17 | .configure .variable { color: #d33682; } 18 | .configure p, .configure ul { margin: 5px 0 0 0; } 19 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Disable login if set true (don't ask for credentials, be careful) 3 | noLogin: false, 4 | // Single-user credentials 5 | user: 'dev', 6 | password: 'dev', 7 | // Multi-user credentials 8 | // Example: 9 | // account: { 'user1': 'password1', 'user2':'password2' } 10 | accounts: {}, 11 | // Password hash algorithm (password must be hashed) 12 | // Example: 13 | // passwordHashAlgorithm: 'md5' 14 | // $PASSWORD_HASH_ALGORITHM: 'sha256' 15 | passwordHashAlgorithm: '', 16 | // Home directory (multi-user mode supported) 17 | // Example: 18 | // homeDirectory: /tmp' 19 | // homeDirectory: {user1': '/home/user1', 'user2': '/home/user2' } 20 | homeDirectory: '' 21 | } 22 | -------------------------------------------------------------------------------- /views/unauthorized.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | include head.pug 5 | body 6 | .configure 7 | p Node Web Console must be configured before use: 8 | ul 9 | li Open the project with your favorite text editor. 10 | li 11 | | Open 12 | span.variable config/index.js 13 | | and enter your 14 | span.variable $USER 15 | | and 16 | span.variable $PASSWORD 17 | | credentials, edit any other settings that you like (see description in the comments). 18 | p 19 | | For more information visit: 20 | a(href="https://github.com/ChrisCindy/node-web-console") https://github.com/ChrisCindy/node-web-console 21 | -------------------------------------------------------------------------------- /server/app.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa') 2 | const serve = require('koa-static') 3 | const views = require('koa-views') 4 | const bodyParser = require('koa-bodyparser') 5 | const c2k = require('koa-connect') 6 | const Router = require('koa-router') 7 | const mount = require('koa-mount') 8 | const path = require('path') 9 | const { RPCServer, isConfigured, noLogin } = require('./RPCServer') 10 | 11 | const server = new Koa() 12 | server.use(bodyParser()) 13 | server.use(async (ctx, next) => { 14 | try { 15 | ctx.req.body = ctx.request.body 16 | await next() 17 | } catch (err) { 18 | ctx.status = 500 19 | ctx.message = err.message || 'Sorry, an error has occurred.' 20 | } 21 | }) 22 | 23 | server.use(views(path.join(__dirname, '../views'), { 24 | extension: 'pug' 25 | })) 26 | 27 | server.use(mount('/static', serve(path.join(__dirname, '../static')))) 28 | 29 | const router = new Router() 30 | router.get('/console', async (ctx) => { 31 | if (isConfigured) { 32 | await ctx.render('index', { 33 | NO_LOGIN: noLogin 34 | }) 35 | } else { 36 | await ctx.render('unauthorized') 37 | } 38 | }) 39 | router.post('/rpc', c2k(RPCServer.middleware())) 40 | 41 | server.use(router.routes()).use(router.allowedMethods()) 42 | 43 | server.listen(3000) 44 | console.log('server started and listens on port 3000') 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-web-console", 3 | "version": "1.0.0", 4 | "description": "a simple web-based SSH, remote shell in your browser based on Node.js, inspired by web-console", 5 | "main": "server/app.js", 6 | "scripts": { 7 | "client:dev": "parcel watch client/js/index.js -d static", 8 | "server:dev": "cross-env NODE_ENV=development nodemon server/app.js", 9 | "client:build": "cross-env NODE_ENV=production parcel build client/js/index.js -d static", 10 | "prod": "npm run client:build && cross-env NODE_ENV=production pm2 start server/app.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/ChrisCindy/node-web-console.git" 15 | }, 16 | "keywords": [ 17 | "web", 18 | "console", 19 | "nodejs" 20 | ], 21 | "author": "ChrisCindy", 22 | "license": "ISC", 23 | "bugs": { 24 | "url": "https://github.com/ChrisCindy/node-web-console/issues" 25 | }, 26 | "homepage": "https://github.com/ChrisCindy/node-web-console#readme", 27 | "dependencies": { 28 | "jayson": "^2.0.6", 29 | "jquery": "^3.3.1", 30 | "jquery-mousewheel": "^3.1.13", 31 | "jquery.terminal": "^1.15.0", 32 | "koa": "^2.5.1", 33 | "koa-bodyparser": "^4.2.0", 34 | "koa-connect": "^2.0.1", 35 | "koa-mount": "^3.0.0", 36 | "koa-router": "^7.4.0", 37 | "koa-static": "^4.0.2", 38 | "koa-views": "^6.1.4", 39 | "natural-compare-lite": "^1.4.0", 40 | "normalize.css": "^8.0.0", 41 | "pug": "^2.0.3" 42 | }, 43 | "devDependencies": { 44 | "babel-eslint": "^8.2.3", 45 | "cross-env": "^5.1.5", 46 | "eslint": "^5.14.1", 47 | "eslint-config-standard": "^11.0.0", 48 | "eslint-plugin-import": "^2.11.0", 49 | "eslint-plugin-node": "^6.0.1", 50 | "eslint-plugin-promise": "^3.7.0", 51 | "eslint-plugin-standard": "^3.1.0", 52 | "nodemon": "^1.17.4", 53 | "parcel-bundler": "^1.8.1" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /README.zh-CN.md: -------------------------------------------------------------------------------- 1 | [English](./README.md) | 简体中文 2 | ``` 3 | _ __ __ _ __ __ ______ __ 4 | / | / /___ ____/ /__ | | / /__ / /_ / ____/___ ____ _________ / /__ 5 | / |/ / __ \/ __ / _ \ | | /| / / _ \/ __ \ / / / __ \/ __ \/ ___/ __ \/ / _ \ 6 | / /| / /_/ / /_/ / __/ | |/ |/ / __/ /_/ / / /___/ /_/ / / / (__ ) /_/ / / __/ 7 | /_/ |_/\____/\__,_/\___/ |__/|__/\___/_.___/ \____/\____/_/ /_/____/\____/_/\___/ 8 | 9 | ``` 10 | ## 概要 11 | 12 | Node-Web-Console 是基于 Node.js 开发的一个网页版应用(可以理解为网页版的 SSH)。它允许你直接从浏览器向服务器发送并执行 shell 命令。这个项目受到另一个 php 项目 [web-console](https://github.com/nickola/web-console) 的启发并基于其移植而来。Node-Web-Console 非常轻量,其不需要依赖数据库,同时能够在 3 分钟内配置完毕。 13 | 14 | ![](./screenshots/node-web-console.jpg) 15 | 16 | ## 特性 17 | 18 | - 界面整洁友好,看起来就像是真的 shell 终端 19 | - 易于扩展。Node-Web-Console 使用 [Koa](https://github.com/koajs/koa) 作为 web 服务器,你可以很容易地扩展或者将其集成到你自己的项目中 20 | - 安全。你可以在你的服务器上配置 HTTPS(SSL),然后 Node-Web-Console 的所有流量都将受到保护。同时,Node-Web-Console 设置了标记,不允许搜索引擎索引其所有页面 21 | - 极速配置。Node-Web-Console 是一个纯 Node.js 项目,其可被极快地安装和配置使用 22 | - 移动端友好。Node-Web-Console 支持移动浏览器上的软键盘输入。因此你可以在你的移动设备上方便地使用它 23 | 24 | ## 安装 25 | 26 | Node-Web-Console 使用 [Koa](https://github.com/koajs/koa) 作为 web 服务器,因此 node 版本需要至少 7.6.0 或者更高。 27 | 28 | ```shell 29 | git clone https://github.com/ChrisCindy/node-web-console.git 30 | cd node-web-console 31 | 32 | # 安装依赖 33 | npm install 34 | ``` 35 | 36 | ## 上手 37 | 38 | - 配置选项 39 | 40 | 打开 `config/index.js` 并输入你的 `$USER` 和 `$PASSWORD` 凭证,同时你可以编辑其他任何设置(注释中有设置的描述)。 41 | 42 | - 启动 web 服务器 43 | 44 | - Development mode 45 | 46 | ```shell 47 | ## 构建并且监听前端脚本及样式表 48 | npm run client:dev 49 | 50 | ## 打开另一个 shell 51 | ## 启动 web 服务器 52 | npm run server:dev 53 | ``` 54 | 55 | - Production mode 56 | 57 | ```shell 58 | ## 构建并且压缩前端脚本和样式表 59 | npm run client:build 60 | 61 | ## 使用 pm2 启动 web 服务器 62 | npm run prod 63 | ``` 64 | 65 | - 在浏览器打开 `http://localhost:3000/console`,开始使用吧。 66 | 67 | 68 | ## 证书 69 | 70 | Node-Web-Console 使用 [GNU LGPL Version 3](http://www.gnu.org/licenses/lgpl.html) 证书。 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | English | [简体中文](./README.zh-CN.md) 2 | ``` 3 | _ __ __ _ __ __ ______ __ 4 | / | / /___ ____/ /__ | | / /__ / /_ / ____/___ ____ _________ / /__ 5 | / |/ / __ \/ __ / _ \ | | /| / / _ \/ __ \ / / / __ \/ __ \/ ___/ __ \/ / _ \ 6 | / /| / /_/ / /_/ / __/ | |/ |/ / __/ /_/ / / /___/ /_/ / / / (__ ) /_/ / / __/ 7 | /_/ |_/\____/\__,_/\___/ |__/|__/\___/_.___/ \____/\____/_/ /_/____/\____/_/\___/ 8 | 9 | ``` 10 | ## Summary 11 | 12 | Node-Web-Console is a web-based Node.js application that allows to execute shell commands on a server directly from a browser (web-based SSH). This project is inspired by the php-based [web-console](https://github.com/nickola/web-console). 13 | The application is very light, does not require any database and can be installed and configured in about 3 minutes. 14 | 15 | ![](./screenshots/node-web-console.jpg) 16 | 17 | ## Features 18 | 19 | - Clean interface, which looks and feels like a real shell terminal 20 | - Easy to extend. Node-Web-Console uses [Koa](https://github.com/koajs/koa) to start the web server. You can easily extend it or integrate it to your own project 21 | - Secure. You can configure HTTPS (SSL) on your web server and all Node-Web-Console traffic will be protected. Also, Node-Web-Console has a mark to search engines that will disallow the Node-Web-Console page from indexing 22 | - Fast configuration. Node-Web-Console is a pure Node.js project and can be installed and configured quickly 23 | - Mobile friendly. Node-Web-Console supports inputs from the virtual keyboard in the mobile browser. So you can use it conveniently in your mobile devices like iPad, iPhone and Android phones. 24 | 25 | 26 | ## Installation 27 | 28 | Node-Web-Console uses [Koa](https://github.com/koajs/koa) to start the web server, so it requires node v7.6.0 or higher. 29 | 30 | ```shell 31 | git clone https://github.com/ChrisCindy/node-web-console.git 32 | cd node-web-console 33 | 34 | # instal dependencies 35 | npm install 36 | ``` 37 | 38 | ## Getting Started 39 | 40 | - configure the settings 41 | 42 | open `config/index.js` and enter your `$USER` and `$PASSWORD` credentials, edit any other settings that you like (see description in the comments). 43 | 44 | - start the web server 45 | 46 | - Development mode 47 | 48 | ```shell 49 | ## build and watch client side scripts and stylesheets 50 | npm run client:dev 51 | 52 | ## open another shell 53 | ## start the web server 54 | npm run server:dev 55 | ``` 56 | 57 | - Production mode 58 | 59 | ```shell 60 | ## build and minify client side scripts and stylesheets 61 | npm run client:build 62 | 63 | ## start the server with pm2 64 | npm run prod 65 | ``` 66 | 67 | - open `http://localhost:3000/console` in your browser and enjoy it. 68 | 69 | ## License 70 | 71 | Node-Web-Console is licensed under [GNU LGPL Version 3](http://www.gnu.org/licenses/lgpl.html) license. 72 | -------------------------------------------------------------------------------- /client/js/index.js: -------------------------------------------------------------------------------- 1 | // CSS 2 | import 'normalize.css' 3 | import 'jquery.terminal/css/jquery.terminal.min.css' 4 | import '../css/index.css' 5 | 6 | const $ = require('jquery') 7 | const jt = require('jquery.terminal') 8 | jt(window, $) 9 | require('jquery-mousewheel')($) 10 | 11 | const settings = { 12 | // url: `//${window.location.hostname}:4000/`, 13 | url: `/rpc`, 14 | promptPathLength: 32, 15 | domain: document.domain || window.location.host, 16 | isSmallWindow: $(document).width() < 625 17 | } 18 | const environment = { 19 | user: '', 20 | hostname: '', 21 | path: '' 22 | } 23 | /* global NO_LOGIN */ 24 | const noLogin = NO_LOGIN 25 | let silentMode = false 26 | 27 | // Default banner 28 | let bannerMain = 'Node Web Console' 29 | const bannerLink = 'https://github.com/ChrisCindy/node-web-console' 30 | let bannerExtra = `${bannerLink}\n` 31 | 32 | // Big banner 33 | if (!settings.isSmallWindow) { 34 | bannerMain = 35 | ' _ __ __ _ __ __ ______ __' + 36 | '\n / | / /___ ____/ /__ | | / /__ / /_ / ____/___ ____ _________ / /__ ' + 37 | '\n / |/ / __ \\/ __ / _ \\ | | /| / / _ \\/ __ \\ / / / __ \\/ __ \\/ ___/ __ \\/ / _ \\' + 38 | '\n / /| / /_/ / /_/ / __/ | |/ |/ / __/ /_/ / / /___/ /_/ / / / (__ ) /_/ / / __/' + 39 | '\n/_/ |_/\\____/\\__,_/\\___/ |__/|__/\\___/_.___/ \\____/\\____/_/ /_/____/\\____/_/\\___/ ' 40 | bannerExtra = `\n${bannerLink}\n` 41 | } 42 | 43 | let terminal = null 44 | 45 | init() 46 | 47 | function init () { 48 | terminal = $('.shell').terminal(interpreter, { 49 | login: !noLogin ? login : false, 50 | prompt: makePrompt(), 51 | greetings: !noLogin ? 'You are authenticated' : '', 52 | completion: completion, 53 | exceptionHandler: function (exception) { 54 | if (!silentMode) { 55 | terminal.exception(exception) 56 | } 57 | } 58 | }).css({ 59 | overflow: 'auto' 60 | }) 61 | 62 | // Logout 63 | if (noLogin) { 64 | terminal.set_token('NO_LOGIN') 65 | } else { 66 | logout() 67 | $(window).on('unload', () => { 68 | logout() 69 | }) 70 | } 71 | 72 | // Banner 73 | if (bannerMain) { 74 | terminal.echo(bannerMain) 75 | } 76 | if (bannerExtra) { 77 | terminal.echo(bannerExtra) 78 | } 79 | } 80 | 81 | // Output 82 | function showOutput (output) { 83 | if (output) { 84 | if (typeof output === 'string') { 85 | terminal.echo(output) 86 | } else if (output instanceof Array) { 87 | terminal.echo($.map(output, function (object) { 88 | return $.json_stringify(object) 89 | }).join(' ')) 90 | } else if (typeof output === 'object') { 91 | terminal.echo($.json_stringify(output)) 92 | } else { 93 | terminal.echo(output) 94 | } 95 | } 96 | } 97 | 98 | // Prompt 99 | function makePrompt () { 100 | let path = environment.path 101 | if (path && path.length > settings.promptPathLength) { 102 | path = `...${path.slice(path.length - settings.promptPathLength + 3)}` 103 | } 104 | return `[[b;#d33682;]${(environment.user || 'user')}]@[[b;#6c71c4;]${(environment.hostname || settings.domain || 'node-web-console')}]${(path || '~')}$ ` 105 | } 106 | 107 | function updatePrompt (terminal) { 108 | terminal.set_prompt(makePrompt()) 109 | } 110 | 111 | // Environment 112 | function updateEnvironment (terminal, data) { 113 | if (data) { 114 | $.extend(environment, data) 115 | updatePrompt(terminal) 116 | } 117 | } 118 | 119 | // Service 120 | function service (terminal, method, parameters, success, error, options) { 121 | options = $.extend({ 'pause': true }, options) 122 | if (options.pause) { 123 | terminal.pause() 124 | } 125 | $.jrpc(settings.url, method, parameters, function (json) { 126 | if (options.pause) { 127 | terminal.resume() 128 | } 129 | 130 | if (!json.error) { 131 | if (success) { 132 | success(json.result) 133 | } 134 | } else if (error) { 135 | error() 136 | } else { 137 | let message = $.trim(json.error.message || '') 138 | let data = $.trim(json.error.data || '') 139 | 140 | if (!message && data) { 141 | message = data 142 | data = '' 143 | } 144 | terminal.error(`[ERROR] RPC: ${(message || 'Unknown error')}${(data ? (' (' + data + ')') : '')}`) 145 | } 146 | }, function (xhr, status, errorData) { 147 | if (options.pause) { 148 | terminal.resume() 149 | } 150 | 151 | if (error) { 152 | error() 153 | } else { 154 | if (status !== 'abort') { 155 | const response = $.trim(xhr.responseText || '') 156 | 157 | terminal.error(`[ERROR] AJAX: ${(status || 'Unknown error')}${(response ? ('\nServer reponse:\n' + response) : '')}`) 158 | } 159 | } 160 | }) 161 | } 162 | 163 | function serviceAuthenticated (terminal, method, parameters, success, error, options) { 164 | const token = terminal.token() 165 | if (token) { 166 | const serviceParameters = [token, environment] 167 | if (parameters && parameters.length) { 168 | serviceParameters.push.apply(serviceParameters, parameters) 169 | } 170 | service(terminal, method, serviceParameters, success, error, options) 171 | } else { 172 | // Should never happen 173 | terminal.error('[ERROR] Access denied (no authentication token found)') 174 | } 175 | } 176 | 177 | // Interpreter 178 | function interpreter (command, terminal) { 179 | command = $.trim(command || '') 180 | if (!command) { 181 | return 182 | } 183 | 184 | const commandParsed = $.terminal.parse_command(command) 185 | let method = null 186 | let parameters = [] 187 | 188 | if (commandParsed.name.toLowerCase() === 'cd') { 189 | method = 'cd' 190 | parameters = [commandParsed.args.length ? commandParsed.args[0] : ''] 191 | } else { 192 | method = 'run' 193 | parameters = [command] 194 | } 195 | 196 | if (method) { 197 | serviceAuthenticated(terminal, method, parameters, function (result) { 198 | updateEnvironment(terminal, result.environment) 199 | showOutput(result.output) 200 | }) 201 | } 202 | } 203 | 204 | // Login 205 | function login (user, password, callback) { 206 | user = $.trim(user || '') 207 | password = $.trim(password || '') 208 | 209 | if (user && password) { 210 | service(terminal, 'login', [user, password], function (result) { 211 | if (result && result.token) { 212 | environment.user = user 213 | // FIXME: updateEnvironment not work Synchronously 214 | setTimeout(() => { 215 | updateEnvironment(terminal, result.environment) 216 | }, 0) 217 | showOutput(result.output) 218 | callback(result.token) 219 | } else { 220 | callback(null) 221 | } 222 | }, function () { 223 | callback(null) 224 | }) 225 | } else { 226 | callback(null) 227 | } 228 | } 229 | 230 | // Completion 231 | function completion (pattern, callback) { 232 | const view = this.terminal().export_view() 233 | const command = view.command.substring(0, view.position) 234 | 235 | serviceAuthenticated(terminal, 'completion', [pattern, command], function (result) { 236 | showOutput(result.output) 237 | 238 | if (result.completion && result.completion.length) { 239 | result.completion.reverse() 240 | callback(result.completion) 241 | } 242 | }, null, { pause: false }) 243 | } 244 | 245 | // Logout 246 | function logout () { 247 | silentMode = true 248 | 249 | try { 250 | terminal.clear() 251 | terminal.logout() 252 | } catch (error) { } 253 | 254 | silentMode = false 255 | } 256 | -------------------------------------------------------------------------------- /server/RPCServer.js: -------------------------------------------------------------------------------- 1 | const crypto = require('crypto') 2 | const os = require('os') 3 | const fs = require('fs') 4 | const path = require('path') 5 | const { execSync } = require('child_process') 6 | require('natural-compare-lite') 7 | const jayson = require('jayson') 8 | const config = require('../config') 9 | 10 | function getHash (algorithm, str) { 11 | const hash = crypto.createHash(algorithm) 12 | hash.update(str.trim()) 13 | return hash.digest('hex') 14 | } 15 | 16 | function isDirectory (thePath) { 17 | return fs.existsSync(thePath) && fs.statSync(thePath).isDirectory() 18 | } 19 | 20 | // Command execution 21 | function executeCommand (command) { 22 | return execSync(`${command} 2>&1`, { 23 | encoding: 'utf8' 24 | }) 25 | } 26 | 27 | // Initializing 28 | if (config.user && config.password) { 29 | config.accounts[config.user] = config.password 30 | } 31 | const isConfigured = config.noLogin || Object.keys(config.accounts).length >= 1 32 | 33 | // RPC Server 34 | let HOME_DIRECTORY = '' 35 | 36 | const methods = { 37 | error: (message) => { 38 | throw new Error(message) 39 | }, 40 | 41 | // Authentication 42 | authenticateUser: (user, password) => { 43 | user = user.trim() 44 | password = password.trim() 45 | if (user && password) { 46 | if (config.accounts[user]) { 47 | if (config.passwordHashAlgorithm) { 48 | password = getHash(config.passwordHashAlgorithm, password) 49 | } 50 | if (password === config.accounts[user]) { 51 | return `${user}:${getHash('sha256', password)}` 52 | } 53 | } 54 | } 55 | throw new Error('Incorrect user or password') 56 | }, 57 | authenticateToken: (token) => { 58 | if (config.noLogin) { 59 | return true 60 | } 61 | token = token.trim() 62 | const tokenParts = token.split(':', 2) 63 | 64 | if (tokenParts.length === 2) { 65 | const user = tokenParts[0].trim() 66 | const passwordHash = tokenParts[1].trim() 67 | 68 | if (user && passwordHash) { 69 | if (config.accounts) { 70 | const realPasswordHash = getHash('sha256', config.accounts[user]) 71 | if (passwordHash === realPasswordHash) { 72 | return user 73 | } 74 | } 75 | } 76 | } 77 | 78 | throw new Error('Incorrect user or password') 79 | }, 80 | getHomeDirectory: (user) => { 81 | if (typeof config.homeDirectory === 'string') { 82 | if (config.homeDirectory) { 83 | return config.homeDirectory 84 | } 85 | } else if (typeof user === 'string' && user && config.homeDirectory.user) { 86 | return config.homeDirectory.user 87 | } 88 | return process.cwd() 89 | }, 90 | 91 | // Environment 92 | getEnvironment: () => { 93 | return { 94 | path: process.cwd(), 95 | hostname: os.hostname() 96 | } 97 | }, 98 | setEnvironment: (environment = {}, methods) => { 99 | const thePath = environment.path || HOME_DIRECTORY 100 | if (thePath) { 101 | if (isDirectory(thePath)) { 102 | try { 103 | process.chdir(thePath) 104 | } catch (e) { 105 | return { 106 | output: 'Unable to change directory to current working directory, updating current directory', 107 | environment: methods.getEnvironment.handler() 108 | } 109 | } 110 | } 111 | } else { 112 | return { 113 | output: 'Current working directory not found, updating current directory', 114 | environment: methods.getEnvironment.handler() 115 | } 116 | } 117 | }, 118 | 119 | // Initialization 120 | initialize: (token, environment, methods) => { 121 | const user = methods.authenticateToken.handler(token) 122 | HOME_DIRECTORY = methods.getHomeDirectory.handler(user) 123 | const result = methods.setEnvironment.handler(environment, methods) 124 | if (result) { 125 | return result 126 | } 127 | }, 128 | 129 | // Methods 130 | login: (user, password, methods) => { 131 | const result = { 132 | token: methods.authenticateUser.handler(user, password), 133 | environment: methods.getEnvironment.handler() 134 | } 135 | const homeDirectory = methods.getHomeDirectory.handler(user) 136 | if (homeDirectory) { 137 | if (isDirectory(homeDirectory)) { 138 | result.environment.path = homeDirectory 139 | } else { 140 | result.output = `Home directory not found: ${homeDirectory}` 141 | } 142 | } 143 | return result 144 | }, 145 | cd: (token, environment, thePath, methods) => { 146 | const result = methods.initialize.handler(token, environment, methods) 147 | if (result) { 148 | return result 149 | } 150 | thePath = thePath.trim() 151 | if (!thePath) { 152 | thePath = HOME_DIRECTORY 153 | } 154 | if (thePath) { 155 | if (isDirectory(thePath)) { 156 | try { 157 | process.chdir(thePath) 158 | } catch (e) { 159 | return { 160 | output: `cd ${thePath}: Unable to change directory` 161 | } 162 | } 163 | } else { 164 | return { 165 | output: `cd ${thePath}: No such directory` 166 | } 167 | } 168 | } 169 | return { 170 | environment: methods.getEnvironment.handler() 171 | } 172 | }, 173 | completion: (token, environment, pattern, command, methods) => { 174 | const result = methods.initialize.handler(token, environment, methods) 175 | if (result) { 176 | return result 177 | } 178 | let scanPath = '' 179 | let completionPrefix = '' 180 | let completion = [] 181 | 182 | if (pattern) { 183 | if (!isDirectory(pattern)) { 184 | pattern = path.dirname(pattern) 185 | pattern = pattern === '.' ? '' : pattern 186 | } 187 | if (pattern) { 188 | if (isDirectory(pattern)) { 189 | scanPath = completionPrefix = pattern 190 | if (completionPrefix.substr(-1) !== '/') { 191 | completionPrefix += '/' 192 | } 193 | } 194 | } else { 195 | scanPath = process.cwd() 196 | } 197 | } else { 198 | scanPath = process.cwd() 199 | } 200 | 201 | if (scanPath) { 202 | // Loading directory listing 203 | completion = fs.readdirSync(scanPath) 204 | completion.sort(String.naturalCompare) 205 | 206 | // Prefix 207 | if (completionPrefix && completion.length > 0) { 208 | completion = completion.map(c => completionPrefix + c) 209 | } 210 | // Pattern 211 | if (pattern && completion.length > 0) { 212 | completion = completion.filter(c => { 213 | return pattern === c.substr(0, pattern.length) 214 | }) 215 | } 216 | } 217 | 218 | return { 219 | completion 220 | } 221 | }, 222 | 223 | run: (token, environment, command, methods) => { 224 | const result = methods.initialize.handler(token, environment, methods) 225 | if (result) { 226 | return result 227 | } 228 | let output = command ? executeCommand(command) : '' 229 | if (output && output.substr(-1) === '\n') { 230 | output = output.substr(0, output.length - 1) 231 | } 232 | return { 233 | output 234 | } 235 | } 236 | } 237 | 238 | const RPCServer = jayson.server(methods, { 239 | router (method, params) { 240 | return (p, cb) => { 241 | try { 242 | const result = this._methods[method].handler(...p, this._methods) 243 | cb(null, result) 244 | } catch (e) { 245 | console.log(e) 246 | const error = { 247 | code: 500, 248 | message: e.message || 'Internal Error' 249 | } 250 | cb(error) 251 | } 252 | } 253 | } 254 | }) 255 | 256 | module.exports = { 257 | RPCServer, 258 | isConfigured, 259 | noLogin: config.noLogin 260 | } 261 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /static/index.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}/*! 2 | * __ _____ ________ __ 3 | * / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / 4 | * __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / 5 | * / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ 6 | * \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ 7 | * \/ /____/ version 1.15.0 8 | * http://terminal.jcubic.pl 9 | * 10 | * This file is part of jQuery Terminal. 11 | * 12 | * Copyright (c) 2011-2018 Jakub Jankiewicz 13 | * Released under the MIT license 14 | * 15 | * Date: Sun, 13 May 2018 09:34:11 +0000 16 | */.cmd .format,.cmd .prompt,.cmd .prompt div,.terminal .terminal-output .format,.terminal .terminal-output div div{display:inline-block}.cmd,.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6,.terminal pre{margin:0}.terminal h1,.terminal h2,.terminal h3,.terminal h4,.terminal h5,.terminal h6{line-height:1.2em}.cmd .clipboard{position:absolute;left:-16px;top:0;width:20px;height:16px;background:transparent;border:none;color:transparent;outline:none;padding:0;resize:none;z-index:1000;overflow:hidden;white-space:pre;text-indent:-9999em}.terminal audio,.terminal canvas,.terminal img,.terminal object,.terminal value{cursor:default}.terminal .error{color:red}.terminal{position:relative;overflow-y:auto}.cmd,.terminal{contain:content}body.terminal{height:100%;min-height:100vh;margin:0}.terminal>div{overflow:hidden}.terminal>.font .resizer,.terminal>.resizer{position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;z-index:-1;visibility:hidden;height:100%;border:none;padding:0;width:100%}.cmd{padding:0;position:relative;float:left;padding-bottom:3px}.terminal a[tabindex="1000"],.terminal a[tabindex="1000"]:active,.terminal a[tabindex="1000"]:focus{outline:none}.cmd .inverted,.terminal .inverted{background-color:#aaa;color:#000}.cmd .cursor{border-bottom:3px solid transparent;margin-bottom:-3px;background-clip:content-box}.cmd .cursor.blink{animation:terminal-blink 1s infinite step-start;border-left:1px solid transparent;margin-left:-1px}.bar.cmd .inverted,.bar.terminal .inverted{border-left-color:#aaa}.cmd .prompt,.terminal .terminal-output div div{display:block;line-height:14px;height:auto}.terminal .terminal-output>div:not(.raw) div{white-space:nowrap}.cmd .prompt>span{float:left}.cmd,.terminal{font-family:monospace;color:#aaa;background-color:#000;font-size:12px;line-height:14px;box-sizing:border-box;cursor:text}.cmd div{clear:both}.cmd .prompt+div{clear:right}.terminal-output>div>div{min-height:14px}terminal .terminal-output>div{margin-top:-1px}.terminal-output>div.raw>div *{overflow-wrap:break-word;word-wrap:break-word}.terminal .font{position:absolute;font-size:inherit;width:1em;height:1em;top:-100%;left:0;margin-bottom:1px}.terminal .terminal-output div span{display:inline-block}.cmd>span:not(.prompt){float:left}.cmd .prompt span.line{display:block;float:none}.terminal table{border-collapse:collapse}.terminal td{border:1px solid #aaa}.cmd .prompt span::-moz-selection,.cmd>div::-moz-selection,.cmd>div span::-moz-selection,.cmd>span::-moz-selection,.cmd>span span::-moz-selection,.cmd div::-moz-selection,.terminal .terminal-output .raw div::-moz-selection,.terminal .terminal-output div div::-moz-selection,.terminal .terminal-output div div a::-moz-selection,.terminal .terminal-output div span::-moz-selection,.terminal h1::-moz-selection,.terminal h2::-moz-selection,.terminal h3::-moz-selection,.terminal h4::-moz-selection,.terminal h5::-moz-selection,.terminal h6::-moz-selection,.terminal pre::-moz-selection,.terminal td::-moz-selection{background-color:#aaa;color:#000}.cmd .prompt span::selection,.cmd>div::selection,.cmd>div span::selection,.cmd>span::selection,.cmd>span span::selection,.cmd div::selection,.terminal .terminal-output .raw div::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection{background-color:hsla(0,0%,67%,.99);color:#000}.terminal .terminal-output div.error,.terminal .terminal-output div.error div{color:red;color:var(--error-color,red)}.tilda{position:fixed;top:0;left:0;width:100%;z-index:1100}.ui-dialog-content .terminal{width:100%;height:100%;box-sizing:border-box}.ui-dialog .ui-dialog-content.dterm{padding:0}.clear{clear:both}.terminal a{color:#0f60ff;color:var(--link-color,#0f60ff)}.terminal a:hover{background:#0f60ff;background:var(--link-color,#0f60ff);color:var(--background,#000);text-decoration:none}.terminal .terminal-fill{position:absolute;left:0;top:-100%;width:100%;height:100%;margin:1px 0 0;border:none;opacity:.01;pointer-events:none;box-sizing:border-box}.terminal,.terminal .terminal-fill{padding:10px}@keyframes terminal-blink{0%,to{background-color:#000;color:#aaa}50%{background-color:#bbb;color:#000}}@keyframes terminal-bar{0%,to{border-left-color:#aaa}50%{border-left-color:#000}}@keyframes terminal-underline{0%,to{border-bottom-color:#aaa;position:relative;line-height:12px;margin-top:1px;border-left:none;margin-left:0}50%{border-bottom-color:#000;position:relative;line-height:12px;margin-top:1px;border-left:none;margin-left:0}}.underline-animation .cursor.blink{border-left:none;animation-name:terminal-underline}.bar-animation .cursor.blink{animation-name:terminal-bar}@supports (--css:variables){.cmd,.terminal{color:var(--color,#aaa);background-color:var(--background,#000)}.terminal .font{width:calc(var(--size, 1) * 1em);height:calc(var(--size, 1) * 1em)}.terminal span[style*="--length"]{width:calc(var(--length, 1) * var(--char-width, 7.23438) * 1px);display:inline-block}.cmd,.cmd .prompt,.terminal,.terminal .terminal-output>div>div{font-size:calc(var(--size, 1) * 12px);line-height:calc(var(--size, 1) * 14px)}.terminal .terminal-output>div>div{min-height:calc(var(--size, 1) * 14px)}.cmd .inverted,.terminal .inverted{background-color:var(--color,#aaa);color:var(--background,#000)}.cmd .cursor.blink{animation:var(--animation,terminal-blink) 1s infinite step-start;color:var(--color,#aaa);background-color:var(--background,#000)}.cmd .prompt span::-moz-selection,.cmd>div::-moz-selection,.cmd>div span::-moz-selection,.cmd>span::-moz-selection,.cmd>span span::-moz-selection,.cmd div::-moz-selection,.terminal .terminal-output div div::-moz-selection,.terminal .terminal-output div div a::-moz-selection,.terminal .terminal-output div span::-moz-selection,.terminal h1::-moz-selection,.terminal h2::-moz-selection,.terminal h3::-moz-selection,.terminal h4::-moz-selection,.terminal h5::-moz-selection,.terminal h6::-moz-selection,.terminal pre::-moz-selection,.terminal td::-moz-selection{background-color:var(--color,#aaa);color:var(--background,#000)}.cmd .prompt span::selection,.cmd>div::selection,.cmd>div span::selection,.cmd>span::selection,.cmd>span span::selection,.cmd div::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection{background-color:var(--color,hsla(0,0%,67%,.99));color:var(--background,#000)}@keyframes terminal-blink{0%,to{background-color:var(--background,#000);color:var(--color,#aaa)}50%{background-color:var(--color,#aaa);color:var(--background,#000)}}@keyframes terminal-bar{0%,to{border-left-color:var(--background,#000)}50%{border-left-color:var(--color,#aaa)}}@keyframes terminal-underline{0%,to{border-bottom-color:var(--background,#000);position:relative;line-height:calc(var(--size, 1) * 12px);margin-top:calc(var(--size, 1) * 1px);border-left:none;margin-left:0}50%{border-bottom-color:var(--color,#aaa);position:relative;line-height:calc(var(--size, 1) * 12px);margin-top:calc(var(--size, 1) * 1px);border-left:none;margin-left:0}}}@supports (-ms-ime-align:auto){.cmd .prompt span::selection,.cmd>div::selection,.cmd>div span::selection,.cmd>span::selection,.cmd>span span::selection,.cmd div::selection,.terminal .terminal-output div div::selection,.terminal .terminal-output div div a::selection,.terminal .terminal-output div span::selection,.terminal h1::selection,.terminal h2::selection,.terminal h3::selection,.terminal h4::selection,.terminal h5::selection,.terminal h6::selection,.terminal pre::selection,.terminal td::selection{background-color:hsla(0,0%,67%,.99);color:#000}}body{background-color:#000}.cmd,.terminal,.terminal .prompt,.terminal .terminal-output div div,body{color:#ccc;font-family:monospace,fixed;font-size:15px;line-height:18px}.terminal a,.terminal a:hover,a,a:hover{color:#6c71c4}.spaced{margin:15px 0}.spaced-top{margin:15px 0 0}.spaced-bottom{margin:0 0 15px}.configure{margin:20px}.configure .variable{color:#d33682}.configure p,.configure ul{margin:5px 0 0} -------------------------------------------------------------------------------- /static/index.js: -------------------------------------------------------------------------------- 1 | parcelRequire=function(e,r,n,t){function i(n,t){function o(e){return i(o.resolve(e))}function c(r){return e[n][1][r]||r}if(!r[n]){if(!e[n]){var l="function"==typeof parcelRequire&&parcelRequire;if(!t&&l)return l(n,!0);if(u)return u(n,!0);if(f&&"string"==typeof n)return f(n);var p=new Error("Cannot find module '"+n+"'");throw p.code="MODULE_NOT_FOUND",p}o.resolve=c;var a=r[n]=new i.Module(n);e[n][0].call(a.exports,o,a,a.exports,this)}return r[n].exports}function o(e){this.id=e,this.bundle=i,this.exports={}}var u="function"==typeof parcelRequire&&parcelRequire,f="function"==typeof require&&require;i.isParcelRequire=!0,i.Module=o,i.modules=e,i.cache=r,i.parent=u;for(var c=0;c1)for(var n=1;n0&&t-1 in e)}w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return a.call(this)},get:function(e){return null==e?a.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(a.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,y,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!v||!v.test(e))){if(1!==T)m=t,y=e;else if("object"!==t.nodeName.toLowerCase()){for((c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;s--;)h[s]="#"+c+" "+ye(h[s]);y=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(y)try{return L.apply(r,m.querySelectorAll(y)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];return function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){for(var n=e.split("|"),i=n.length;i--;)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(h=(d=a).documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&g)return t.getElementsByClassName(e)},y=[],v=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||v.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),y.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),y=y.length&&new RegExp(y.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!y||!y.test(t))&&(!v||!v.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){for(;t=e[o++];)t===e[o]&&(i=r.push(o));for(;i--;)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else for(;t=e[r++];)n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",v=t.parentNode,y=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(v){if(o){for(;g;){for(p=t;p=p[g];)if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?v.firstChild:v.lastChild],a&&m){for(x=(d=(l=(c=(f=(p=v)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&v.childNodes[d];p=++d&&p&&p[g]||(x=d=0)||h.pop();)if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)for(;(p=++d&&p&&p[g]||(x=d=0)||h.pop())&&((s?p.nodeName.toLowerCase()!==y:1!==p.nodeType)||!++x||(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p!==t)););return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){for(var r,o=i(e,t),a=o.length;a--;)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){for(var o,a=r(e,null,i,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s-1&&(o[l]=!(a[l]=f))}}else y=be(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):L.apply(a,y)})}function Te(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&xe(p),u>1&&ye(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,v,y=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){for(h=0,a||f.ownerDocument===d||(p(f),s=!g);v=e[h++];)if(v(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!v&&f)&&y--,o&&x.push(f))}if(y+=m,n&&m!==y){for(h=0;v=t[h++];)v(x,b,a,s);if(o){if(y>0)for(;m--;)x[m]||b[m]||(b[m]=j.call(u));b=be(b)}L.apply(u,b),c&&!o&&b.length>0&&y+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}(o,i))).selector=e}return s},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}for(o=V.needsContext.test(e)?0:u.length;o--&&(l=u[o],!r.relative[c=l.type]);)if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ye(u)))return L.apply(n,i),n;break}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(t);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return v(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return l.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var r,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:i,!0)),A.test(r[1])&&w.isPlainObject(t))for(r in t)v(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(o=i.getElementById(r[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):v(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(i);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?l.call(w(e),this[0]):l.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){return e}function I(e){throw e}function W(e,t,n,r){var i;try{e&&v(i=e.promise)?i.call(e).done(t).fail(n):e&&v(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.Callbacks=function(e){e="string"==typeof e?function(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1)for(n=a.shift();++s-1;)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l},w.extend({Deferred:function(e){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=v(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&v(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(e,r,i){var o=0;function a(e,n,r,i){return function(){var s=this,u=arguments,l=function(){var t,l;if(!(e=o&&(r!==I&&(s=void 0,u=[t]),n.rejectWith(s,u))}};e?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),t.setTimeout(c))}}return w.Deferred(function(t){n[0][3].add(a(0,t,v(i)?i:R,t.notifyWith)),n[1][3].add(a(0,t,v(e)?e:R)),n[2][3].add(a(0,t,v(r)?r:I))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),e&&e.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=a.call(arguments),o=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?a.call(arguments):n,--t||o.resolveWith(r,i)}};if(t<=1&&(W(e,o.done(s(n)).resolve,o.reject,!t),"pending"===o.state()||v(i[n]&&i[n].then)))return o.then();for(;n--;)W(i[n],s(n),o.reject);return o.promise()}});var $=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(e,n){t.console&&t.console.warn&&e&&$.test(e.name)&&t.console.warn("jQuery.Deferred exception: "+e.message,e.stack,n)},w.readyException=function(e){t.setTimeout(function(){throw e})};var B=w.Deferred();function F(){i.removeEventListener("DOMContentLoaded",F),t.removeEventListener("load",F),w.ready()}w.fn.ready=function(e){return B.then(e).catch(function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||B.resolveWith(i,[w]))}}),w.ready.then=B.then,"complete"===i.readyState||"loading"!==i.readyState&&!i.documentElement.doScroll?t.setTimeout(w.ready):(i.addEventListener("DOMContentLoaded",F),t.addEventListener("load",F));var _=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===b(n))for(s in i=!0,n)_(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,v(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){J.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Q.get(e,t),n&&(!r||Array.isArray(n)?r=Q.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){w.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Q.get(e,n)||Q.access(e,n,{empty:w.Callbacks("once memory").add(function(){Q.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,pe=/^$|^module$|\/(?:java|ecma)script/i,de={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function he(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ge(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=he(f.appendChild(o),"script"),l&&ge(a),n)for(c=0;o=a[c++];)pe.test(o.type||"")&&n.push(o);return f}ve=i.createDocumentFragment().appendChild(i.createElement("div")),(ye=i.createElement("input")).setAttribute("type","radio"),ye.setAttribute("checked","checked"),ye.setAttribute("name","t"),ve.appendChild(ye),g.checkClone=ve.cloneNode(!0).cloneNode(!0).lastChild.checked,ve.innerHTML="",g.noCloneChecked=!!ve.cloneNode(!0).lastChild.defaultValue;var be=i.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return i.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(e);if(v)for(n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(t){return void 0!==w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;l--;)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){for(l=(t=(t||"").match(M)||[""]).length;l--;)if(d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){for(f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||w.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=w.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=w.event.special[s.type]||{};for(u[0]=s,t=1;t=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")&&w(e).children("tbody")[0]||e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n1&&"string"==typeof h&&!g.checkClone&&je.test(h))return e.each(function(i){var o=e.eq(i);y&&(t[0]=h.call(this,i,o.html())),Me(o,t,n,r)});if(p&&(o=(i=xe(t,e[0].ownerDocument,!1,e,r)).firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(a=w.map(he(i,"script"),He)).length;f")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=w.contains(e.ownerDocument,e);if(!(g.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=he(c),r=0,i=(o=he(e)).length;r0&&ge(a,!f&&he(e,"script")),c},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(G(n)){if(t=n[Q.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[Q.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Re(this,e,!0)},remove:function(e){return Re(this,e)},text:function(e){return _(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Me(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Me(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Me(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Me(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(he(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return _(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!de[(fe.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function Ke(e,t,n){var r=We(e),i=Be(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(Ie.test(i)){if(!n)return i;i="auto"}return a=a&&(g.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Je(e,t,n||(o?"border":"content"),a,r,i)+"px"}function Ze(e,t,n,r,i){return new Ze.prototype.init(e,t,n,r,i)}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=V(t),u=ze.test(t),l=e.style;if(u||(t=Ye(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=ne.exec(n))&&i[1]&&(n=ae(e,t,i),o="number"),null!=n&&n==n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),g.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=V(t);return ze.test(t)||(t=Ye(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Ue&&(i=Ue[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!_e.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ke(e,t,r):oe(e,Xe,function(){return Ke(e,t,r)})},set:function(e,n,r){var i,o=We(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Je(e,t,r,a,o);return a&&g.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Je(e,t,"border",!1,o)-.5)),s&&(i=ne.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Qe(0,n,s)}}}),w.cssHooks.marginLeft=Fe(g.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-oe(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+re[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Qe)}),w.fn.extend({css:function(e,t){return _(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=We(e),i=t.length;a1)}}),w.Tween=Ze,Ze.prototype={constructor:Ze,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=Ze.propHooks[this.prop];return e&&e.get?e.get(this):Ze.propHooks._default.get(this)},run:function(e){var t,n=Ze.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ze.propHooks._default.set(this),this}},Ze.prototype.init.prototype=Ze.prototype,Ze.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},Ze.propHooks.scrollTop=Ze.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=Ze.prototype.init,w.fx.step={};var et,tt,nt=/^(?:toggle|show|hide)$/,rt=/queueHooks$/;function it(){tt&&(!1===i.hidden&&t.requestAnimationFrame?t.requestAnimationFrame(it):t.setTimeout(it,w.fx.interval),w.fx.tick())}function ot(){return t.setTimeout(function(){et=void 0}),et=Date.now()}function at(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=re[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function st(e,t,n){for(var r,i=(ut.tweeners[t]||[]).concat(ut.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?lt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!g.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),lt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ct[t]||w.find.attr;ct[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ct[a],ct[a]=i,i=null!=n(e,t,r)?a:null,ct[a]=o),i}});var ft=/^(?:input|select|textarea|button)$/i,pt=/^(?:a|area)$/i;function dt(e){return(e.match(M)||[]).join(" ")}function ht(e){return e.getAttribute&&e.getAttribute("class")||""}function gt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(M)||[]}w.fn.extend({prop:function(e,t){return _(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):ft.test(e.nodeName)||pt.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),g.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this}),w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(v(e))return this.each(function(t){w(this).addClass(e.call(this,t,ht(this)))});if((t=gt(e)).length)for(;n=this[u++];)if(i=ht(n),r=1===n.nodeType&&" "+dt(i)+" "){for(a=0;o=t[a++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=dt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(v(e))return this.each(function(t){w(this).removeClass(e.call(this,t,ht(this)))});if(!arguments.length)return this.attr("class","");if((t=gt(e)).length)for(;n=this[u++];)if(i=ht(n),r=1===n.nodeType&&" "+dt(i)+" "){for(a=0;o=t[a++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");i!==(s=dt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):v(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,ht(this),t),t)}):this.each(function(){var t,i,o,a;if(r)for(i=0,o=w(this),a=gt(e);t=a[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||((t=ht(this))&&Q.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":Q.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+dt(ht(n))+" ").indexOf(t)>-1)return!0;return!1}});var vt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];return arguments.length?(r=v(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))})):i?(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(vt,""):null==n?"":n:void 0}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:dt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},g.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),g.focusin="onfocusin"in t;var yt=/^(?:focusinfocus|focusoutblur)$/,mt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(e,n,r,o){var a,s,u,l,c,f,d,h,g=[r||i],m=p.call(e,"type")?e.type:e,x=p.call(e,"namespace")?e.namespace.split("."):[];if(s=h=u=r=r||i,3!==r.nodeType&&8!==r.nodeType&&!yt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,(e=e[w.expando]?e:new w.Event(m,"object"==typeof e&&e)).isTrigger=o?2:3,e.namespace=x.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=r),n=null==n?[e]:w.makeArray(n,[e]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(r,n))){if(!o&&!d.noBubble&&!y(r)){for(l=d.delegateType||m,yt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)g.push(s),u=s;u===(r.ownerDocument||i)&&g.push(u.defaultView||u.parentWindow||t)}for(a=0;(s=g[a++])&&!e.isPropagationStopped();)h=s,e.type=a>1?l:d.bindType||m,(f=(Q.get(s,"events")||{})[e.type]&&Q.get(s,"handle"))&&f.apply(s,n),(f=c&&s[c])&&f.apply&&G(s)&&(e.result=f.apply(s,n),!1===e.result&&e.preventDefault());return e.type=m,o||e.isDefaultPrevented()||d._default&&!1!==d._default.apply(g.pop(),n)||!G(r)||c&&v(r[m])&&!y(r)&&((u=r[c])&&(r[c]=null),w.event.triggered=m,e.isPropagationStopped()&&h.addEventListener(m,mt),r[m](),e.isPropagationStopped()&&h.removeEventListener(m,mt),w.event.triggered=void 0,u&&(r[c]=u)),e.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),g.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=Q.access(r,t);i||r.addEventListener(e,n,!0),Q.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=Q.access(r,t)-1;i?Q.access(r,t,i):(r.removeEventListener(e,n,!0),Q.remove(r,t))}}});var xt=t.location,bt=Date.now(),wt=/\?/;w.parseXML=function(e){var n;if(!e||"string"!=typeof e)return null;try{n=(new t.DOMParser).parseFromString(e,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+e),n};var Tt=/\[\]$/,Ct=/\r?\n/g,Et=/^(?:submit|button|image|reset|file)$/i,kt=/^(?:input|select|textarea|keygen)/i;function St(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||Tt.test(e)?r(e,i):St(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==b(t))r(e,t);else for(i in t)St(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=v(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)St(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&kt.test(this.nodeName)&&!Et.test(e)&&(this.checked||!ce.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Ct,"\r\n")}}):{name:t.name,value:n.replace(Ct,"\r\n")}}).get()}});var Dt=/%20/g,Nt=/#.*$/,At=/([?&])_=[^&]*/,jt=/^(.*?):[ \t]*([^\r\n]*)$/gm,qt=/^(?:GET|HEAD)$/,Lt=/^\/\//,Ht={},Ot={},Pt="*/".concat("*"),Mt=i.createElement("a");function Rt(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(v(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function It(e,t,n,r){var i={},o=e===Ot;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function Wt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}Mt.href=xt.href,w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:xt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(xt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Pt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Wt(Wt(e,w.ajaxSettings),t):Wt(w.ajaxSettings,e)},ajaxPrefilter:Rt(Ht),ajaxTransport:Rt(Ot),ajax:function(e,n){"object"==typeof e&&(n=e,e=void 0),n=n||{};var r,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,v=h.context&&(g.nodeType||g.jquery)?w(g):w.event,y=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s)for(s={};t=jt.exec(a);)s[t[1].toLowerCase()]=t[2];t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return r&&r.abort(t),k(0,t),this}};if(y.promise(E),h.url=((e||h.url||xt.href)+"").replace(Lt,xt.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=i.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Mt.protocol+"//"+Mt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),It(Ht,h,n,E),c)return E;for(p in(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!qt.test(h.type),o=h.url.replace(Nt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(Dt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(wt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(At,"$1"),d=(wt.test(o)?"&":"?")+"_="+bt+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+Pt+"; q=0.01":""):h.accepts["*"]),h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),r=It(Ot,h,n,E)){if(E.readyState=1,f&&v.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=t.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,r.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(e,n,i,s){var l,p,d,b,T,C=n;c||(c=!0,u&&t.clearTimeout(u),r=void 0,a=s||"",E.readyState=e>0?4:0,l=e>=200&&e<300||304===e,i&&(b=function(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;"*"===u[0];)u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(h,E,i)),b=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e.throws)t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===e||"HEAD"===h.type?C="nocontent":304===e?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!e&&C||(C="error",e<0&&(e=0))),E.status=e,E.statusText=(n||C)+"",l?y.resolveWith(g,[p,C,E]):y.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&v.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(v.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return v(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(v(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return v(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new t.XMLHttpRequest}catch(e){}};var $t={0:200,1223:204},Bt=w.ajaxSettings.xhr();g.cors=!!Bt&&"withCredentials"in Bt,g.ajax=Bt=!!Bt,w.ajaxTransport(function(e){var n,r;if(g.cors||Bt&&!e.crossDomain)return{send:function(i,o){var a,s=e.xhr();if(s.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(a in e.xhrFields)s[a]=e.xhrFields[a];for(a in e.mimeType&&s.overrideMimeType&&s.overrideMimeType(e.mimeType),e.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest"),i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o($t[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&t.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(e.hasContent&&e.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){var t,n;if(e.crossDomain)return{send:function(r,o){t=w("