├── src
├── common
│ ├── config
│ │ ├── locale
│ │ │ └── en.js
│ │ ├── env
│ │ │ ├── production.js
│ │ │ ├── testing.js
│ │ │ └── development.js
│ │ ├── route.js
│ │ ├── config.js
│ │ ├── view.js
│ │ ├── db.js
│ │ └── websocket.js
│ ├── bootstrap
│ │ ├── hook.js
│ │ └── start.js
│ └── controller
│ │ └── error.js
└── home
│ ├── config
│ └── config.js
│ ├── model
│ └── index.js
│ ├── controller
│ ├── base.js
│ ├── index.js
│ └── socket.js
│ └── logic
│ └── index.js
├── www
├── static
│ ├── img
│ │ ├── bg.jpg
│ │ └── dialog.png
│ ├── libs
│ │ ├── record
│ │ │ ├── recorder.js
│ │ │ └── recorderWorker.js
│ │ ├── custombox
│ │ │ ├── legacy.min.js
│ │ │ ├── custombox.min.js
│ │ │ └── custombox.min.css
│ │ ├── caret.js
│ │ ├── jquery.qrcode.min.js
│ │ └── twemoji.min.js
│ ├── css
│ │ └── chat.css
│ └── js
│ │ └── chat.js
├── testing.js
├── production.js
├── index.js
└── README.md
├── .thinkjsrc
├── pm2.json
├── README.md
├── package.json
├── .gitignore
├── view
├── home
│ ├── index_test.html
│ ├── index_login.html
│ └── index_index.html
└── common
│ ├── error_404.html
│ └── error_400.html
└── nginx.conf
/src/common/config/locale/en.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export default {
4 |
5 | };
--------------------------------------------------------------------------------
/src/common/config/env/production.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export default {
4 |
5 | };
--------------------------------------------------------------------------------
/src/common/config/env/testing.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export default {
4 |
5 | };
--------------------------------------------------------------------------------
/src/common/config/env/development.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export default {
4 |
5 | };
--------------------------------------------------------------------------------
/www/static/img/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizheming/anychat/HEAD/www/static/img/bg.jpg
--------------------------------------------------------------------------------
/www/static/img/dialog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lizheming/anychat/HEAD/www/static/img/dialog.png
--------------------------------------------------------------------------------
/.thinkjsrc:
--------------------------------------------------------------------------------
1 | {
2 | "createAt": "2016-01-24 13:48:41",
3 | "mode": "module",
4 | "es6": true
5 | }
6 |
--------------------------------------------------------------------------------
/src/common/config/route.js:
--------------------------------------------------------------------------------
1 | // export default {
2 | // [/^chat\/(\d+)$/, "home/index/chat?r=:1"]
3 | // }
--------------------------------------------------------------------------------
/src/home/config/config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * config
4 | */
5 | export default {
6 | //key: value
7 | };
--------------------------------------------------------------------------------
/src/home/model/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * model
4 | */
5 | export default class extends think.model.base {
6 |
7 | }
--------------------------------------------------------------------------------
/src/common/bootstrap/hook.js:
--------------------------------------------------------------------------------
1 | /**
2 | * this file will be loaded before server started
3 | * you can register app hook
4 | */
5 |
--------------------------------------------------------------------------------
/src/home/controller/base.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export default class extends think.controller.base {
4 | /**
5 | * some base method in here
6 | */
7 | }
--------------------------------------------------------------------------------
/src/common/config/config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * config
4 | */
5 | export default {
6 | //cluster_on: true //socket.io not support cluster mode
7 | //key: value
8 | route_on: false
9 | };
10 |
--------------------------------------------------------------------------------
/src/common/config/view.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * template config
4 | */
5 | export default {
6 | content_type: 'text/html',
7 | file_ext: '.html',
8 | file_depr: '_',
9 | root_path: think.ROOT_PATH + '/view',
10 | type: 'ejs',
11 | options: {}
12 | };
--------------------------------------------------------------------------------
/pm2.json:
--------------------------------------------------------------------------------
1 | {
2 | "apps": [{
3 | "name": "websocket-socket.io",
4 | "script": "production.js",
5 | "cwd": "/var/www/anychat/www",
6 | "max_memory_restart": "1G",
7 | "autorestart": true,
8 | "node_args": [],
9 | "args": [],
10 | "env": {
11 |
12 | }
13 | }]
14 | }
15 |
--------------------------------------------------------------------------------
/src/common/bootstrap/start.js:
--------------------------------------------------------------------------------
1 | /**
2 | * this file will be loaded before server started
3 | * you can define global functions used in controllers, models, templates
4 | */
5 |
6 | /**
7 | * use global.xxx to define global functions
8 | *
9 | * global.fn1 = function(){
10 | *
11 | * }
12 | */
--------------------------------------------------------------------------------
/www/testing.js:
--------------------------------------------------------------------------------
1 | var thinkjs = require('thinkjs');
2 | var path = require('path');
3 |
4 | var rootPath = path.dirname(__dirname);
5 |
6 | var instance = new thinkjs({
7 | APP_PATH: rootPath + '/app',
8 | ROOT_PATH: rootPath,
9 | RESOURCE_PATH: __dirname,
10 | env: 'testing'
11 | });
12 |
13 | instance.run();
--------------------------------------------------------------------------------
/www/production.js:
--------------------------------------------------------------------------------
1 | var thinkjs = require('thinkjs');
2 | var path = require('path');
3 |
4 | var rootPath = path.dirname(__dirname);
5 |
6 | var instance = new thinkjs({
7 | APP_PATH: rootPath + '/app',
8 | ROOT_PATH: rootPath,
9 | RESOURCE_PATH: __dirname,
10 | env: 'production'
11 | });
12 |
13 | instance.run();
--------------------------------------------------------------------------------
/www/index.js:
--------------------------------------------------------------------------------
1 | var thinkjs = require('thinkjs');
2 | var path = require('path');
3 |
4 | var rootPath = path.dirname(__dirname);
5 |
6 | var instance = new thinkjs({
7 | APP_PATH: rootPath + '/app',
8 | ROOT_PATH: rootPath,
9 | RESOURCE_PATH: __dirname,
10 | env: 'development'
11 | });
12 | instance.compile(true);
13 | instance.run();
--------------------------------------------------------------------------------
/src/common/config/db.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * db config
4 | * @type {Object}
5 | */
6 | export default {
7 | type: 'mysql',
8 | host: '127.0.0.1',
9 | port: '',
10 | name: '',
11 | user: '',
12 | pwd: '',
13 | prefix: 'think_',
14 | encoding: 'utf8',
15 | nums_per_page: 10,
16 | log_sql: true,
17 | log_connect: true,
18 | cache: {
19 | on: true,
20 | type: '',
21 | timeout: 3600
22 | }
23 | };
--------------------------------------------------------------------------------
/src/common/config/websocket.js:
--------------------------------------------------------------------------------
1 | export default {
2 | on: true, //是否开启 WebSocket
3 | type: "socket.io",
4 | allow_origin: "",
5 | sub_protocal: "",
6 | adapter: undefined,
7 | path: "", //url path for websocket
8 | messages: {
9 | open: 'home/socket/open',
10 | close: 'home/socket/close',
11 | chat: 'home/socket/chat',
12 | adduser: 'home/socket/adduser',
13 | voice: '/home/socket/voice'
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## README
2 |
3 | application created by [ThinkJS](http://www.thinkjs.org)
4 |
5 | ## install dependencies
6 |
7 | ```
8 | npm install
9 | ```
10 |
11 | ## start server
12 |
13 | ```
14 | npm start
15 | ```
16 |
17 | ## deploy with pm2
18 |
19 | ```
20 | pm2 startOrReload pm2.json
21 | ```
22 |
23 | ## TODO
24 |
25 | - [X] 消息声音通知以及标签栏闪烁通知
26 | - [ ] 聊天表情和图片
27 | - [X] @ 支持
28 | - [X] 命令模式
29 | - [X] 昵称修改
30 | - [ ] 聊天记录保存
31 | - [X] 增加二维码网址分享
32 | - [X] 语音
33 | - [X] 字母头像
34 |
--------------------------------------------------------------------------------
/src/home/controller/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import Base from './base.js';
4 |
5 | export default class extends Base {
6 | /**
7 | * index action
8 | * @return {Promise} []
9 | */
10 | indexAction() {
11 | //'http://localhost:8360'
12 | this.assign('socketUrl', 'http://' + this.http.host);
13 | return this.display();
14 | }
15 |
16 | loginAction() {
17 | return this.display();
18 | }
19 |
20 | testAction() {
21 | return this.display();
22 | }
23 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "anychat",
3 | "description": "project created by thinkjs",
4 | "version": "1.0.1",
5 | "scripts": {
6 | "start": "node www/index.js",
7 | "compile": "babel --loose all --optional runtime --stage 0 --modules common src/ --out-dir app/",
8 | "watch-compile": "npm run compile -- --watch"
9 | },
10 | "dependencies": {
11 | "babel": "5.8.21",
12 | "babel-runtime": "5.6.17",
13 | "socket.io": "^1.3.7",
14 | "thinkjs": "2.0.x"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/home/logic/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * logic
4 | * @param {} []
5 | * @return {} []
6 | */
7 | export default class extends think.logic.base {
8 | /**
9 | * index action logic
10 | * @return {} []
11 | */
12 | indexAction(){
13 | this.checkRoom();
14 | }
15 |
16 | chatAction() {
17 | this.checkRoom();
18 | }
19 |
20 | loginAction() {
21 | this.checkRoom();
22 | }
23 |
24 | checkRoom() {
25 | /** 必须选择一个聊天室否则随机 **/
26 | if( !this.get('room') ) {
27 | this.http.redirect('?room=' + think.md5(Date.now()).slice(0,8) );
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage/
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # node-waf configuration
20 | .lock-wscript
21 |
22 | # Dependency directory
23 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
24 | node_modules/
25 |
26 | # IDE config
27 | .idea
28 |
29 | # output
30 | app/
31 | output/
32 | output.tar.gz
33 |
--------------------------------------------------------------------------------
/view/home/index_test.html:
--------------------------------------------------------------------------------
1 | hello
2 |
3 |
4 |
34 |
--------------------------------------------------------------------------------
/www/README.md:
--------------------------------------------------------------------------------
1 | ## application
2 |
3 | ### start server
4 |
5 | *development*
6 |
7 | ```js
8 | node www/index.js
9 | ```
10 |
11 | *testing*
12 |
13 | ```js
14 | node www/testing.js
15 | ```
16 |
17 | *production*
18 |
19 | ```js
20 | node www/production.js
21 | ```
22 |
23 | or use pm2 to manage node:
24 |
25 | ```
26 | pm2 start www/production.js
27 | ```
28 |
29 | ### compile es6 code
30 |
31 | ```
32 | npm run compile
33 | ```
34 |
35 | watch file change:
36 |
37 | ```
38 | npm run wacth-compile
39 | ```
40 |
41 | ### how to link resource
42 |
43 | *in template file*
44 |
45 | ```html
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | ```
54 |
55 | *link image in css*
56 |
57 | ```css
58 | .a{
59 | background: url(../img/a.png) no-repeat;
60 | }
61 | ```
--------------------------------------------------------------------------------
/nginx.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | server_name localhost1;
4 | root /Users/welefen/Develop/git/thinkjs2-demos/websocket-socket.io/www;
5 | set $node_port 8360;
6 |
7 | index index.js index.html index.htm;
8 | if ( -f $request_filename/index.html ){
9 | rewrite (.*) $1/index.html break;
10 | }
11 | if ( !-f $request_filename ){
12 | rewrite (.*) /index.js;
13 | }
14 | location = /index.js {
15 | proxy_http_version 1.1;
16 | proxy_set_header Connection "";
17 | proxy_set_header X-Real-IP $remote_addr;
18 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
19 | proxy_set_header Host $http_host;
20 | proxy_set_header X-NginX-Proxy true;
21 | proxy_set_header Upgrade $http_upgrade;
22 | proxy_set_header Connection "upgrade";
23 | proxy_pass http://127.0.0.1:$node_port$request_uri;
24 | proxy_redirect off;
25 | }
26 | location ~ /static/ {
27 | etag on;
28 | expires max;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/common/controller/error.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * error controller
4 | */
5 | export default class extends think.controller.base {
6 | /**
7 | * display error page
8 | * @param {Number} status []
9 | * @return {Promise} []
10 | */
11 | displayErrorPage(status){
12 | let module = 'common';
13 | if(think.mode !== think.mode_module){
14 | module = this.config('default_module');
15 | }
16 | let file = `${module}/error/${status}.html`;
17 | let options = this.config('tpl');
18 | options = think.extend({}, options, {type: 'ejs'});
19 | return this.display(file, options);
20 | }
21 | /**
22 | * Bad Request
23 | * @return {Promise} []
24 | */
25 | _400Action(){
26 | return this.displayErrorPage(400);
27 | }
28 | /**
29 | * Forbidden
30 | * @return {Promise} []
31 | */
32 | _403Action(){
33 | return this.displayErrorPage(403);
34 | }
35 | /**
36 | * Not Found
37 | * @return {Promise} []
38 | */
39 | _404Action(){
40 | return this.displayErrorPage(404);
41 | }
42 | /**
43 | * Internal Server Error
44 | * @return {Promise} []
45 | */
46 | _500Action(){
47 | return this.displayErrorPage(500);
48 | }
49 | /**
50 | * Service Unavailable
51 | * @return {Promise} []
52 | */
53 | _503Action(){
54 | return this.displayErrorPage(503);
55 | }
56 | }
--------------------------------------------------------------------------------
/view/home/index_login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | anychat
6 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
88 |
89 |
--------------------------------------------------------------------------------
/src/home/controller/socket.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import Base from './base.js';
4 |
5 | var chatrooms = {};
6 |
7 | export default class extends Base {
8 | openAction() {
9 |
10 | }
11 |
12 | chatAction(self) {
13 | var {
14 | room, userId, message
15 | } = self.http.data;
16 | var members = chatrooms[room];
17 |
18 | if (!members[userId]) return false;
19 |
20 | this.broadTo('chat', {
21 | displayName: members[userId].displayName,
22 | message
23 | }, room, userId);
24 | }
25 |
26 | voiceAction(self) {
27 | var {
28 | room, userId, message
29 | } = self.http.data;
30 | var members = chatrooms[room];
31 |
32 | if (!members[userId]) return false;
33 |
34 | this.broadTo('chat:voice', {
35 | displayName: members[userId].displayName,
36 | message
37 | }, room, userId);
38 | }
39 |
40 | closeAction(self) {
41 | var socket = self.http.socket;
42 | var logoutRoom, logoutUserId, logoutUser;
43 | for (var room in chatrooms) {
44 | var members = chatrooms[room];
45 | for (var userId in members) {
46 | if (members[userId].socket === socket) {
47 | logoutRoom = room;
48 | logoutUserId = userId;
49 | logoutUser = members[userId];
50 | }
51 | }
52 | }
53 |
54 | if (!logoutUserId) return true;
55 |
56 | var displayName = logoutUser.displayName;
57 | delete chatrooms[logoutRoom][logoutUserId];
58 |
59 | /**通知其他用户有用户离开并更新成员列表**/
60 | this.broadTo('user:exit', {
61 | exit: displayName,
62 | users: this.getUsers(logoutRoom)
63 | }, logoutRoom);
64 | }
65 |
66 | adduserAction(self) {
67 | var socket = self.http.socket;
68 | var {
69 | room, userId, displayName
70 | } = self.http.data;
71 | if (!chatrooms[room]) {
72 | chatrooms[room] = {};
73 | }
74 |
75 | var members = chatrooms[room];
76 | while (members[userId]) {
77 | userId += 1;
78 | }
79 |
80 | /**通知其他用户有新用户加入,并更新用户列表**/
81 | this.broadTo('user:join', {
82 | join: displayName,
83 | users: this.getUsers(room).concat([displayName])
84 | }, room);
85 |
86 | members[userId] = {
87 | displayName, socket
88 | };
89 |
90 | /**告诉本用户加入成功并更新用户 Id**/
91 | this.emit('user:login', {
92 | userId, users: this.getUsers(room)
93 | });
94 | }
95 |
96 | broadTo(event, data, room, filter = false) {
97 | var members = chatrooms[room] || {};
98 | for (var i in members) {
99 | if (i === filter) continue;
100 | let member = members[i];
101 | member.socket.emit(event, data);
102 | }
103 | }
104 |
105 | getUsers(room) {
106 | var members = chatrooms[room];
107 |
108 | return Object.keys(members).map(member => ({id: member, name: members[member].displayName}));
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/www/static/libs/record/recorder.js:
--------------------------------------------------------------------------------
1 | /*License (MIT)
2 |
3 | Copyright © 2013 Matt Diamond
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation
7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
8 | to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of
11 | the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
14 | THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
16 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17 | DEALINGS IN THE SOFTWARE.
18 | */
19 |
20 | (function(window){
21 |
22 | var WORKER_PATH = '/static/libs/record/recorderWorker.js';
23 |
24 | var Recorder = function(source, cfg){
25 | var config = cfg || {};
26 | var bufferLen = config.bufferLen || 4096;
27 | this.context = source.context;
28 | if(!this.context.createScriptProcessor){
29 | this.node = this.context.createJavaScriptNode(bufferLen, 2, 2);
30 | } else {
31 | this.node = this.context.createScriptProcessor(bufferLen, 2, 2);
32 | }
33 |
34 | var worker = new Worker(config.workerPath || WORKER_PATH);
35 | worker.postMessage({
36 | command: 'init',
37 | config: {
38 | sampleRate: this.context.sampleRate
39 | }
40 | });
41 | var recording = false,
42 | currCallback;
43 |
44 | this.node.onaudioprocess = function(e){
45 | if (!recording) return;
46 | worker.postMessage({
47 | command: 'record',
48 | buffer: [
49 | e.inputBuffer.getChannelData(0),
50 | e.inputBuffer.getChannelData(1)
51 | ]
52 | });
53 | }
54 |
55 | this.configure = function(cfg){
56 | for (var prop in cfg){
57 | if (cfg.hasOwnProperty(prop)){
58 | config[prop] = cfg[prop];
59 | }
60 | }
61 | }
62 |
63 | this.record = function(){
64 | recording = true;
65 | }
66 |
67 | this.stop = function(){
68 | recording = false;
69 | }
70 |
71 | this.clear = function(){
72 | worker.postMessage({ command: 'clear' });
73 | }
74 |
75 | this.getBuffers = function(cb) {
76 | currCallback = cb || config.callback;
77 | worker.postMessage({ command: 'getBuffers' })
78 | }
79 |
80 | this.exportWAV = function(cb, type){
81 | currCallback = cb || config.callback;
82 | type = type || config.type || 'audio/wav';
83 | if (!currCallback) throw new Error('Callback not set');
84 | worker.postMessage({
85 | command: 'exportWAV',
86 | type: type
87 | });
88 | }
89 |
90 | this.exportMonoWAV = function(cb, type){
91 | currCallback = cb || config.callback;
92 | type = type || config.type || 'audio/wav';
93 | if (!currCallback) throw new Error('Callback not set');
94 | worker.postMessage({
95 | command: 'exportMonoWAV',
96 | type: type
97 | });
98 | }
99 |
100 | worker.onmessage = function(e){
101 | var blob = e.data;
102 | currCallback(blob);
103 | }
104 |
105 | source.connect(this.node);
106 | this.node.connect(this.context.destination); // if the script node is not connected to an output the "onaudioprocess" event is not triggered in chrome.
107 | };
108 |
109 | Recorder.setupDownload = function(blob, filename){
110 | var url = (window.URL || window.webkitURL).createObjectURL(blob);
111 | var link = document.getElementById("save");
112 | link.href = url;
113 | link.download = filename || 'output.wav';
114 | }
115 |
116 | window.Recorder = Recorder;
117 |
118 | })(window);
119 |
--------------------------------------------------------------------------------
/view/home/index_index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | anychat
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
26 |
27 |
36 |
50 |
65 |
75 |
76 |
81 |
82 |
83 |
84 |
88 |
89 |
按住空格键(Space)说话
90 |
91 |
92 |
93 |
94 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/www/static/libs/record/recorderWorker.js:
--------------------------------------------------------------------------------
1 | /*License (MIT)
2 |
3 | Copyright © 2013 Matt Diamond
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6 | documentation files (the "Software"), to deal in the Software without restriction, including without limitation
7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
8 | to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of
11 | the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
14 | THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
16 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17 | DEALINGS IN THE SOFTWARE.
18 | */
19 |
20 | var recLength = 0,
21 | recBuffersL = [],
22 | recBuffersR = [],
23 | sampleRate;
24 |
25 | this.onmessage = function(e){
26 | switch(e.data.command){
27 | case 'init':
28 | init(e.data.config);
29 | break;
30 | case 'record':
31 | record(e.data.buffer);
32 | break;
33 | case 'exportWAV':
34 | exportWAV(e.data.type);
35 | break;
36 | case 'exportMonoWAV':
37 | exportMonoWAV(e.data.type);
38 | break;
39 | case 'getBuffers':
40 | getBuffers();
41 | break;
42 | case 'clear':
43 | clear();
44 | break;
45 | }
46 | };
47 |
48 | function init(config){
49 | sampleRate = config.sampleRate;
50 | }
51 |
52 | function record(inputBuffer){
53 | recBuffersL.push(inputBuffer[0]);
54 | recBuffersR.push(inputBuffer[1]);
55 | recLength += inputBuffer[0].length;
56 | }
57 |
58 | function exportWAV(type){
59 | var bufferL = mergeBuffers(recBuffersL, recLength);
60 | var bufferR = mergeBuffers(recBuffersR, recLength);
61 | var interleaved = interleave(bufferL, bufferR);
62 | var dataview = encodeWAV(interleaved);
63 | var audioBlob = new Blob([dataview], { type: type });
64 |
65 | this.postMessage(audioBlob);
66 | }
67 |
68 | function exportMonoWAV(type){
69 | var bufferL = mergeBuffers(recBuffersL, recLength);
70 | var dataview = encodeWAV(bufferL, true);
71 | var audioBlob = new Blob([dataview], { type: type });
72 |
73 | this.postMessage(audioBlob);
74 | }
75 |
76 | function getBuffers() {
77 | var buffers = [];
78 | buffers.push( mergeBuffers(recBuffersL, recLength) );
79 | buffers.push( mergeBuffers(recBuffersR, recLength) );
80 | this.postMessage(buffers);
81 | }
82 |
83 | function clear(){
84 | recLength = 0;
85 | recBuffersL = [];
86 | recBuffersR = [];
87 | }
88 |
89 | function mergeBuffers(recBuffers, recLength){
90 | var result = new Float32Array(recLength);
91 | var offset = 0;
92 | for (var i = 0; i < recBuffers.length; i++){
93 | result.set(recBuffers[i], offset);
94 | offset += recBuffers[i].length;
95 | }
96 | return result;
97 | }
98 |
99 | function interleave(inputL, inputR){
100 | var length = inputL.length + inputR.length;
101 | var result = new Float32Array(length);
102 |
103 | var index = 0,
104 | inputIndex = 0;
105 |
106 | while (index < length){
107 | result[index++] = inputL[inputIndex];
108 | result[index++] = inputR[inputIndex];
109 | inputIndex++;
110 | }
111 | return result;
112 | }
113 |
114 | function floatTo16BitPCM(output, offset, input){
115 | for (var i = 0; i < input.length; i++, offset+=2){
116 | var s = Math.max(-1, Math.min(1, input[i]));
117 | output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
118 | }
119 | }
120 |
121 | function writeString(view, offset, string){
122 | for (var i = 0; i < string.length; i++){
123 | view.setUint8(offset + i, string.charCodeAt(i));
124 | }
125 | }
126 |
127 | function encodeWAV(samples, mono){
128 | var buffer = new ArrayBuffer(44 + samples.length * 2);
129 | var view = new DataView(buffer);
130 |
131 | /* RIFF identifier */
132 | writeString(view, 0, 'RIFF');
133 | /* file length */
134 | view.setUint32(4, 32 + samples.length * 2, true);
135 | /* RIFF type */
136 | writeString(view, 8, 'WAVE');
137 | /* format chunk identifier */
138 | writeString(view, 12, 'fmt ');
139 | /* format chunk length */
140 | view.setUint32(16, 16, true);
141 | /* sample format (raw) */
142 | view.setUint16(20, 1, true);
143 | /* channel count */
144 | view.setUint16(22, mono?1:2, true);
145 | /* sample rate */
146 | view.setUint32(24, sampleRate, true);
147 | /* byte rate (sample rate * block align) */
148 | view.setUint32(28, sampleRate * 4, true);
149 | /* block align (channel count * bytes per sample) */
150 | view.setUint16(32, 4, true);
151 | /* bits per sample */
152 | view.setUint16(34, 16, true);
153 | /* data chunk identifier */
154 | writeString(view, 36, 'data');
155 | /* data chunk length */
156 | view.setUint32(40, samples.length * 2, true);
157 |
158 | floatTo16BitPCM(view, 44, samples);
159 |
160 | return view;
161 | }
162 |
--------------------------------------------------------------------------------
/www/static/css/chat.css:
--------------------------------------------------------------------------------
1 | ::-webkit-scrollbar-track {
2 | background-color: transparent;
3 | }
4 |
5 | ::-webkit-scrollbar-thumb {
6 | border-radius: 3px;
7 | -moz-border-radius: 3px;
8 | -webkit-border-radius: 3px;
9 | background-color: #c3c3c3;
10 | }
11 |
12 | ::-webkit-scrollbar {
13 | width: 6px;
14 | height: 6px;
15 | }
16 |
17 | html, body {
18 | height: 100%;
19 | width: 100%;
20 | margin: 0;
21 | padding: 0;
22 | }
23 |
24 | body {
25 | background: url(/static/img/bg.jpg) no-repeat;
26 | background-size: cover;
27 | font-family: 'Microsoft Yahei', serif, monospace, sans-serif;
28 | }
29 |
30 | *{
31 | padding: 0;
32 | margin: 0;
33 | font-size: 16px;
34 | line-height: 20px;
35 | font-family: arial;
36 | }
37 | .clear {
38 | clear:both;
39 | }
40 | .content {
41 | position: absolute;
42 | top: 0;
43 | bottom: 0;
44 | left: 0;
45 | right: 0;
46 | margin: auto;
47 | height: 600px;
48 | width: 850px;
49 | }
50 |
51 | .user-list-wrap {
52 | float: left;
53 | height: 100%;
54 | color: #ccc;
55 | background-color: white;
56 | background-color: #2e3238;
57 | }
58 |
59 | .title {
60 | padding: 12px 18px 11px;
61 | border-bottom: 1px solid #292C33;
62 | }
63 |
64 | .title span {
65 | vertical-align: middle;
66 | }
67 |
68 | .dialog-logo {
69 | height: 20px;
70 | width: 20px;
71 | vertical-align: middle;
72 | }
73 |
74 | .user-list {
75 | position: relative;
76 | width: 250px;
77 | }
78 |
79 | .user {
80 | overflow: hidden;
81 | padding: 12px 18px 11px;
82 | cursor: pointer;
83 | position: relative;
84 | border-bottom: 1px solid #ccc;
85 | background-color: #2e3238;
86 | border-bottom: 1px solid #292C33;
87 | margin-left: 15px;
88 | }
89 | .user.circle {
90 | margin-left: 0px;
91 | }
92 | .user.circle:before {
93 | content: '';
94 | display: inline-block;
95 | margin-right: 5px;
96 | width: 10px;
97 | height: 10px;
98 | border-radius: 50%;
99 | background-color: #3cc51f;
100 | }
101 |
102 | .user > button {
103 | float: right;
104 | background: none;
105 | border: none;
106 | color: #AAA;
107 | font-size: 14px;
108 | }
109 |
110 | .chat-view {
111 | width: 600px;
112 | padding-left: 250px;
113 | height: 600px;
114 | background-color: #eee;
115 | }
116 |
117 | .chat-history {
118 | overflow-y: auto;
119 | height: 75%;
120 | }
121 |
122 | .msg-wrap, .msg-mine-wrap {
123 | margin: 10px;
124 | }
125 |
126 | .msg-mine-wrap {
127 | float: right;
128 | }
129 |
130 | .msg-mine-wrap:after {
131 | content: '';
132 | display: block;
133 | clear: both;
134 | }
135 |
136 | .msg-wrap-left {
137 | display: inline-block;
138 | }
139 |
140 | .msg, .msg-mine {
141 | position: relative;
142 | padding: 6px 13px;
143 | max-width: 280px;
144 | display: inline-block;
145 | color: #666;
146 | font-size: 14px;
147 | border-radius: 3px;
148 | word-wrap: break-word;
149 | word-break: break-all;
150 | }
151 |
152 | .msg {
153 | background-color: white;
154 | }
155 |
156 | .msg-mine {
157 | background-color: #B2E281;
158 | color: #000;
159 | }
160 |
161 | .msg-mine:after {
162 | position: absolute;
163 | content: " ";
164 | border: 6px solid transparent;
165 | border-left-color: #B2E281;
166 | border-left-width: 4px;
167 | top: 9px;
168 | right: -9px;
169 | }
170 |
171 | .msg-name {
172 | font-size: 12px;
173 | color: #4f4f4f;
174 | font-weight: normal;
175 | }
176 |
177 | .msg:before {
178 | position: absolute;
179 | content: " ";
180 | border: 6px solid transparent;
181 | border-right-color: #fff;
182 | border-right-width: 4px;
183 | top: 9px;
184 | left: -9px;
185 | }
186 | .msg-avatar {
187 | margin-top: 7px;
188 | margin-left: 10px;
189 | }
190 | .msg-wrap .msg-avatar {
191 | margin: 0 10px 0;
192 | position: relative;
193 | top: 11px;
194 | }
195 | .msg-wrap .msg-avatar.msg-avatar-voice {
196 | top: 0;
197 | }
198 | .msg-avatar:before {
199 | content: attr(data-avatar);
200 | width: 45px;
201 | height: 45px;
202 | display:table-cell;
203 | vertical-align: middle;
204 | text-align: center;
205 | font-size: 24px;
206 | color: #FFF;
207 | }
208 | .msg-wrap-right {
209 | float: right;
210 | }
211 |
212 | .tip-wrap {
213 | margin-top: 10px;
214 | text-align: center;
215 | }
216 |
217 | .tip {
218 | display: inline-block;
219 | background-color: #dcdcdc;
220 | font-size: 12px;
221 | padding: 1px 18px;
222 | color: #fff;
223 | border-radius: 2px;
224 | -moz-border-radius: 2px;
225 | -webkit-border-radius: 2px;
226 | }
227 |
228 | .type-area {
229 | border-top: 1px solid #ccc;
230 | position: relative;
231 | height: 25%;
232 | }
233 | .type-area > .toolbar {
234 | height: 30px;
235 | padding: 5px 17px;
236 | }
237 | .web-face {
238 | background: url(https://p2.ssl.qhimg.com/t0144ecd6235c655b76.png) 0 -805px;
239 | width: 30px;
240 | height: 30px;
241 | vertical-align: middle;
242 | display: inline-block;
243 | background-size: 150px 2489px;
244 | }
245 | .web-speech {
246 | width: 50px;
247 | height: 20px;
248 | float: right;
249 | border-radius: 20px;
250 | margin-top: 4px;
251 | background: #C3C3C3;
252 | }
253 | .web-speech::after {
254 | content: '';
255 | width: 18px;
256 | height: 18px;
257 | border-radius: 18px;
258 | background: #FFF;
259 | display: block;
260 | margin: 1px;
261 | transition: all .5s;
262 | }
263 | .web-speech.on {
264 | background: #3caf36;
265 | }
266 | .web-speech.on::after {
267 | margin-left: 31px;
268 | }
269 | .web-voice-gray {
270 | float: left;
271 | background: url(https://p2.ssl.qhimg.com/t0144ecd6235c655b76.png) 0 -2427px;
272 | width: 23px;
273 | height: 23px;
274 | vertical-align: middle;
275 | display: inline-block;;
276 | background-size: 150px 2489px;
277 | }
278 | .web-voice-gray-playing {
279 | float:left;
280 | background: url(https://p4.ssl.qhimg.com/t0158d301fe3bb20afc.gif);
281 | width: 23px;
282 | height: 23px;
283 | vertical-align: middle;
284 | display: inline-block;
285 | background-size: 23px 23px
286 | }
287 | .web-voice-green {
288 | float:right;
289 | background: url(https://p2.ssl.qhimg.com/t0144ecd6235c655b76.png) 0 -2450px;
290 | width: 23px;
291 | height: 23px;
292 | vertical-align: middle;
293 | display: inline-block;
294 | background-size: 150px 2489px;
295 | }
296 | .web-voice-playing {
297 | float:right;
298 | background: url(https://p3.ssl.qhimg.com/t01d46cac05690404bc.gif);
299 | width: 23px;
300 | height: 23px;
301 | vertical-align: middle;
302 | display: inline-block;
303 | background-size: 23px 23px;
304 | }
305 | .input-box {
306 | height: 5em;
307 | overflow-y: auto;
308 | overflow-x: hidden;
309 | outline: 0;
310 | border: 0;
311 | font-size: 14px;
312 | background-color: #eee;
313 | padding-left: 15px;
314 | margin-right: 10px;
315 | margin-top: 10px;
316 | }
317 | .voice-tip {
318 | display: none;
319 | line-height: 5em;
320 | text-align: center;
321 | color: #a3a3a3;
322 | }
323 |
324 | .btn-record {
325 | position: absolute;
326 | right: 90px;
327 | bottom: 15px;
328 | padding: 3px 20px;
329 | font-size: 14px;
330 | background: #FFF;
331 | border: 1px solid #C1c1c1;
332 | border-radius: 4px;
333 | color: #222;
334 | }
335 | .btn-send {
336 | position: absolute;
337 | right: 10px;
338 | bottom: 15px;
339 | background-color: #fff;
340 | color: #222;
341 | border: 1px solid #666;
342 | display: inline-block;
343 | border: 1px solid #c1c1c1;
344 | border-radius: 4px;
345 | -moz-border-radius: 4px;
346 | -webkit-border-radius: 4px;
347 | padding: 3px 20px;
348 | font-size: 14px;
349 | cursor: pointer;
350 | }
351 |
352 | #qrcode {
353 | position: absolute;
354 | width: 400px;
355 | height: 358px;
356 | top: 30px;
357 | left: 50px;
358 | background: white;
359 | text-align: center;
360 | padding: 10px 20px;
361 | }
362 |
363 | img.emoji {
364 | width: 20px;
365 | height: 20px;
366 | }
367 | .qr-content {
368 | margin: 25px 0;
369 | }
370 |
371 | .qr-share {
372 | position: relative;
373 | width: 60px;
374 | left: 85px;
375 | background-color: #fff;
376 | color: #222;
377 | border-radius: 3px;
378 | font-size: 14px
379 | }
380 |
381 |
382 | @-webkit-keyframes twinkling{ /*透明度由0到1*/
383 | 0%{
384 | opacity:0; /*透明度为0*/
385 | }
386 | 100%{
387 | opacity:1; /*透明度为1*/
388 |
389 | }
390 | }
391 |
392 | .atwho-view{position:absolute;top:0;left:0;display:none;margin-top:18px;background:#fff;border:1px solid #DDD;border-radius:3px;box-shadow:0 0 5px rgba(0,0,0,.1);min-width:120px;z-index:10}.atwho-view .cur{background:#36F;color:#fff}.atwho-view .cur small{color:#fff}.atwho-view strong{color:#36F}.atwho-view .cur strong{color:#fff;font:bold}.atwho-view ul{list-style:none;padding:0;margin:auto}.atwho-view ul li{display:block;padding:5px 10px;border-bottom:1px solid #DDD;cursor:pointer}.atwho-view small{font-size:smaller;color:#777;font-weight:400}
393 |
--------------------------------------------------------------------------------
/www/static/libs/custombox/legacy.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * custombox v3.0.2 - 2015-12-05
3 | * Modal Window Effects with transitions CSS3.
4 | * http://dixso.github.io/custombox/
5 | * (c) 2015 Julio de la Calle - @dixso9
6 | *
7 | * dataset - https://gist.github.com/brettz9/4093766
8 | * classList - http://purl.eligrey.com/github/classList.js/blob/master/classList.js
9 | * addEventListener - https://gist.github.com/2864711/946225eb3822c203e8d6218095d888aac5e1748e
10 | * :scope polyfill - http://stackoverflow.com/questions/6481612/queryselector-search-immediate-children
11 | * forEach - http://es5.github.com/#x15.4.4.18
12 | * Object.assign() - https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/assign
13 | * Array.isArray() - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
14 | *
15 | * Under MIT License - http://opensource.org/licenses/MIT
16 | */
17 |
18 | function cbExtendObjects(){for(var a=1,b=arguments.length;b>a;a++)for(var c in arguments[a])arguments[a].hasOwnProperty(c)&&(arguments[0][c]=arguments[a][c]);return arguments[0]}if(function(a){a.getComputedStyle||(a.getComputedStyle=function(a){return this.el=a,this.getPropertyValue=function(b){var c=/(\-([a-z]){1})/g;return"float"==b&&(b="styleFloat"),c.test(b)&&(b=b.replace(c,function(){return arguments[2].toUpperCase()})),a.currentStyle[b]?a.currentStyle[b]:null},this})}(window),Function.prototype.bind||(Function.prototype.bind=function(a){"use strict";if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b=Array.prototype.slice.call(arguments,1),c=this,d=function(){},e=function(){return c.apply(this instanceof d&&a?this:a,b.concat(Array.prototype.slice.call(arguments)))};return d.prototype=this.prototype,e.prototype=new d,e}),function(){"use strict";var a=Object.prototype,b=a.__defineGetter__,c=a.__defineSetter__,d=a.__lookupGetter__,e=a.__lookupSetter__,f=a.hasOwnProperty;b&&c&&d&&e&&(Object.defineProperty||(Object.defineProperty=function(a,g,h){if(arguments.length<3)throw new TypeError("Arguments not optional");if(g+="",f.call(h,"value")&&(d.call(a,g)||e.call(a,g)||(a[g]=h.value),f.call(h,"get")||f.call(h,"set")))throw new TypeError("Cannot specify an accessor and a value");if(!(h.writable&&h.enumerable&&h.configurable))throw new TypeError("This implementation of Object.defineProperty does not support false for configurable, enumerable, or writable.");return h.get&&b.call(a,g,h.get),h.set&&c.call(a,g,h.set),a}),Object.getOwnPropertyDescriptor||(Object.getOwnPropertyDescriptor=function(a,b){if(arguments.length<2)throw new TypeError("Arguments not optional.");b+="";var c={configurable:!0,enumerable:!0,writable:!0},g=d.call(a,b),h=e.call(a,b);return f.call(a,b)?g||h?(delete c.writable,c.get=c.set=void 0,g&&(c.get=g),h&&(c.set=h),c):(c.value=a[b],c):c}),Object.defineProperties||(Object.defineProperties=function(a,b){var c;for(c in b)f.call(b,c)&&Object.defineProperty(a,c,b[c])}))}(),!(document.documentElement.dataset||Object.getOwnPropertyDescriptor(Element.prototype,"dataset")&&Object.getOwnPropertyDescriptor(Element.prototype,"dataset").get)){var propDescriptor={enumerable:!0,get:function(){"use strict";var a,b,c,d,e,f,g=this,h=this.attributes,i=h.length,j=function(a){return a.charAt(1).toUpperCase()},k=function(){return this},l=function(a,b){return"undefined"!=typeof b?this.setAttribute(a,b):this.removeAttribute(a)};try{({}).__defineGetter__("test",function(){}),b={}}catch(m){b=document.createElement("div")}for(a=0;i>a;a++)if(f=h[a],f&&f.name&&/^data-\w[\w\-]*$/.test(f.name)){c=f.value,d=f.name,e=d.substr(5).replace(/-./g,j);try{Object.defineProperty(b,e,{enumerable:this.enumerable,get:k.bind(c||""),set:l.bind(g,d)})}catch(n){b[e]=c}}return b}};try{Object.defineProperty(Element.prototype,"dataset",propDescriptor)}catch(e){propDescriptor.enumerable=!1,Object.defineProperty(Element.prototype,"dataset",propDescriptor)}}"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var a=document.createElement("_");if(a.classList.add("c1","c2"),!a.classList.contains("c2")){var b=function(a){var b=DOMTokenList.prototype[a];DOMTokenList.prototype[a]=function(a){var c,d=arguments.length;for(c=0;d>c;c++)a=arguments[c],b.call(this,a)}};b("add"),b("remove")}if(a.classList.toggle("c3",!1),a.classList.contains("c3")){var c=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(a,b){return 1 in arguments&&!this.contains(a)==!b?b:c.call(this,a)}}a=null}():!function(a){"use strict";if("Element"in a){var b="classList",c="prototype",d=a.Element[c],e=Object,f=String[c].trim||function(){return this.replace(/^\s+|\s+$/g,"")},g=Array[c].indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(b in this&&this[b]===a)return b;return-1},h=function(a,b){this.name=a,this.code=DOMException[a],this.message=b},i=function(a,b){if(""===b)throw new h("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(b))throw new h("INVALID_CHARACTER_ERR","String contains an invalid character");return g.call(a,b)},j=function(a){for(var b=f.call(a.getAttribute("class")||""),c=b?b.split(/\s+/):[],d=0,e=c.length;e>d;d++)this.push(c[d]);this._updateClassName=function(){a.setAttribute("class",this.toString())}},k=j[c]=[],l=function(){return new j(this)};if(h[c]=Error[c],k.item=function(a){return this[a]||null},k.contains=function(a){return a+="",-1!==i(this,a)},k.add=function(){var a,b=arguments,c=0,d=b.length,e=!1;do a=b[c]+"",-1===i(this,a)&&(this.push(a),e=!0);while(++c>>0;if(0===e)return-1;var f=+b||0;if(Math.abs(f)===1/0&&(f=0),f>=e)return-1;for(c=Math.max(f>=0?f:e-Math.abs(f),0);e>c;){if(c in d&&d[c]===a)return c;c++}return-1}),this.Element&&Element.prototype.attachEvent&&!Element.prototype.addEventListener&&function(){function a(a,b){Window.prototype[a]=HTMLDocument.prototype[a]=Element.prototype[a]=b}function b(a){b.interval&&document.body&&(b.interval=clearInterval(b.interval),document.dispatchEvent(new CustomEvent("DOMContentLoaded")))}a("addEventListener",function(a,b){var c=this,d=c.addEventListener.listeners=c.addEventListener.listeners||{},e=d[a]=d[a]||[];e.length||c.attachEvent("on"+a,e.event=function(a){var b=c.document&&c.document.documentElement||c.documentElement||{scrollLeft:0,scrollTop:0};a.currentTarget=c,a.pageX=a.clientX+b.scrollLeft,a.pageY=a.clientY+b.scrollTop,a.preventDefault=function(){a.returnValue=!1},a.relatedTarget=a.fromElement||null,a.stopImmediatePropagation=function(){h=!1,a.cancelBubble=!0},a.stopPropagation=function(){a.cancelBubble=!0},a.target=a.srcElement||c,a.timeStamp=+new Date;for(var d,f=0,g=[].concat(e),h=!0;h&&(d=g[f]);++f)for(var i,j=0;i=e[j];++j)if(i==d){i.call(c,a);break}}),e.push(b)}),a("removeEventListener",function(a,b){for(var c,d=this,e=d.addEventListener.listeners=d.addEventListener.listeners||{},f=e[a]=e[a]||[],g=f.length-1;c=f[g];--g)if(c==b){f.splice(g,1);break}!f.length&&f.event&&d.detachEvent("on"+a,f.event)}),a("dispatchEvent",function(a){var b=this,c=a.type,d=b.addEventListener.listeners=b.addEventListener.listeners||{},e=d[c]=d[c]||[];try{return b.fireEvent("on"+c,a)}catch(f){return void(e.event&&e.event(a))}}),Object.defineProperty(Window.prototype,"CustomEvent",{get:function(){var a=this;return function(b,c){var d,e=a.document.createEventObject();e.type=b;for(d in c)"cancelable"==d?e.returnValue=!c.cancelable:"bubbles"==d?e.cancelBubble=!c.bubbles:"detail"==d&&(e.detail=c.detail);return e}}}),b.interval=setInterval(b,1),window.addEventListener("load",b)}(),(!this.CustomEvent||"object"==typeof this.CustomEvent)&&function(){this.CustomEvent=function(a,b){var c;b=b||{bubbles:!1,cancelable:!1,detail:void 0};try{c=document.createEvent("CustomEvent"),c.initCustomEvent(a,b.bubbles,b.cancelable,b.detail)}catch(d){c=document.createEvent("Event"),c.initEvent(a,b.bubbles,b.cancelable),c.detail=b.detail}return c}}(),Array.prototype.forEach||(Array.prototype.forEach=function(a,b){"use strict";var c,d;if(null==this)throw new TypeError("this is null or not defined");var e,f=Object(this),g=f.length>>>0;if("[object Function]"!=={}.toString.call(a))throw new TypeError(a+" is not a function");for(arguments.length>=2&&(c=b),d=0;g>d;)d in f&&(e=f[d],a.call(c,e,d,f)),d++}),function(a,b){try{a.querySelector(":scope body")}catch(c){["querySelector","querySelectorAll"].forEach(function(c){var d=b[c];b[c]=function(b){if(/(^|,)\s*:scope/.test(b)){var e=this.id;this.id="ID_"+Date.now(),b=b.replace(/((^|,)\s*):scope/g,"$1#"+this.id);var f=a[c](b);return this.id=e,f}return d.call(this,b)}})}}(window.document,Element.prototype),-1===navigator.appVersion.indexOf("MSIE 8.")&&-1===navigator.appVersion.indexOf("MSIE 9.")&&(Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(a,b){"use strict";if(void 0===a||null===a)throw new TypeError("Cannot convert first argument to object");for(var c=Object(a),d=1;dg;g++){var i=f[g],j=Object.getOwnPropertyDescriptor(e,i);void 0!==j&&j.enumerable&&(c[i]=e[i])}}return c}})),Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)});
--------------------------------------------------------------------------------
/www/static/js/chat.js:
--------------------------------------------------------------------------------
1 | function playVoice(ele, normal, playing) {
2 | var audio = ele.querySelector('audio'), i = ele.querySelector('i');
3 | if( i.className === playing ) {
4 | audio.pause();
5 | i.className = normal;
6 | } else {
7 | i.className = playing;
8 | audio.play();
9 | audio.onended = function() {
10 | i.className = normal;
11 | }
12 | }
13 | }
14 |
15 | ! function() {
16 | // 工具类
17 | function query(selector) {
18 | return document.querySelector(selector);
19 | }
20 |
21 | // 模版
22 | function generateHTML(el, data) {
23 | var msgHTML = query(el).innerHTML;
24 |
25 | function generate(data) {
26 | if (typeof(data) === 'string') {
27 | return msgHTML.replace(/\{(\w+)\}/g, function($0, $1) {
28 | return data;
29 | });
30 |
31 | } else {
32 | return msgHTML.replace(/\{(\w+)\}/g, function($0, $1) {
33 | return data[$1];
34 | });
35 | }
36 | }
37 | return Array.isArray(data) ? data.map(generate).join('') : generate(data);
38 | }
39 |
40 | function getRoomByUrl() {
41 | return location.search.match(/room=(\w+)?($|&)/)[1];
42 | }
43 |
44 | function renderTip(tip) {
45 | chatHistory.innerHTML += generateHTML('#tip-tpl', tip);
46 | }
47 |
48 | function twinklingUser(msgUser, second) {
49 | $(".user-list").children("li").each(function(i, item) {
50 | if($(item).text() === msgUser) {
51 | $(item).css({"-webkit-animation":"twinkling 1s infinite ease-in-out"});
52 | setTimeout(function(){
53 | $(item).css({"-webkit-animation": ""});
54 | }, second||5000);
55 | }
56 | })
57 | }
58 |
59 | function renderUsrList(users) {
60 | var usrList = query('.user-list');
61 | usrList.innerHTML = generateHTML('#usr-tpl', users);
62 | atwho(users);
63 |
64 | var mine = query('.user-list li[data-id="'+localStorage.id+'"]');
65 | if( !mine ) {
66 | return false;
67 | }
68 |
69 | var btn = document.createElement('button');
70 | btn.innerHTML = '修改';
71 | btn.onclick = function() {
72 | location.href = '/index/login'+location.search;
73 | }
74 | mine.appendChild( btn );
75 | mine.classList.add('circle');
76 | }
77 |
78 | function scrollHistoryBottom() {
79 | chatHistory.scrollTop = chatHistory.scrollHeight;
80 | }
81 |
82 | function notification(name,text) {
83 | /** 标题状态改变 **/
84 | var o = document.title;
85 | document.title = '';
86 | var note = setInterval(function() {
87 | document.title = document.title.length > 1 ? document.title.substr(1) : name + ' 说...';
88 | }, 500);
89 | setTimeout(function() {
90 | clearInterval(note);
91 | document.title = o;
92 | }, 10000);
93 | /** 语音提示 **/
94 | document.getElementById('notification').play();
95 |
96 | /** 消息通知 **/
97 | if(!Notification) return false;
98 | if(Notification.permission != 'granted')
99 | Notification.requestPermission(notification);
100 | var notification = new Notification(name+' 说:', {
101 | dir: 'ltr',
102 | lang: 'zh-CN',
103 | body: text,
104 | tag: 'anychat',
105 | icon: null
106 | });
107 | notification.onclose = function() {
108 | clearInterval(note);
109 | document.title = o;
110 | }
111 | /** 点击后想增加一个跳转到该页面的代码 **/
112 | notification.onclick = function() {
113 | this.close();
114 | }
115 | notification.onshow = function() {
116 | setTimeout(notification.close, 10000);
117 | }
118 | }
119 |
120 | function atwho(users) {
121 | $('.input-box').atwho({
122 | at: "@",
123 | data: users,
124 | max_len: 8,
125 | search_key: 'text',
126 | tpl: '${name}'
127 | });
128 | }
129 |
130 | var audioRecorder, recording;
131 | function gotBuffers() {
132 | audioRecorder.exportWAV(function(blob) {
133 | var reader = new window.FileReader();
134 | reader.readAsDataURL(blob);
135 | reader.onloadend = function() {
136 | var base64data = reader.result;
137 | addVoiceMsg(base64data);
138 | }
139 | }, 'audio/mp3');
140 | }
141 |
142 | function gotStream(stream) {
143 | window.AudioContext = window.AudioContext || window.webkitAudioContext;
144 |
145 | var audioContext = new AudioContext();
146 | var audioInput = null,
147 | realAudioInput = null,
148 | inputPoint = null;
149 |
150 | inputPoint = audioContext.createGain();
151 |
152 | // Create an AudioNode from the stream.
153 | realAudioInput = audioContext.createMediaStreamSource(stream);
154 | audioInput = realAudioInput;
155 | audioInput.connect(inputPoint);
156 |
157 | analyserNode = audioContext.createAnalyser();
158 | analyserNode.fftSize = 2048;
159 | inputPoint.connect( analyserNode );
160 |
161 | audioRecorder = new Recorder( inputPoint );
162 |
163 | zeroGain = audioContext.createGain();
164 | zeroGain.gain.value = 0.0;
165 | inputPoint.connect( zeroGain );
166 | zeroGain.connect( audioContext.destination );
167 | }
168 |
169 | function recordStart(e) {
170 | if(e.keyCode !== 32 || !audioRecorder || recording) { return; }
171 | audioRecorder.clear();
172 | audioRecorder.record();
173 | recording = true;
174 | }
175 | function recordStop(e) {
176 | if(e.keyCode !== 32) { return; }
177 | audioRecorder.stop();
178 | recording = false;
179 | audioRecorder.getBuffers( gotBuffers );
180 | }
181 |
182 | if (!navigator.getUserMedia)
183 | navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
184 |
185 | navigator.getUserMedia({audio: true}, gotStream, function(e) { alert('Error getting audio'); console.log(e);});
186 |
187 | $('.web-speech').click(function() {
188 | var listenHandler = $(this).hasClass('on') ? 'off' : 'on';
189 | $(document)[listenHandler]('keydown', recordStart);
190 | $(document)[listenHandler]('keyup', recordStop);
191 | })
192 |
193 | var COLORS = [
194 | '#e21400', '#91580f', '#f8a700', '#f78b00',
195 | '#58dc00', '#287b00', '#a8f07a', '#4ae8c4',
196 | '#3b88eb', '#3824aa', '#a700ff', '#d300e7'
197 | ];
198 |
199 | var name = localStorage.getItem('name');
200 | var id = localStorage.getItem('id');
201 |
202 | var sendBtn = query('.btn-send');
203 | var chatHistory = query('.chat-history');
204 | var inputBox = query('.input-box');
205 | function addVoiceMsg(data) {
206 | chatHistory.innerHTML += generateHTML('#voice-mine-tpl', {
207 | displayName: name,
208 | message: data,
209 | avatar: name.charAt(0).toUpperCase(),
210 | background: COLORS[ name.charCodeAt(0)%COLORS.length ],
211 | width: Math.min(40 + data.length / 50000 * 7, 200)
212 | });
213 |
214 | socket.emit('voice', {
215 | room: getRoomByUrl(),
216 | userId: id,
217 | message: data
218 | });
219 |
220 | scrollHistoryBottom();
221 | }
222 |
223 | var addMsg = function() {
224 | var msg = inputBox.innerText;
225 | inputBox.innerText = '';
226 | if(msg === '') {
227 | return alert('发送消息不能为空');
228 | }
229 |
230 | var data = {
231 | displayName: name,
232 | message: twemoji.parse(msg),
233 | avatar: name.charAt(0).toUpperCase(),
234 | background: COLORS[ name.charCodeAt(0)%COLORS.length ]
235 | };
236 | chatHistory.innerHTML += generateHTML('#msg-mine-tpl', data);
237 |
238 | var adminName = '系统消息';
239 | switch(msg) {
240 | case '/help':
241 | chatHistory.innerHTML += generateHTML('#msg-tpl', {
242 | displayName: adminName,
243 | message: '/help - 列出所有命令
/clear - 清屏
',
244 | avatar: adminName.charAt(0),
245 | background: COLORS[ adminName.charCodeAt(0)%COLORS.length ]
246 | });
247 | break;
248 | case '/clear':
249 | chatHistory.innerHTML = '';
250 | break;
251 | default:
252 | socket.emit('chat', {
253 | room: getRoomByUrl(),
254 | userId: id,
255 | message: msg
256 | })
257 | break;
258 | }
259 | scrollHistoryBottom();
260 | };
261 |
262 | // 如果用户没登录就跳转给用户去登录
263 | if (!name || !id) {
264 | window.location.href = '/index/login' + location.search;
265 | }
266 |
267 | var socket = io(socketUrl);
268 | socket.emit('adduser', {
269 | room: getRoomByUrl(),
270 | userId: id,
271 | displayName: name
272 | });
273 |
274 | socket.on('user:login', function(data) {
275 | var usrList = query('.user-list');
276 | localStorage.setItem('id', data.userId);
277 | renderUsrList(data.users);
278 | });
279 |
280 | socket.on('user:join', function(data) {
281 | renderUsrList(data.users);
282 | renderTip(data.join + '已进入');
283 | scrollHistoryBottom();
284 | });
285 |
286 | socket.on('user:exit', function(data) {
287 | renderUsrList(data.users);
288 | renderTip(data.exit + '已退出');
289 | scrollHistoryBottom();
290 | });
291 |
292 | socket.on('chat', function(data) {
293 | chatHistory.innerHTML += generateHTML('#msg-tpl', {
294 | displayName: data.displayName,
295 | message: twemoji.parse(data.message),
296 | avatar: data.displayName.charAt(0).toUpperCase(),
297 | background: COLORS[ data.displayName.charCodeAt(0)%COLORS.length ]
298 | });
299 | if(document.hidden) {
300 | notification(data.displayName, data.message);
301 | }
302 | twinklingUser(data.displayName, 3000);
303 | scrollHistoryBottom();
304 | });
305 |
306 | socket.on('chat:voice', function(data) {
307 | chatHistory.innerHTML += generateHTML('#voice-tpl', {
308 | displayName: data.displayName,
309 | message: data.message,
310 | avatar: data.displayName.charAt(0).toUpperCase(),
311 | background: COLORS[ data.displayName.charCodeAt(0)%COLORS.length ],
312 | width: Math.min(40 + data.message.length / 50000 * 7, 200)
313 | });
314 | if(document.hidden) {
315 | notification(data.displayName, '[语音消息]');
316 | }
317 | twinklingUser(data.displayName, 3000);
318 | scrollHistoryBottom();
319 | });
320 |
321 | sendBtn.addEventListener('click', addMsg);
322 | inputBox.addEventListener('keydown', function(e) {
323 | if (e.keyCode == 13) {
324 | e.preventDefault();
325 | return addMsg();
326 | }
327 | });
328 | // 二维码分享a
329 | $('#qrcode').children(".qr-content").qrcode({
330 | width: 256,
331 | height: 256,
332 | text: location.href
333 | })
334 | .end().children(".qr-des").text(location.href)
335 | $(".qr-share").on("click", function(e) {
336 | Custombox.open({
337 | target: "#qrcode",
338 | effect: "fadein"
339 | });
340 | e.preventDefault();
341 | });
342 |
343 | $('.web-speech').click(function() {
344 | $(this).toggleClass('on');
345 | $('.input-box').toggle();
346 | $('.voice-tip').toggle();
347 | });
348 | $('.btn-record').click(function() {
349 | var $btn = $(this);
350 | function onSuccess(stream) {
351 | //创建一个音频环境对像
352 | var audioContext = window.AudioContext || window.webkitAudioContext;
353 | var context = new audioContext();
354 |
355 | //将声音输入这个对像
356 | audioInput = context.createMediaStreamSources(stream);
357 |
358 | //设置音量节点
359 | volume = context.createGain();
360 | audioInput.connect(volume);
361 |
362 | //创建缓存,用来缓存声音
363 | var bufferSize = 2048;
364 |
365 | // 创建声音的缓存节点,createJavaScriptNode方法的
366 | // 第二个和第三个参数指的是输入和输出都是双声道。
367 | recorder = context.createJavaScriptNode(bufferSize, 2, 2);
368 |
369 | // 录音过程的回调函数,基本上是将左右两声道的声音
370 | // 分别放入缓存。
371 | recorder.onaudioprocess = function(e){
372 | console.log('recording');
373 | var left = e.inputBuffer.getChannelData(0);
374 | var right = e.inputBuffer.getChannelData(1);
375 | // we clone the samples
376 | leftchannel.push(new Float32Array(left));
377 | rightchannel.push(new Float32Array(right));
378 | recordingLength += bufferSize;
379 | }
380 |
381 | // 将音量节点连上缓存节点,换言之,音量节点是输入
382 | // 和输出的中间环节。
383 | volume.connect(recorder);
384 |
385 | // 将缓存节点连上输出的目的地,可以是扩音器,也可以
386 | // 是音频文件。
387 | recorder.connect(context.destination);
388 |
389 | }
390 | })
391 | }()
392 |
--------------------------------------------------------------------------------
/www/static/libs/caret.js:
--------------------------------------------------------------------------------
1 | (function (root, factory) {
2 | if (typeof define === 'function' && define.amd) {
3 | // AMD. Register as an anonymous module.
4 | define(["jquery"], function ($) {
5 | return (root.returnExportsGlobal = factory($));
6 | });
7 | } else if (typeof exports === 'object') {
8 | // Node. Does not work with strict CommonJS, but
9 | // only CommonJS-like enviroments that support module.exports,
10 | // like Node.
11 | module.exports = factory(require("jquery"));
12 | } else {
13 | factory(jQuery);
14 | }
15 | }(this, function ($) {
16 |
17 | //@ sourceMappingURL=jquery.caret.map
18 | /*
19 | Implement Github like autocomplete mentions
20 | http://ichord.github.com/At.js
21 |
22 | Copyright (c) 2013 chord.luo@gmail.com
23 | Licensed under the MIT license.
24 | */
25 |
26 | /*
27 | 本插件操作 textarea 或者 input 内的插入符
28 | 只实现了获得插入符在文本框中的位置,我设置
29 | 插入符的位置.
30 | */
31 |
32 | "use strict";
33 | var EditableCaret, InputCaret, Mirror, Utils, discoveryIframeOf, methods, oDocument, oFrame, oWindow, pluginName, setContextBy;
34 |
35 | pluginName = 'caret';
36 |
37 | EditableCaret = (function() {
38 | function EditableCaret($inputor) {
39 | this.$inputor = $inputor;
40 | this.domInputor = this.$inputor[0];
41 | }
42 |
43 | EditableCaret.prototype.setPos = function(pos) {
44 | return this.domInputor;
45 | };
46 |
47 | EditableCaret.prototype.getIEPosition = function() {
48 | return this.getPosition();
49 | };
50 |
51 | EditableCaret.prototype.getPosition = function() {
52 | var inputor_offset, offset;
53 | offset = this.getOffset();
54 | inputor_offset = this.$inputor.offset();
55 | offset.left -= inputor_offset.left;
56 | offset.top -= inputor_offset.top;
57 | return offset;
58 | };
59 |
60 | EditableCaret.prototype.getOldIEPos = function() {
61 | var preCaretTextRange, textRange;
62 | textRange = oDocument.selection.createRange();
63 | preCaretTextRange = oDocument.body.createTextRange();
64 | preCaretTextRange.moveToElementText(this.domInputor);
65 | preCaretTextRange.setEndPoint("EndToEnd", textRange);
66 | return preCaretTextRange.text.length;
67 | };
68 |
69 | EditableCaret.prototype.getPos = function() {
70 | var clonedRange, pos, range;
71 | if (range = this.range()) {
72 | clonedRange = range.cloneRange();
73 | clonedRange.selectNodeContents(this.domInputor);
74 | clonedRange.setEnd(range.endContainer, range.endOffset);
75 | pos = clonedRange.toString().length;
76 | clonedRange.detach();
77 | return pos;
78 | } else if (oDocument.selection) {
79 | return this.getOldIEPos();
80 | }
81 | };
82 |
83 | EditableCaret.prototype.getOldIEOffset = function() {
84 | var range, rect;
85 | range = oDocument.selection.createRange().duplicate();
86 | range.moveStart("character", -1);
87 | rect = range.getBoundingClientRect();
88 | return {
89 | height: rect.bottom - rect.top,
90 | left: rect.left,
91 | top: rect.top
92 | };
93 | };
94 |
95 | EditableCaret.prototype.getOffset = function(pos) {
96 | var clonedRange, offset, range, rect, shadowCaret;
97 | if (oWindow.getSelection && (range = this.range())) {
98 | if (range.endOffset - 1 > 0 && range.endContainer === !this.domInputor) {
99 | clonedRange = range.cloneRange();
100 | clonedRange.setStart(range.endContainer, range.endOffset - 1);
101 | clonedRange.setEnd(range.endContainer, range.endOffset);
102 | rect = clonedRange.getBoundingClientRect();
103 | offset = {
104 | height: rect.height,
105 | left: rect.left + rect.width,
106 | top: rect.top
107 | };
108 | clonedRange.detach();
109 | }
110 | if (!offset || (offset != null ? offset.height : void 0) === 0) {
111 | clonedRange = range.cloneRange();
112 | shadowCaret = $(oDocument.createTextNode("|"));
113 | clonedRange.insertNode(shadowCaret[0]);
114 | clonedRange.selectNode(shadowCaret[0]);
115 | rect = clonedRange.getBoundingClientRect();
116 | offset = {
117 | height: rect.height,
118 | left: rect.left,
119 | top: rect.top
120 | };
121 | shadowCaret.remove();
122 | clonedRange.detach();
123 | }
124 | } else if (oDocument.selection) {
125 | offset = this.getOldIEOffset();
126 | }
127 | if (offset) {
128 | offset.top += $(oWindow).scrollTop();
129 | offset.left += $(oWindow).scrollLeft();
130 | }
131 | return offset;
132 | };
133 |
134 | EditableCaret.prototype.range = function() {
135 | var sel;
136 | if (!oWindow.getSelection) {
137 | return;
138 | }
139 | sel = oWindow.getSelection();
140 | if (sel.rangeCount > 0) {
141 | return sel.getRangeAt(0);
142 | } else {
143 | return null;
144 | }
145 | };
146 |
147 | return EditableCaret;
148 |
149 | })();
150 |
151 | InputCaret = (function() {
152 | function InputCaret($inputor) {
153 | this.$inputor = $inputor;
154 | this.domInputor = this.$inputor[0];
155 | }
156 |
157 | InputCaret.prototype.getIEPos = function() {
158 | var endRange, inputor, len, normalizedValue, pos, range, textInputRange;
159 | inputor = this.domInputor;
160 | range = oDocument.selection.createRange();
161 | pos = 0;
162 | if (range && range.parentElement() === inputor) {
163 | normalizedValue = inputor.value.replace(/\r\n/g, "\n");
164 | len = normalizedValue.length;
165 | textInputRange = inputor.createTextRange();
166 | textInputRange.moveToBookmark(range.getBookmark());
167 | endRange = inputor.createTextRange();
168 | endRange.collapse(false);
169 | if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
170 | pos = len;
171 | } else {
172 | pos = -textInputRange.moveStart("character", -len);
173 | }
174 | }
175 | return pos;
176 | };
177 |
178 | InputCaret.prototype.getPos = function() {
179 | if (oDocument.selection) {
180 | return this.getIEPos();
181 | } else {
182 | return this.domInputor.selectionStart;
183 | }
184 | };
185 |
186 | InputCaret.prototype.setPos = function(pos) {
187 | var inputor, range;
188 | inputor = this.domInputor;
189 | if (oDocument.selection) {
190 | range = inputor.createTextRange();
191 | range.move("character", pos);
192 | range.select();
193 | } else if (inputor.setSelectionRange) {
194 | inputor.setSelectionRange(pos, pos);
195 | }
196 | return inputor;
197 | };
198 |
199 | InputCaret.prototype.getIEOffset = function(pos) {
200 | var h, textRange, x, y;
201 | textRange = this.domInputor.createTextRange();
202 | pos || (pos = this.getPos());
203 | textRange.move('character', pos);
204 | x = textRange.boundingLeft;
205 | y = textRange.boundingTop;
206 | h = textRange.boundingHeight;
207 | return {
208 | left: x,
209 | top: y,
210 | height: h
211 | };
212 | };
213 |
214 | InputCaret.prototype.getOffset = function(pos) {
215 | var $inputor, offset, position;
216 | $inputor = this.$inputor;
217 | if (oDocument.selection) {
218 | offset = this.getIEOffset(pos);
219 | offset.top += $(oWindow).scrollTop() + $inputor.scrollTop();
220 | offset.left += $(oWindow).scrollLeft() + $inputor.scrollLeft();
221 | return offset;
222 | } else {
223 | offset = $inputor.offset();
224 | position = this.getPosition(pos);
225 | return offset = {
226 | left: offset.left + position.left - $inputor.scrollLeft(),
227 | top: offset.top + position.top - $inputor.scrollTop(),
228 | height: position.height
229 | };
230 | }
231 | };
232 |
233 | InputCaret.prototype.getPosition = function(pos) {
234 | var $inputor, at_rect, end_range, format, html, mirror, start_range;
235 | $inputor = this.$inputor;
236 | format = function(value) {
237 | value = value.replace(/<|>|`|"|&/g, '?').replace(/\r\n|\r|\n/g, "
");
238 | if (/firefox/i.test(navigator.userAgent)) {
239 | value = value.replace(/\s/g, ' ');
240 | }
241 | return value;
242 | };
243 | if (pos === void 0) {
244 | pos = this.getPos();
245 | }
246 | start_range = $inputor.val().slice(0, pos);
247 | end_range = $inputor.val().slice(pos);
248 | html = "" + format(start_range) + "";
249 | html += "|";
250 | html += "" + format(end_range) + "";
251 | mirror = new Mirror($inputor);
252 | return at_rect = mirror.create(html).rect();
253 | };
254 |
255 | InputCaret.prototype.getIEPosition = function(pos) {
256 | var h, inputorOffset, offset, x, y;
257 | offset = this.getIEOffset(pos);
258 | inputorOffset = this.$inputor.offset();
259 | x = offset.left - inputorOffset.left;
260 | y = offset.top - inputorOffset.top;
261 | h = offset.height;
262 | return {
263 | left: x,
264 | top: y,
265 | height: h
266 | };
267 | };
268 |
269 | return InputCaret;
270 |
271 | })();
272 |
273 | Mirror = (function() {
274 | Mirror.prototype.css_attr = ["borderBottomWidth", "borderLeftWidth", "borderRightWidth", "borderTopStyle", "borderRightStyle", "borderBottomStyle", "borderLeftStyle", "borderTopWidth", "boxSizing", "fontFamily", "fontSize", "fontWeight", "height", "letterSpacing", "lineHeight", "marginBottom", "marginLeft", "marginRight", "marginTop", "outlineWidth", "overflow", "overflowX", "overflowY", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop", "textAlign", "textOverflow", "textTransform", "whiteSpace", "wordBreak", "wordWrap"];
275 |
276 | function Mirror($inputor) {
277 | this.$inputor = $inputor;
278 | }
279 |
280 | Mirror.prototype.mirrorCss = function() {
281 | var css,
282 | _this = this;
283 | css = {
284 | position: 'absolute',
285 | left: -9999,
286 | top: 0,
287 | zIndex: -20000
288 | };
289 | if (this.$inputor.prop('tagName') === 'TEXTAREA') {
290 | this.css_attr.push('width');
291 | }
292 | $.each(this.css_attr, function(i, p) {
293 | return css[p] = _this.$inputor.css(p);
294 | });
295 | return css;
296 | };
297 |
298 | Mirror.prototype.create = function(html) {
299 | this.$mirror = $('');
300 | this.$mirror.css(this.mirrorCss());
301 | this.$mirror.html(html);
302 | this.$inputor.after(this.$mirror);
303 | return this;
304 | };
305 |
306 | Mirror.prototype.rect = function() {
307 | var $flag, pos, rect;
308 | $flag = this.$mirror.find("#caret");
309 | pos = $flag.position();
310 | rect = {
311 | left: pos.left,
312 | top: pos.top,
313 | height: $flag.height()
314 | };
315 | this.$mirror.remove();
316 | return rect;
317 | };
318 |
319 | return Mirror;
320 |
321 | })();
322 |
323 | Utils = {
324 | contentEditable: function($inputor) {
325 | return !!($inputor[0].contentEditable && $inputor[0].contentEditable === 'true');
326 | }
327 | };
328 |
329 | methods = {
330 | pos: function(pos) {
331 | if (pos || pos === 0) {
332 | return this.setPos(pos);
333 | } else {
334 | return this.getPos();
335 | }
336 | },
337 | position: function(pos) {
338 | if (oDocument.selection) {
339 | return this.getIEPosition(pos);
340 | } else {
341 | return this.getPosition(pos);
342 | }
343 | },
344 | offset: function(pos) {
345 | var offset;
346 | offset = this.getOffset(pos);
347 | return offset;
348 | }
349 | };
350 |
351 | oDocument = null;
352 |
353 | oWindow = null;
354 |
355 | oFrame = null;
356 |
357 | setContextBy = function(settings) {
358 | var iframe;
359 | if (iframe = settings != null ? settings.iframe : void 0) {
360 | oFrame = iframe;
361 | oWindow = iframe.contentWindow;
362 | return oDocument = iframe.contentDocument || oWindow.document;
363 | } else {
364 | oFrame = void 0;
365 | oWindow = window;
366 | return oDocument = document;
367 | }
368 | };
369 |
370 | discoveryIframeOf = function($dom) {
371 | var error;
372 | oDocument = $dom[0].ownerDocument;
373 | oWindow = oDocument.defaultView || oDocument.parentWindow;
374 | try {
375 | return oFrame = oWindow.frameElement;
376 | } catch (_error) {
377 | error = _error;
378 | }
379 | };
380 |
381 | $.fn.caret = function(method, value, settings) {
382 | var caret;
383 | if (methods[method]) {
384 | if ($.isPlainObject(value)) {
385 | setContextBy(value);
386 | value = void 0;
387 | } else {
388 | setContextBy(settings);
389 | }
390 | caret = Utils.contentEditable(this) ? new EditableCaret(this) : new InputCaret(this);
391 | return methods[method].apply(caret, [value]);
392 | } else {
393 | return $.error("Method " + method + " does not exist on jQuery.caret");
394 | }
395 | };
396 |
397 | $.fn.caret.EditableCaret = EditableCaret;
398 |
399 | $.fn.caret.InputCaret = InputCaret;
400 |
401 | $.fn.caret.Utils = Utils;
402 |
403 | $.fn.caret.apis = methods;
404 |
405 |
406 | }));
407 |
--------------------------------------------------------------------------------
/www/static/libs/jquery.qrcode.min.js:
--------------------------------------------------------------------------------
1 | (function(r){r.fn.qrcode=function(h){var s;function u(a){this.mode=s;this.data=a}function o(a,c){this.typeNumber=a;this.errorCorrectLevel=c;this.modules=null;this.moduleCount=0;this.dataCache=null;this.dataList=[]}function q(a,c){if(void 0==a.length)throw Error(a.length+"/"+c);for(var d=0;da||this.moduleCount<=a||0>c||this.moduleCount<=c)throw Error(a+","+c);return this.modules[a][c]},getModuleCount:function(){return this.moduleCount},make:function(){if(1>this.typeNumber){for(var a=1,a=1;40>a;a++){for(var c=p.getRSBlocks(a,this.errorCorrectLevel),d=new t,b=0,e=0;e=d;d++)if(!(-1>=a+d||this.moduleCount<=a+d))for(var b=-1;7>=b;b++)-1>=c+b||this.moduleCount<=c+b||(this.modules[a+d][c+b]=
5 | 0<=d&&6>=d&&(0==b||6==b)||0<=b&&6>=b&&(0==d||6==d)||2<=d&&4>=d&&2<=b&&4>=b?!0:!1)},getBestMaskPattern:function(){for(var a=0,c=0,d=0;8>d;d++){this.makeImpl(!0,d);var b=j.getLostPoint(this);if(0==d||a>b)a=b,c=d}return c},createMovieClip:function(a,c,d){a=a.createEmptyMovieClip(c,d);this.make();for(c=0;c=f;f++)for(var i=-2;2>=i;i++)this.modules[b+f][e+i]=-2==f||2==f||-2==i||2==i||0==f&&0==i?!0:!1}},setupTypeNumber:function(a){for(var c=
7 | j.getBCHTypeNumber(this.typeNumber),d=0;18>d;d++){var b=!a&&1==(c>>d&1);this.modules[Math.floor(d/3)][d%3+this.moduleCount-8-3]=b}for(d=0;18>d;d++)b=!a&&1==(c>>d&1),this.modules[d%3+this.moduleCount-8-3][Math.floor(d/3)]=b},setupTypeInfo:function(a,c){for(var d=j.getBCHTypeInfo(this.errorCorrectLevel<<3|c),b=0;15>b;b++){var e=!a&&1==(d>>b&1);6>b?this.modules[b][8]=e:8>b?this.modules[b+1][8]=e:this.modules[this.moduleCount-15+b][8]=e}for(b=0;15>b;b++)e=!a&&1==(d>>b&1),8>b?this.modules[8][this.moduleCount-
8 | b-1]=e:9>b?this.modules[8][15-b-1+1]=e:this.modules[8][15-b-1]=e;this.modules[this.moduleCount-8][8]=!a},mapData:function(a,c){for(var d=-1,b=this.moduleCount-1,e=7,f=0,i=this.moduleCount-1;0g;g++)if(null==this.modules[b][i-g]){var n=!1;f>>e&1));j.getMask(c,b,i-g)&&(n=!n);this.modules[b][i-g]=n;e--; -1==e&&(f++,e=7)}b+=d;if(0>b||this.moduleCount<=b){b-=d;d=-d;break}}}};o.PAD0=236;o.PAD1=17;o.createData=function(a,c,d){for(var c=p.getRSBlocks(a,
9 | c),b=new t,e=0;e8*a)throw Error("code length overflow. ("+b.getLengthInBits()+">"+8*a+")");for(b.getLengthInBits()+4<=8*a&&b.put(0,4);0!=b.getLengthInBits()%8;)b.putBit(!1);for(;!(b.getLengthInBits()>=8*a);){b.put(o.PAD0,8);if(b.getLengthInBits()>=8*a)break;b.put(o.PAD1,8)}return o.createBytes(b,c)};o.createBytes=function(a,c){for(var d=
10 | 0,b=0,e=0,f=Array(c.length),i=Array(c.length),g=0;g>>=1;return c},getPatternPosition:function(a){return j.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,c,d){switch(a){case 0:return 0==(c+d)%2;case 1:return 0==c%2;case 2:return 0==d%3;case 3:return 0==(c+d)%3;case 4:return 0==(Math.floor(c/2)+Math.floor(d/3))%2;case 5:return 0==c*d%2+c*d%3;case 6:return 0==(c*d%2+c*d%3)%2;case 7:return 0==(c*d%3+(c+d)%2)%2;default:throw Error("bad maskPattern:"+
14 | a);}},getErrorCorrectPolynomial:function(a){for(var c=new q([1],0),d=0;dc)switch(a){case 1:return 10;case 2:return 9;case s:return 8;case 8:return 8;default:throw Error("mode:"+a);}else if(27>c)switch(a){case 1:return 12;case 2:return 11;case s:return 16;case 8:return 10;default:throw Error("mode:"+a);}else if(41>c)switch(a){case 1:return 14;case 2:return 13;case s:return 16;case 8:return 12;default:throw Error("mode:"+
15 | a);}else throw Error("type:"+c);},getLostPoint:function(a){for(var c=a.getModuleCount(),d=0,b=0;b=g;g++)if(!(0>b+g||c<=b+g))for(var h=-1;1>=h;h++)0>e+h||c<=e+h||0==g&&0==h||i==a.isDark(b+g,e+h)&&f++;5a)throw Error("glog("+a+")");return l.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;256<=a;)a-=255;return l.EXP_TABLE[a]},EXP_TABLE:Array(256),
17 | LOG_TABLE:Array(256)},m=0;8>m;m++)l.EXP_TABLE[m]=1<m;m++)l.EXP_TABLE[m]=l.EXP_TABLE[m-4]^l.EXP_TABLE[m-5]^l.EXP_TABLE[m-6]^l.EXP_TABLE[m-8];for(m=0;255>m;m++)l.LOG_TABLE[l.EXP_TABLE[m]]=m;q.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var c=Array(this.getLength()+a.getLength()-1),d=0;d
18 | this.getLength()-a.getLength())return this;for(var c=l.glog(this.get(0))-l.glog(a.get(0)),d=Array(this.getLength()),b=0;b>>7-a%8&1)},put:function(a,c){for(var d=0;d>>c-d-1&1))},getLengthInBits:function(){return this.length},putBit:function(a){var c=Math.floor(this.length/8);this.buffer.length<=c&&this.buffer.push(0);a&&(this.buffer[c]|=128>>>this.length%8);this.length++}};"string"===typeof h&&(h={text:h});h=r.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,
26 | correctLevel:2,background:"#ffffff",foreground:"#000000"},h);return this.each(function(){var a;if("canvas"==h.render){a=new o(h.typeNumber,h.correctLevel);a.addData(h.text);a.make();var c=document.createElement("canvas");c.width=h.width;c.height=h.height;for(var d=c.getContext("2d"),b=h.width/a.getModuleCount(),e=h.height/a.getModuleCount(),f=0;f").css("width",h.width+"px").css("height",h.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",h.background);d=h.width/a.getModuleCount();b=h.height/a.getModuleCount();for(e=0;e").css("height",b+"px").appendTo(c);for(i=0;i").css("width",
28 | d+"px").css("background-color",a.isDark(e,i)?h.foreground:h.background).appendTo(f)}}a=c;jQuery(a).appendTo(this)})}})(jQuery);
29 |
--------------------------------------------------------------------------------
/www/static/libs/custombox/custombox.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * custombox v3.0.2 - 2015-12-05
3 | * Modal Window Effects with transitions CSS3.
4 | * http://dixso.github.io/custombox/
5 | * (c) 2015 Julio de la Calle - @dixso9
6 | *
7 | * Under MIT License - http://opensource.org/licenses/MIT
8 | */
9 |
10 | !function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.Custombox=b()}(this,function(){"use strict";var a={target:null,cache:!1,escKey:!0,zIndex:9999,overlay:!0,overlayColor:"#000",overlayOpacity:.8,overlayClose:!0,overlaySpeed:300,overlayEffect:"auto",width:null,effect:"fadein",position:["center","center"],animation:null,speed:500,loading:!1,open:null,complete:null,close:null},b={oldIE:navigator.appVersion.indexOf("MSIE 8.")>-1||navigator.appVersion.indexOf("MSIE 9.")>-1,oldMobile:/(iPhone|iPad|iPod)\sOS\s6/.test(navigator.userAgent),overlay:{perspective:["letmein","makeway","slip"],together:["corner","slidetogether","scale","door","push","contentscale","simplegenie","slit","slip"]},modal:{position:["slide","flip","rotate"],animationend:["swell","rotatedown","flash"]}},c={set:function(c){if(this.cb&&this.cb.length||(this.cb=[],this.item=-1),this.item++,c&&"auto"===c.zIndex){for(var d=0,e=0,f=document.getElementsByTagName("*"),g=f.length;g>e;e+=1){var h=window.getComputedStyle(f[e]).getPropertyValue("z-index");h&&(h=+h,h>d&&(d=h))}c.zIndex=d}this.cb.push({settings:b.oldIE&&"undefined"!=typeof cbExtendObjects?cbExtendObjects({},a,c):Object.assign({},a,c)}),"auto"===this.cb[this.item].settings.overlayEffect&&(this.cb[this.item].settings.overlayEffect=this.cb[this.item].settings.effect)},get:function(){return this.cb[this.cb.length-1]||null},init:function(){document.documentElement.classList.add("custombox-open"),document.documentElement.classList.add("custombox-open-"+this.cb[this.item].settings.overlayEffect),b.overlay.perspective.indexOf(this.cb[this.item].settings.overlayEffect)>-1&&(this.cb[this.item].scroll=document.documentElement&&document.documentElement.scrollTop||document.body&&document.body.scrollTop||0,document.documentElement.classList.add("custombox-perspective"),window.scrollTo(0,0)),this.main||this.built("container"),this.cb[this.item].settings.loading&&this.cb[this.item].settings.loading.parent&&this.built("loading"),this.cb[this.item].settings.overlay?this.built("overlay").built("modal").open():this.built("modal").open(),this.binds()},built:function(a){var c;switch("undefined"!=typeof this.item&&(c=this.cb[this.item]),a){case"container":for(this.main=document.createElement("div");document.body.firstChild;)this.main.appendChild(document.body.firstChild);document.body.appendChild(this.main);break;case"overlay":c.overlay||(c.overlay={}),c.overlay=document.createElement("div"),c.overlay.classList.add("custombox-overlay"),c.overlay.classList.add("custombox-overlay-"+c.settings.overlayEffect),c.overlay.style.zIndex=c.settings.zIndex+2,c.overlay.style.backgroundColor=c.settings.overlayColor,b.overlay.perspective.indexOf(c.settings.overlayEffect)>-1||b.overlay.together.indexOf(c.settings.overlayEffect)>-1?c.overlay.style.opacity=c.settings.overlayOpacity:c.overlay.classList.add("custombox-overlay-default"),b.overlay.together.indexOf(c.settings.overlayEffect)>-1?c.overlay.style.transitionDuration=c.settings.speed+"ms":c.overlay.style.transitionDuration=c.settings.overlaySpeed+"ms",document.body.insertBefore(c.overlay,document.body.lastChild.nextSibling);break;case"modal":"push"===c.settings.overlayEffect&&(this.main.style.transitionDuration=c.settings.speed+"ms"),this.main.classList.add("custombox-container"),this.main.classList.add("custombox-container-"+c.settings.overlayEffect),c.wrapper=document.createElement("div"),c.wrapper.classList.add("custombox-modal-wrapper"),c.wrapper.classList.add("custombox-modal-wrapper-"+c.settings.effect),c.wrapper.style.zIndex=c.settings.zIndex+3,document.body.insertBefore(c.wrapper,document.body.lastChild.nextSibling),c.container=document.createElement("div"),c.container.classList.add("custombox-modal-container"),c.container.classList.add("custombox-modal-container-"+c.settings.effect),c.container.style.zIndex=c.settings.zIndex+4,b.modal.position.indexOf(c.settings.effect)>-1&&null===c.settings.animation&&("slide"===c.settings.effect?c.settings.animation=["top"]:"flip"===c.settings.effect?c.settings.animation=["horizontal"]:c.settings.animation=["bottom"]),c.modal=document.createElement("div"),c.modal.classList.add("custombox-modal"),c.modal.classList.add("custombox-modal-"+c.settings.effect+(b.modal.position.indexOf(c.settings.effect)>-1?"-"+c.settings.animation[0].trim():"")),c.modal.style.transitionDuration=c.settings.speed+"ms",c.modal.style.zIndex=c.settings.zIndex+4,c.wrapper.appendChild(c.container).appendChild(c.modal);break;case"loading":this.loading=document.createElement("div"),this.loading.classList.add("custombox-loading");for(var d=document.createElement("div"),e=0,f=this.cb[this.item].settings.loading.parent.length;f>e;e++)d.classList.add(this.cb[this.item].settings.loading.parent[e]);if(this.loading.appendChild(d),this.loading.style.zIndex=c.settings.zIndex+3,this.cb[this.item].settings.loading.childrens)for(var g=0,h=this.cb[this.item].settings.loading.childrens.length;h>g;g++){for(var i=document.createElement("div"),j=0,k=this.cb[this.item].settings.loading.childrens[g].length;k>j;j++)i.classList.add(this.cb[this.item].settings.loading.childrens[g][j]);d.appendChild(i)}document.body.appendChild(this.loading)}return this},load:function(){var a=this.cb[this.item];if("function"==typeof a.settings.open&&a.settings.open.call(),document.createEvent){var b=document.createEvent("Event");b.initEvent("custombox.open",!0,!0),document.dispatchEvent(b)}return null!==a.settings.target&&Array.isArray(a.settings.position)?"#"===a.settings.target.charAt(0)||"."===a.settings.target.charAt(0)&&"/"!==a.settings.target.charAt(1)?document.querySelector(a.settings.target)?(a.inline=document.createElement("div"),a.content=document.querySelector(a.settings.target),a.display="none"===a.content.style.display,a.content.style.display="block",a.content.parentNode.insertBefore(a.inline,a.content),this.size()):this.error():this.ajax():this.error(),this},size:function(){var a=this.cb[this.item],c=a.content.offsetWidth;if(b.oldIE&&(window.innerHeight=document.documentElement.clientHeight),a.inline||(b.oldIE?a.content.style.styleFloat="none":a.content.style.cssFloat="none"),null!==a.settings.width&&(isNaN(a.settings.width)?(c=window.innerWidth,a.content.style.height=window.innerHeight+"px"):c=parseInt(a.settings.width,0)),a.size=c,a.size+60>=window.innerWidth){a.container.style.width="auto","full"!==a.settings.width&&(a.container.style.margin="5%"),a.wrapper.style.width=window.innerWidth+"px";for(var d=0,e=a.content.querySelectorAll(":scope > *"),f=e.length;f>d;d++)e[d].offsetWidth>window.innerWidth&&(e[d].style.width="auto")}else{switch(a.settings.position[0].trim()){case"left":a.container.style.marginLeft=0;break;case"right":a.container.style.marginRight=0}a.container.style.width=a.size+"px"}if(a.content.style.width="auto",a.modal.appendChild(a.content),a.content.offsetHeight>=window.innerHeight&&"full"!==a.settings.width)a.container.style.marginTop="5%",a.container.style.marginBottom="5%";else{var g;switch(a.settings.position[1].trim()){case"top":g=0;break;case"bottom":g=window.innerHeight-a.content.offsetHeight+"px";break;default:g=window.innerHeight/2-a.content.offsetHeight/2+"px"}a.container.style.marginTop=g}this.loading&&(document.body.removeChild(this.loading),delete this.loading),a.wrapper.classList.add("custombox-modal-open")},ajax:function(){var a=this,c=a.cb[a.item],d=new XMLHttpRequest,e=document.createElement("div");d.onreadystatechange=function(){4===d.readyState&&(200===d.status?(e.innerHTML=d.responseText,c.content=e,c.content.style.display="block",b.oldIE?c.content.style.styleFloat="left":c.content.style.cssFloat="left",c.container.appendChild(c.content),a.size()):a.error())},d.open("GET",c.settings.target+(c.settings.cache?"":(/[?].+=/.test(c.settings.target)?"&_=":"?_=")+Date.now()),!0),d.setRequestHeader("X-Requested-With","XMLHttpRequest"),d.send(null)},scrollbar:function(){var a=document.createElement("div");a.classList.add("custombox-scrollbar"),document.body.appendChild(a);var b=a.offsetWidth-a.clientWidth;return document.body.removeChild(a),b},open:function(){var a=this,c=0,d=a.cb[a.item],e=a.scrollbar();e&&(document.body.style.paddingRight=e+"px"),a.main.classList.add("custombox-container-open"),a.cb[a.item].settings.loading&&(c=a.cb[a.item].settings.loading.delay&&!isNaN(1*a.cb[a.item].settings.loading.delay)?1*a.cb[a.item].settings.loading.delay:1e3);var f=function(b){b&&d.overlay.removeEventListener("transitionend",f),a.load(),d.inline&&d.wrapper.classList.add("custombox-modal-open")};return d.settings.overlay?(b.overlay.perspective.indexOf(d.settings.overlayEffect)>-1||b.overlay.together.indexOf(d.settings.overlayEffect)>-1?d.overlay.classList.add("custombox-overlay-open"):d.overlay.style.opacity=d.settings.overlayOpacity,a.cb[a.item].settings.loading?setTimeout(f,c):b.overlay.together.indexOf(d.settings.overlayEffect)>-1||b.oldIE?f(!1):d.overlay.addEventListener("transitionend",f,!1)):a.cb[a.item].settings.loading?setTimeout(f,c):f(!1),a},clean:function(a){var c=this,d=this.cb[a];if(document.documentElement.classList.remove("custombox-open-"+d.settings.overlayEffect),d.settings.overlay&&(d.overlay.style.opacity&&(d.overlay.style.opacity=0),d.overlay.classList.remove("custombox-overlay-open"),c.main.classList.remove("custombox-container-open")),b.oldIE||b.oldMobile||!d.overlay)c.remove(a);else{var e=function(){d.overlay.removeEventListener("transitionend",e),c.remove(a)};d.overlay.addEventListener("transitionend",e,!1)}},remove:function(a){var c=this,d=this.cb[a];if(d){if(1===c.cb.length&&(document.documentElement.classList.remove("custombox-open","custombox-perspective"),c.scrollbar()&&(document.body.style.paddingRight=0),"undefined"!=typeof d.scroll&&window.scrollTo(0,d.scroll)),d.inline&&(b.oldIE?(d.content.style.removeAttribute("width"),d.content.style.removeAttribute("height"),d.content.style.removeAttribute("display")):(d.content.style.removeProperty("width"),d.content.style.removeProperty("height"),d.content.style.removeProperty("display")),d.display&&(d.content.style.display="none"),d.inline.parentNode.replaceChild(d.content,d.inline)),c.main.classList.remove("custombox-container-"+d.settings.overlayEffect),d.wrapper.parentNode.removeChild(d.wrapper),d.settings.overlay&&d.overlay.parentNode.removeChild(d.overlay),document.createEvent){var e=document.createEvent("Event");e.initEvent("custombox.close",!0,!0),document.dispatchEvent(e)}if(1===c.cb.length){for(var f=document.querySelectorAll(".custombox-container > *"),g=0,h=f.length;h>g;g++)document.body.insertBefore(f[g],c.main);c.main.parentNode&&c.main.parentNode.removeChild(c.main),delete c.main}c.cb.splice(a,1),"function"==typeof d.settings.close&&d.settings.close.call()}},close:function(a,c){var d,e=this;if(a){for(var f=0,g=this.cb.length;g>f;f++)if(this.cb[f].settings.target===a){d=f;break}}else d=e.cb.length-1;var h=e.cb[d];if("function"==typeof c&&(h.settings.close=c),b.modal.position.indexOf(h.settings.effect)>-1&&h.settings.animation.length>1&&(h.modal.classList.remove("custombox-modal-"+h.settings.effect+"-"+h.settings.animation[0]),h.modal.classList.add("custombox-modal-"+h.settings.effect+"-"+h.settings.animation[1].trim())),h.wrapper.classList.remove("custombox-modal-open"),b.oldIE||b.oldMobile||b.overlay.together.indexOf(h.settings.overlayEffect)>-1)e.clean(d);else{var i=function(){h.wrapper.removeEventListener("transitionend",i),e.clean(d)};b.modal.animationend.indexOf(h.settings.effect)>-1?h.wrapper.addEventListener("animationend",i,!1):h.wrapper.addEventListener("transitionend",i,!1)}},responsive:function(){b.oldIE&&(window.innerHeight=document.documentElement.clientHeight);for(var a,c=0,d=this.cb.length;d>c;c++){if(this.cb[c].size+60>=window.innerWidth)"full"!==this.cb[c].settings.width?(this.cb[c].container.style.marginLeft="5%",this.cb[c].container.style.marginRight="5%"):this.cb[c].content.offsetWidth<=window.innerWidth&&(this.cb[c].content.style.width="auto"),this.cb[c].container.style.width="auto",this.cb[c].wrapper.style.width=window.innerWidth+"px";else{switch(this.cb[c].settings.position[0].trim()){case"left":this.cb[c].container.style.marginLeft=0;break;case"right":this.cb[c].container.style.marginRight=0;break;default:this.cb[c].container.style.marginLeft="auto",this.cb[c].container.style.marginRight="auto"}this.cb[c].container.style.width=this.cb[c].size+"px",this.cb[c].wrapper.style.width="auto"}if(this.cb[c].content.offsetHeight>=window.innerHeight&&"full"!==this.cb[c].settings.width)this.cb[c].container.style.marginTop="5%",this.cb[c].container.style.marginBottom="5%";else{switch("full"===this.cb[c].settings.width&&(this.cb[c].settings.position[1]="top",this.cb[c].content.offsetHeight<=window.innerHeight&&(this.cb[c].content.style.height=window.innerHeight+"px")),this.cb[c].settings.position[1].trim()){case"top":a=0;break;case"bottom":a=window.innerHeight-this.cb[c].content.offsetHeight+"px";break;default:a=window.innerHeight/2-this.cb[c].content.offsetHeight/2+"px"}this.cb[c].container.style.marginTop=a}}},binds:function(){var a=this,c=a.cb[a.item],d=!1;1===a.cb.length&&(a.esc=function(b){1===a.cb.length&&document.removeEventListener("keydown",a.esc),b=b||window.event,!d&&27===b.keyCode&&a.get()&&a.get().settings.escKey&&(d=!0,a.close())},document.addEventListener("keydown",a.esc,!1),window.addEventListener("onorientationchange"in window?"orientationchange":"resize",function(){a.responsive()},!1)),c.wrapper.event=function(b){1===a.cb.length&&document.removeEventListener("keydown",c.wrapper.event),!d&&b.target===c.wrapper&&a.get()&&a.get().settings.overlayClose&&(d=!0,a.close())},c.wrapper.addEventListener("click",c.wrapper.event,!1),document.addEventListener("custombox.close",function(){d=!1});var e=function(){if(!c.inline)for(var a=0,b=c.modal.getElementsByTagName("script"),d=b.length;d>a;a++)new Function(b[a].text)();if(c.settings&&"function"==typeof c.settings.complete&&c.settings.complete.call(),document.createEvent){var e=document.createEvent("Event");e.initEvent("custombox.complete",!0,!0),document.dispatchEvent(e)}},f=function(){e(),c.modal.removeEventListener("transitionend",f)};b.oldIE||b.oldMobile?setTimeout(function(){e()},c.settings.overlaySpeed):"slit"!==c.settings.effect?c.modal.addEventListener("transitionend",f,!1):c.modal.addEventListener("animationend",f,!1)},error:function(){var a=this,b=a.cb.length-1;alert("Error to load this target: "+a.cb[b].settings.target),a.remove(b)}};return{set:function(a){a.autobuild&&c.built("container")},open:function(a){c.set(a),c.init()},close:function(a,b){"function"==typeof a&&(b=a,a=!1),c.close(a,b)}}});
--------------------------------------------------------------------------------
/www/static/libs/twemoji.min.js:
--------------------------------------------------------------------------------
1 | /*! Copyright Twitter Inc. and other contributors. Licensed under MIT */
2 | var twemoji=function(){"use strict";var twemoji={base:(location.protocol==="https:"?"https:":"http:")+"//twemoji.maxcdn.com/",ext:".png",size:"36x36",className:"emoji",convert:{fromCodePoint:fromCodePoint,toCodePoint:toCodePoint},onerror:function onerror(){if(this.parentNode){this.parentNode.replaceChild(createText(this.alt),this)}},parse:parse,replace:replace,test:test},escaper={"&":"&","<":"<",">":">","'":"'",'"':"""},re=/((?:\ud83c\udde8\ud83c\uddf3|\ud83c\uddfa\ud83c\uddf8|\ud83c\uddf7\ud83c\uddfa|\ud83c\uddf0\ud83c\uddf7|\ud83c\uddef\ud83c\uddf5|\ud83c\uddee\ud83c\uddf9|\ud83c\uddec\ud83c\udde7|\ud83c\uddeb\ud83c\uddf7|\ud83c\uddea\ud83c\uddf8|\ud83c\udde9\ud83c\uddea|\u0039\ufe0f?\u20e3|\u0038\ufe0f?\u20e3|\u0037\ufe0f?\u20e3|\u0036\ufe0f?\u20e3|\u0035\ufe0f?\u20e3|\u0034\ufe0f?\u20e3|\u0033\ufe0f?\u20e3|\u0032\ufe0f?\u20e3|\u0031\ufe0f?\u20e3|\u0030\ufe0f?\u20e3|\u0023\ufe0f?\u20e3|\ud83d\udeb3|\ud83d\udeb1|\ud83d\udeb0|\ud83d\udeaf|\ud83d\udeae|\ud83d\udea6|\ud83d\udea3|\ud83d\udea1|\ud83d\udea0|\ud83d\ude9f|\ud83d\ude9e|\ud83d\ude9d|\ud83d\ude9c|\ud83d\ude9b|\ud83d\ude98|\ud83d\ude96|\ud83d\ude94|\ud83d\ude90|\ud83d\ude8e|\ud83d\ude8d|\ud83d\ude8b|\ud83d\ude8a|\ud83d\ude88|\ud83d\ude86|\ud83d\ude82|\ud83d\ude81|\ud83d\ude36|\ud83d\ude34|\ud83d\ude2f|\ud83d\ude2e|\ud83d\ude2c|\ud83d\ude27|\ud83d\ude26|\ud83d\ude1f|\ud83d\ude1b|\ud83d\ude19|\ud83d\ude17|\ud83d\ude15|\ud83d\ude11|\ud83d\ude10|\ud83d\ude0e|\ud83d\ude08|\ud83d\ude07|\ud83d\ude00|\ud83d\udd67|\ud83d\udd66|\ud83d\udd65|\ud83d\udd64|\ud83d\udd63|\ud83d\udd62|\ud83d\udd61|\ud83d\udd60|\ud83d\udd5f|\ud83d\udd5e|\ud83d\udd5d|\ud83d\udd5c|\ud83d\udd2d|\ud83d\udd2c|\ud83d\udd15|\ud83d\udd09|\ud83d\udd08|\ud83d\udd07|\ud83d\udd06|\ud83d\udd05|\ud83d\udd04|\ud83d\udd02|\ud83d\udd01|\ud83d\udd00|\ud83d\udcf5|\ud83d\udcef|\ud83d\udced|\ud83d\udcec|\ud83d\udcb7|\ud83d\udcb6|\ud83d\udcad|\ud83d\udc6d|\ud83d\udc6c|\ud83d\udc65|\ud83d\udc2a|\ud83d\udc16|\ud83d\udc15|\ud83d\udc13|\ud83d\udc10|\ud83d\udc0f|\ud83d\udc0b|\ud83d\udc0a|\ud83d\udc09|\ud83d\udc08|\ud83d\udc07|\ud83d\udc06|\ud83d\udc05|\ud83d\udc04|\ud83d\udc03|\ud83d\udc02|\ud83d\udc01|\ud83d\udc00|\ud83c\udfe4|\ud83c\udfc9|\ud83c\udfc7|\ud83c\udf7c|\ud83c\udf50|\ud83c\udf4b|\ud83c\udf33|\ud83c\udf32|\ud83c\udf1e|\ud83c\udf1d|\ud83c\udf1c|\ud83c\udf1a|\ud83c\udf18|\ud83c\udccf|\ud83c\udd8e|\ud83c\udd91|\ud83c\udd92|\ud83c\udd93|\ud83c\udd94|\ud83c\udd95|\ud83c\udd96|\ud83c\udd97|\ud83c\udd98|\ud83c\udd99|\ud83c\udd9a|\ud83d\udc77|\ud83d\udec5|\ud83d\udec4|\ud83d\udec3|\ud83d\udec2|\ud83d\udec1|\ud83d\udebf|\ud83d\udeb8|\ud83d\udeb7|\ud83d\udeb5|\ud83c\ude01|\ud83c\ude32|\ud83c\ude33|\ud83c\ude34|\ud83c\ude35|\ud83c\ude36|\ud83c\ude38|\ud83c\ude39|\ud83c\ude3a|\ud83c\ude50|\ud83c\ude51|\ud83c\udf00|\ud83c\udf01|\ud83c\udf02|\ud83c\udf03|\ud83c\udf04|\ud83c\udf05|\ud83c\udf06|\ud83c\udf07|\ud83c\udf08|\ud83c\udf09|\ud83c\udf0a|\ud83c\udf0b|\ud83c\udf0c|\ud83c\udf0f|\ud83c\udf11|\ud83c\udf13|\ud83c\udf14|\ud83c\udf15|\ud83c\udf19|\ud83c\udf1b|\ud83c\udf1f|\ud83c\udf20|\ud83c\udf30|\ud83c\udf31|\ud83c\udf34|\ud83c\udf35|\ud83c\udf37|\ud83c\udf38|\ud83c\udf39|\ud83c\udf3a|\ud83c\udf3b|\ud83c\udf3c|\ud83c\udf3d|\ud83c\udf3e|\ud83c\udf3f|\ud83c\udf40|\ud83c\udf41|\ud83c\udf42|\ud83c\udf43|\ud83c\udf44|\ud83c\udf45|\ud83c\udf46|\ud83c\udf47|\ud83c\udf48|\ud83c\udf49|\ud83c\udf4a|\ud83c\udf4c|\ud83c\udf4d|\ud83c\udf4e|\ud83c\udf4f|\ud83c\udf51|\ud83c\udf52|\ud83c\udf53|\ud83c\udf54|\ud83c\udf55|\ud83c\udf56|\ud83c\udf57|\ud83c\udf58|\ud83c\udf59|\ud83c\udf5a|\ud83c\udf5b|\ud83c\udf5c|\ud83c\udf5d|\ud83c\udf5e|\ud83c\udf5f|\ud83c\udf60|\ud83c\udf61|\ud83c\udf62|\ud83c\udf63|\ud83c\udf64|\ud83c\udf65|\ud83c\udf66|\ud83c\udf67|\ud83c\udf68|\ud83c\udf69|\ud83c\udf6a|\ud83c\udf6b|\ud83c\udf6c|\ud83c\udf6d|\ud83c\udf6e|\ud83c\udf6f|\ud83c\udf70|\ud83c\udf71|\ud83c\udf72|\ud83c\udf73|\ud83c\udf74|\ud83c\udf75|\ud83c\udf76|\ud83c\udf77|\ud83c\udf78|\ud83c\udf79|\ud83c\udf7a|\ud83c\udf7b|\ud83c\udf80|\ud83c\udf81|\ud83c\udf82|\ud83c\udf83|\ud83c\udf84|\ud83c\udf85|\ud83c\udf86|\ud83c\udf87|\ud83c\udf88|\ud83c\udf89|\ud83c\udf8a|\ud83c\udf8b|\ud83c\udf8c|\ud83c\udf8d|\ud83c\udf8e|\ud83c\udf8f|\ud83c\udf90|\ud83c\udf91|\ud83c\udf92|\ud83c\udf93|\ud83c\udfa0|\ud83c\udfa1|\ud83c\udfa2|\ud83c\udfa3|\ud83c\udfa4|\ud83c\udfa5|\ud83c\udfa6|\ud83c\udfa7|\ud83c\udfa8|\ud83c\udfa9|\ud83c\udfaa|\ud83c\udfab|\ud83c\udfac|\ud83c\udfad|\ud83c\udfae|\ud83c\udfaf|\ud83c\udfb0|\ud83c\udfb1|\ud83c\udfb2|\ud83c\udfb3|\ud83c\udfb4|\ud83c\udfb5|\ud83c\udfb6|\ud83c\udfb7|\ud83c\udfb8|\ud83c\udfb9|\ud83c\udfba|\ud83c\udfbb|\ud83c\udfbc|\ud83c\udfbd|\ud83c\udfbe|\ud83c\udfbf|\ud83c\udfc0|\ud83c\udfc1|\ud83c\udfc2|\ud83c\udfc3|\ud83c\udfc4|\ud83c\udfc6|\ud83c\udfc8|\ud83c\udfca|\ud83c\udfe0|\ud83c\udfe1|\ud83c\udfe2|\ud83c\udfe3|\ud83c\udfe5|\ud83c\udfe6|\ud83c\udfe7|\ud83c\udfe8|\ud83c\udfe9|\ud83c\udfea|\ud83c\udfeb|\ud83c\udfec|\ud83c\udfed|\ud83c\udfee|\ud83c\udfef|\ud83c\udff0|\ud83d\udc0c|\ud83d\udc0d|\ud83d\udc0e|\ud83d\udc11|\ud83d\udc12|\ud83d\udc14|\ud83d\udc17|\ud83d\udc18|\ud83d\udc19|\ud83d\udc1a|\ud83d\udc1b|\ud83d\udc1c|\ud83d\udc1d|\ud83d\udc1e|\ud83d\udc1f|\ud83d\udc20|\ud83d\udc21|\ud83d\udc22|\ud83d\udc23|\ud83d\udc24|\ud83d\udc25|\ud83d\udc26|\ud83d\udc27|\ud83d\udc28|\ud83d\udc29|\ud83d\udc2b|\ud83d\udc2c|\ud83d\udc2d|\ud83d\udc2e|\ud83d\udc2f|\ud83d\udc30|\ud83d\udc31|\ud83d\udc32|\ud83d\udc33|\ud83d\udc34|\ud83d\udc35|\ud83d\udc36|\ud83d\udc37|\ud83d\udc38|\ud83d\udc39|\ud83d\udc3a|\ud83d\udc3b|\ud83d\udc3c|\ud83d\udc3d|\ud83d\udc3e|\ud83d\udc40|\ud83d\udc42|\ud83d\udc43|\ud83d\udc44|\ud83d\udc45|\ud83d\udc46|\ud83d\udc47|\ud83d\udc48|\ud83d\udc49|\ud83d\udc4a|\ud83d\udc4b|\ud83d\udc4c|\ud83d\udc4d|\ud83d\udc4e|\ud83d\udc4f|\ud83d\udc50|\ud83d\udc51|\ud83d\udc52|\ud83d\udc53|\ud83d\udc54|\ud83d\udc55|\ud83d\udc56|\ud83d\udc57|\ud83d\udc58|\ud83d\udc59|\ud83d\udc5a|\ud83d\udc5b|\ud83d\udc5c|\ud83d\udc5d|\ud83d\udc5e|\ud83d\udc5f|\ud83d\udc60|\ud83d\udc61|\ud83d\udc62|\ud83d\udc63|\ud83d\udc64|\ud83d\udc66|\ud83d\udc67|\ud83d\udc68|\ud83d\udc69|\ud83d\udc6a|\ud83d\udc6b|\ud83d\udc6e|\ud83d\udc6f|\ud83d\udc70|\ud83d\udc71|\ud83d\udc72|\ud83d\udc73|\ud83d\udc74|\ud83d\udc75|\ud83d\udc76|\ud83d\udeb4|\ud83d\udc78|\ud83d\udc79|\ud83d\udc7a|\ud83d\udc7b|\ud83d\udc7c|\ud83d\udc7d|\ud83d\udc7e|\ud83d\udc7f|\ud83d\udc80|\ud83d\udc81|\ud83d\udc82|\ud83d\udc83|\ud83d\udc84|\ud83d\udc85|\ud83d\udc86|\ud83d\udc87|\ud83d\udc88|\ud83d\udc89|\ud83d\udc8a|\ud83d\udc8b|\ud83d\udc8c|\ud83d\udc8d|\ud83d\udc8e|\ud83d\udc8f|\ud83d\udc90|\ud83d\udc91|\ud83d\udc92|\ud83d\udc93|\ud83d\udc94|\ud83d\udc95|\ud83d\udc96|\ud83d\udc97|\ud83d\udc98|\ud83d\udc99|\ud83d\udc9a|\ud83d\udc9b|\ud83d\udc9c|\ud83d\udc9d|\ud83d\udc9e|\ud83d\udc9f|\ud83d\udca0|\ud83d\udca1|\ud83d\udca2|\ud83d\udca3|\ud83d\udca4|\ud83d\udca5|\ud83d\udca6|\ud83d\udca7|\ud83d\udca8|\ud83d\udca9|\ud83d\udcaa|\ud83d\udcab|\ud83d\udcac|\ud83d\udcae|\ud83d\udcaf|\ud83d\udcb0|\ud83d\udcb1|\ud83d\udcb2|\ud83d\udcb3|\ud83d\udcb4|\ud83d\udcb5|\ud83d\udcb8|\ud83d\udcb9|\ud83d\udcba|\ud83d\udcbb|\ud83d\udcbc|\ud83d\udcbd|\ud83d\udcbe|\ud83d\udcbf|\ud83d\udcc0|\ud83d\udcc1|\ud83d\udcc2|\ud83d\udcc3|\ud83d\udcc4|\ud83d\udcc5|\ud83d\udcc6|\ud83d\udcc7|\ud83d\udcc8|\ud83d\udcc9|\ud83d\udcca|\ud83d\udccb|\ud83d\udccc|\ud83d\udccd|\ud83d\udcce|\ud83d\udccf|\ud83d\udcd0|\ud83d\udcd1|\ud83d\udcd2|\ud83d\udcd3|\ud83d\udcd4|\ud83d\udcd5|\ud83d\udcd6|\ud83d\udcd7|\ud83d\udcd8|\ud83d\udcd9|\ud83d\udcda|\ud83d\udcdb|\ud83d\udcdc|\ud83d\udcdd|\ud83d\udcde|\ud83d\udcdf|\ud83d\udce0|\ud83d\udce1|\ud83d\udce2|\ud83d\udce3|\ud83d\udce4|\ud83d\udce5|\ud83d\udce6|\ud83d\udce7|\ud83d\udce8|\ud83d\udce9|\ud83d\udcea|\ud83d\udceb|\ud83d\udcee|\ud83d\udcf0|\ud83d\udcf1|\ud83d\udcf2|\ud83d\udcf3|\ud83d\udcf4|\ud83d\udcf6|\ud83d\udcf7|\ud83d\udcf9|\ud83d\udcfa|\ud83d\udcfb|\ud83d\udcfc|\ud83d\udd03|\ud83d\udd0a|\ud83d\udd0b|\ud83d\udd0c|\ud83d\udd0d|\ud83d\udd0e|\ud83d\udd0f|\ud83d\udd10|\ud83d\udd11|\ud83d\udd12|\ud83d\udd13|\ud83d\udd14|\ud83d\udd16|\ud83d\udd17|\ud83d\udd18|\ud83d\udd19|\ud83d\udd1a|\ud83d\udd1b|\ud83d\udd1c|\ud83d\udd1d|\ud83d\udd1e|\ud83d\udd1f|\ud83d\udd20|\ud83d\udd21|\ud83d\udd22|\ud83d\udd23|\ud83d\udd24|\ud83d\udd25|\ud83d\udd26|\ud83d\udd27|\ud83d\udd28|\ud83d\udd29|\ud83d\udd2a|\ud83d\udd2b|\ud83d\udd2e|\ud83d\udd2f|\ud83d\udd30|\ud83d\udd31|\ud83d\udd32|\ud83d\udd33|\ud83d\udd34|\ud83d\udd35|\ud83d\udd36|\ud83d\udd37|\ud83d\udd38|\ud83d\udd39|\ud83d\udd3a|\ud83d\udd3b|\ud83d\udd3c|\ud83d\udd3d|\ud83d\udd50|\ud83d\udd51|\ud83d\udd52|\ud83d\udd53|\ud83d\udd54|\ud83d\udd55|\ud83d\udd56|\ud83d\udd57|\ud83d\udd58|\ud83d\udd59|\ud83d\udd5a|\ud83d\udd5b|\ud83d\uddfb|\ud83d\uddfc|\ud83d\uddfd|\ud83d\uddfe|\ud83d\uddff|\ud83d\ude01|\ud83d\ude02|\ud83d\ude03|\ud83d\ude04|\ud83d\ude05|\ud83d\ude06|\ud83d\ude09|\ud83d\ude0a|\ud83d\ude0b|\ud83d\ude0c|\ud83d\ude0d|\ud83d\ude0f|\ud83d\ude12|\ud83d\ude13|\ud83d\ude14|\ud83d\ude16|\ud83d\ude18|\ud83d\ude1a|\ud83d\ude1c|\ud83d\ude1d|\ud83d\ude1e|\ud83d\ude20|\ud83d\ude21|\ud83d\ude22|\ud83d\ude23|\ud83d\ude24|\ud83d\ude25|\ud83d\ude28|\ud83d\ude29|\ud83d\ude2a|\ud83d\ude2b|\ud83d\ude2d|\ud83d\ude30|\ud83d\ude31|\ud83d\ude32|\ud83d\ude33|\ud83d\ude35|\ud83d\ude37|\ud83d\ude38|\ud83d\ude39|\ud83d\ude3a|\ud83d\ude3b|\ud83d\ude3c|\ud83d\ude3d|\ud83d\ude3e|\ud83d\ude3f|\ud83d\ude40|\ud83d\ude45|\ud83d\ude46|\ud83d\ude47|\ud83d\ude48|\ud83d\ude49|\ud83d\ude4a|\ud83d\ude4b|\ud83d\ude4c|\ud83d\ude4d|\ud83d\ude4e|\ud83d\ude4f|\ud83d\ude80|\ud83d\ude83|\ud83d\ude84|\ud83d\ude85|\ud83d\ude87|\ud83d\ude89|\ud83d\ude8c|\ud83d\ude8f|\ud83d\ude91|\ud83d\ude92|\ud83d\ude93|\ud83d\ude95|\ud83d\ude97|\ud83d\ude99|\ud83d\ude9a|\ud83d\udea2|\ud83d\udea4|\ud83d\udea5|\ud83d\udea7|\ud83d\udea8|\ud83d\udea9|\ud83d\udeaa|\ud83d\udeab|\ud83d\udeac|\ud83d\udead|\ud83d\udeb2|\ud83d\udeb6|\ud83d\udeb9|\ud83d\udeba|\ud83d\udebb|\ud83d\udebc|\ud83d\udebd|\ud83d\udebe|\ud83d\udec0|\ud83c\udde6|\ud83c\udde7|\ud83c\udde8|\ud83c\udde9|\ud83c\uddea|\ud83c\uddeb|\ud83c\uddec|\ud83c\udded|\ud83c\uddee|\ud83c\uddef|\ud83c\uddf0|\ud83c\uddf1|\ud83c\uddf2|\ud83c\uddf3|\ud83c\uddf4|\ud83c\uddf5|\ud83c\uddf6|\ud83c\uddf7|\ud83c\uddf8|\ud83c\uddf9|\ud83c\uddfa|\ud83c\uddfb|\ud83c\uddfc|\ud83c\uddfd|\ud83c\uddfe|\ud83c\uddff|\ud83c\udf0d|\ud83c\udf0e|\ud83c\udf10|\ud83c\udf12|\ud83c\udf16|\ud83c\udf17|\ue50a|\u27b0|\u2797|\u2796|\u2795|\u2755|\u2754|\u2753|\u274e|\u274c|\u2728|\u270b|\u270a|\u2705|\u26ce|\u23f3|\u23f0|\u23ec|\u23eb|\u23ea|\u23e9|\u27bf|\u00a9|\u00ae)|(?:(?:\ud83c\udc04|\ud83c\udd70|\ud83c\udd71|\ud83c\udd7e|\ud83c\udd7f|\ud83c\ude02|\ud83c\ude1a|\ud83c\ude2f|\ud83c\ude37|\u3299|\u303d|\u3030|\u2b55|\u2b50|\u2b1c|\u2b1b|\u2b07|\u2b06|\u2b05|\u2935|\u2934|\u27a1|\u2764|\u2757|\u2747|\u2744|\u2734|\u2733|\u2716|\u2714|\u2712|\u270f|\u270c|\u2709|\u2708|\u2702|\u26fd|\u26fa|\u26f5|\u26f3|\u26f2|\u26ea|\u26d4|\u26c5|\u26c4|\u26be|\u26bd|\u26ab|\u26aa|\u26a1|\u26a0|\u2693|\u267f|\u267b|\u3297|\u2666|\u2665|\u2663|\u2660|\u2653|\u2652|\u2651|\u2650|\u264f|\u264e|\u264d|\u264c|\u264b|\u264a|\u2649|\u2648|\u263a|\u261d|\u2615|\u2614|\u2611|\u260e|\u2601|\u2600|\u25fe|\u25fd|\u25fc|\u25fb|\u25c0|\u25b6|\u25ab|\u25aa|\u24c2|\u231b|\u231a|\u21aa|\u21a9|\u2199|\u2198|\u2197|\u2196|\u2195|\u2194|\u2139|\u2122|\u2049|\u203c|\u2668)([\uFE0E\uFE0F]?)))/g,rescaper=/[&<>'"]/g,shouldntBeParsed=/IFRAME|NOFRAMES|NOSCRIPT|SCRIPT|SELECT|STYLE|TEXTAREA|[a-z]/,fromCharCode=String.fromCharCode;return twemoji;function createText(text){return document.createTextNode(text)}function escapeHTML(s){return s.replace(rescaper,replacer)}function defaultImageSrcGenerator(icon,options){return"".concat(options.base,options.size,"/",icon,options.ext)}function grabAllTextNodes(node,allText){var childNodes=node.childNodes,length=childNodes.length,subnode,nodeType;while(length--){subnode=childNodes[length];nodeType=subnode.nodeType;if(nodeType===3){allText.push(subnode)}else if(nodeType===1&&!shouldntBeParsed.test(subnode.nodeName)){grabAllTextNodes(subnode,allText)}}return allText}function grabTheRightIcon(icon,variant){return toCodePoint(variant==="️"?icon.slice(0,-1):icon.length===3&&icon.charAt(1)==="️"?icon.charAt(0)+icon.charAt(2):icon)}function parseNode(node,options){var allText=grabAllTextNodes(node,[]),length=allText.length,attrib,attrname,modified,fragment,subnode,text,match,i,index,img,alt,icon,variant,src;while(length--){modified=false;fragment=document.createDocumentFragment();subnode=allText[length];text=subnode.nodeValue;i=0;while(match=re.exec(text)){index=match.index;if(index!==i){fragment.appendChild(createText(text.slice(i,index)))}alt=match[0];icon=match[1];variant=match[2];i=index+alt.length;if(variant!=="︎"){src=options.callback(grabTheRightIcon(icon,variant),options,variant);if(src){img=new Image;img.onerror=options.onerror;img.setAttribute("draggable","false");attrib=options.attributes(icon,variant);for(attrname in attrib){if(attrib.hasOwnProperty(attrname)&&attrname.indexOf("on")!==0&&!img.hasAttribute(attrname)){img.setAttribute(attrname,attrib[attrname])}}img.className=options.className;img.alt=alt;img.src=src;modified=true;fragment.appendChild(img)}}if(!img)fragment.appendChild(createText(alt));img=null}if(modified){if(i")}}return ret})}function replacer(m){return escaper[m]}function returnNull(){return null}function toSizeSquaredAsset(value){return typeof value==="number"?value+"x"+value:value}function fromCodePoint(codepoint){var code=typeof codepoint==="string"?parseInt(codepoint,16):codepoint;if(code<65536){return fromCharCode(code)}code-=65536;return fromCharCode(55296+(code>>10),56320+(code&1023))}function parse(what,how){if(!how||typeof how==="function"){how={callback:how}}return(typeof what==="string"?parseString:parseNode)(what,{callback:how.callback||defaultImageSrcGenerator,attributes:typeof how.attributes==="function"?how.attributes:returnNull,base:typeof how.base==="string"?how.base:twemoji.base,ext:how.ext||twemoji.ext,size:how.folder||toSizeSquaredAsset(how.size||twemoji.size),className:how.className||twemoji.className,onerror:how.onerror||twemoji.onerror})}function replace(text,callback){return String(text).replace(re,callback)}function test(text){re.lastIndex=0;var result=re.test(text);re.lastIndex=0;return result}function toCodePoint(unicodeSurrogates,sep){var r=[],c=0,p=0,i=0;while(idiv,.custombox-modal-container-slidetogether>div{opacity:0;float:left}.custombox-modal-open>.custombox-modal-container-slide>div,.custombox-modal-open>.custombox-modal-container-slidetogether>div{opacity:1}.custombox-modal-slide-top{-webkit-transform:translateY(-300%);-ms-transform:translateY(-300%);transform:translateY(-300%)}.custombox-modal-open .custombox-modal-slide-top{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.custombox-modal-slide-left{-webkit-transform:translateX(-300%);-ms-transform:translateX(-300%);transform:translateX(-300%)}.custombox-modal-open .custombox-modal-slide-left{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.custombox-modal-slide-right{-webkit-transform:translateX(300%);-ms-transform:translateX(300%);transform:translateX(300%)}.custombox-modal-open .custombox-modal-slide-right{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.custombox-modal-slide-bottom{-webkit-transform:translateY(300%);-ms-transform:translateY(300%);transform:translateY(300%)}.custombox-modal-open .custombox-modal-slide-bottom{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.custombox-modal-newspaper{-webkit-transform:scale(0) rotate(720deg);-ms-transform:scale(0) rotate(720deg);transform:scale(0) rotate(720deg);opacity:0;-webkit-transition-property:all;transition-property:all;position:absolute}.custombox-overlay-newspaper{-webkit-transition-property:all;transition-property:all}.custombox-modal-open .custombox-modal-newspaper{-webkit-transform:scale(1) rotate(0);-ms-transform:scale(1) rotate(0);transform:scale(1) rotate(0);opacity:1}.custombox-modal-container-fall{-webkit-perspective:1300px;perspective:1300px}.custombox-modal-fall{-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:translateZ(600px) rotateX(20deg);transform:translateZ(600px) rotateX(20deg);opacity:0}.custombox-modal-open .custombox-modal-fall{-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-property:all;transition-property:all;-webkit-transform:translateZ(0) rotateX(0);transform:translateZ(0) rotateX(0);opacity:1}.custombox-modal-container-sidefall{-webkit-perspective:1300px;perspective:1300px}.custombox-modal-wrapper-sidefall{overflow-x:hidden}.custombox-modal-sidefall{-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:translate(30%) translateZ(600px) rotate(10deg);transform:translate(30%) translateZ(600px) rotate(10deg);opacity:0}.custombox-modal-open .custombox-modal-sidefall{-webkit-transition-timing-function:ease-in;transition-timing-function:ease-in;-webkit-transition-property:all;transition-property:all;-webkit-transform:translate(0) translateZ(0) rotate(0);transform:translate(0) translateZ(0) rotate(0);opacity:1}.custombox-open-blur .custombox-container-blur{-webkit-filter:blur(3px);filter:blur(3px)}@media all and (-ms-high-contrast:none){.custombox-open-blur .custombox-container-blur{text-shadow:0 0 8px #000;color:rgba(255,255,255,0);filter:progid:DXImageTransform.Microsoft.Blur(PixelRadius='3');zoom:1}}.custombox-modal-blur{-webkit-transform:translateY(-5%);-ms-transform:translateY(-5%);transform:translateY(-5%);opacity:0;position:absolute}.custombox-modal-container-blur,.custombox-overlay-blur{-webkit-transition-property:all;transition-property:all}.custombox-modal-open .custombox-modal-blur{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);opacity:1}.custombox-modal-container-flip{-webkit-perspective:1300px;perspective:1300px}.custombox-modal-flip-horizontal{position:absolute;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:rotateY(-70deg);transform:rotateY(-70deg);-webkit-transition-property:all;transition-property:all;opacity:0}.custombox-modal-open .custombox-modal-flip-horizontal{-webkit-transform:rotateY(0);transform:rotateY(0);opacity:1}.custombox-modal-flip-vertical{position:absolute;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:rotateX(-70deg);transform:rotateX(-70deg);-webkit-transition-property:all;transition-property:all;opacity:0}.custombox-modal-open .custombox-modal-flip-vertical{-webkit-transform:rotateX(0);transform:rotateX(0);opacity:1}.custombox-modal-container-sign{-webkit-perspective:1300px;perspective:1300px}.custombox-modal-sign{-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:rotateX(-60deg);transform:rotateX(-60deg);-webkit-transform-origin:50% 0;-ms-transform-origin:50% 0;transform-origin:50% 0;opacity:0;-webkit-transition-property:all;transition-property:all}.custombox-modal-open .custombox-modal-sign{-webkit-transform:rotateX(0);transform:rotateX(0);opacity:1}.custombox-modal-superscaled{-webkit-transform:scale(2);-ms-transform:scale(2);transform:scale(2);opacity:0;-webkit-transition-property:all;transition-property:all;position:absolute}.custombox-modal-open .custombox-modal-superscaled{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}.custombox-modal-container-slit{-webkit-perspective:1300px;perspective:1300px}.custombox-modal-slit{-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:translateZ(-3000px) rotateY(90deg);transform:translateZ(-3000px) rotateY(90deg);opacity:0}.custombox-modal-open .custombox-modal-slit{-webkit-animation:slit .7s forwards ease-out;animation:slit .7s forwards ease-out}@-webkit-keyframes slit{50%{-webkit-transform:translateZ(-250px) rotateY(89deg);transform:translateZ(-250px) rotateY(89deg);opacity:1;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}100%{-webkit-transform:translateZ(0) rotateY(0);transform:translateZ(0) rotateY(0);opacity:1}}@keyframes slit{50%{-webkit-transform:translateZ(-250px) rotateY(89deg);transform:translateZ(-250px) rotateY(89deg);opacity:1;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}100%{-webkit-transform:translateZ(0) rotateY(0);transform:translateZ(0) rotateY(0);opacity:1}}.custombox-modal-container-rotate{-webkit-perspective:1300px;perspective:1300px}.custombox-modal-rotate-bottom{-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:translateY(100%) rotateX(90deg);transform:translateY(100%) rotateX(90deg);-webkit-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%;opacity:0;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out;-webkit-transition-property:all;transition-property:all;position:absolute}.custombox-modal-open .custombox-modal-rotate-bottom{-webkit-transform:translateY(0) rotateX(0);transform:translateY(0) rotateX(0);opacity:1}.custombox-modal-rotate-left{-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:translateZ(100px) translateX(-30%) rotateY(90deg);transform:translateZ(100px) translateX(-30%) rotateY(90deg);-webkit-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%;opacity:0;-webkit-transition-property:all;transition-property:all;position:absolute}.custombox-modal-open .custombox-modal-rotate-left{-webkit-transform:translateZ(0) translateX(0) rotateY(0);transform:translateZ(0) translateX(0) rotateY(0);opacity:1}.custombox-modal-container-letmein{-webkit-transition-property:-webkit-transform;transition-property:transform;-webkit-transform:rotateX(-2deg);transform:rotateX(-2deg);-webkit-transform-origin:50% 0;-ms-transform-origin:50% 0;transform-origin:50% 0;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;opacity:1}.custombox-modal-letmein{opacity:0;-webkit-transform:translateY(300%);-ms-transform:translateY(300%);transform:translateY(300%);float:left}.custombox-modal-open .custombox-modal-letmein{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);opacity:1;-webkit-transition-property:all;transition-property:all}.custombox-modal-makeway{-webkit-transform:translateX(200%);-ms-transform:translateX(200%);transform:translateX(200%);opacity:0;float:left}.custombox-modal-open .custombox-modal-makeway{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0);opacity:1}.custombox-modal-wrapper-makeway{overflow:hidden}.custombox-modal-slip{-webkit-transform:translateY(-350%);-ms-transform:translateY(-350%);transform:translateY(-350%)}.custombox-modal-open .custombox-modal-slip{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);-webkit-transition-property:all;transition-property:all}.custombox-modal-corner{opacity:0;-webkit-transform:translateY(150px) translateX(150px);-ms-transform:translateY(150px) translateX(150px);transform:translateY(150px) translateX(150px);-webkit-transition-property:opacity,-webkit-transform,visibility;transition-property:opacity,transform,visibility}.custombox-modal-open .custombox-modal-corner{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0);opacity:1;-webkit-transition-property:opacity,-webkit-transform;transition-property:opacity,transform}.custombox-modal-slidetogether{-webkit-transform:translateY(-600%);-ms-transform:translateY(-600%);transform:translateY(-600%)}.custombox-modal-open .custombox-modal-slidetogether{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.custombox-modal-scale{-webkit-transform:scale(.9);-ms-transform:scale(.9);transform:scale(.9);-webkit-transition:-webkit-transform;transition:transform;opacity:0}.custombox-modal-open .custombox-modal-scale{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);-webkit-transition:-webkit-transform;transition:transform;opacity:1}.custombox-modal-door{visibility:hidden;opacity:0}.custombox-modal-open .custombox-modal-door{opacity:1;visibility:visible}.custombox-modal-push{-webkit-transform:translateX(-300%);-ms-transform:translateX(-300%);transform:translateX(-300%)}.custombox-modal-open .custombox-modal-push{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}.custombox-modal-contentscale{-webkit-transform:translateY(600%);-ms-transform:translateY(600%);transform:translateY(600%);-webkit-transition-property:-webkit-transform ease-in-out;transition-property:transform ease-in-out;position:absolute}.custombox-modal-open .custombox-modal-contentscale{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.custombox-modal-swell{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-name:swell-close;animation-name:swell-close}.custombox-modal-open .custombox-modal-swell{-webkit-animation-name:swell-open;animation-name:swell-open}@-webkit-keyframes swell-open{0%{opacity:0;-webkit-transform:translate3d(-webkit-calc(-100vw - 50%),0,0);transform:translate3d(calc(-100vw - 50%),0,0)}50%{opacity:1;-webkit-transform:translate3d(100px,0,0);transform:translate3d(100px,0,0)}100%{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes swell-open{0%{opacity:0;-webkit-transform:translate3d(-webkit-calc(-100vw - 50%),0,0);transform:translate3d(calc(-100vw - 50%),0,0)}50%{opacity:1;-webkit-transform:translate3d(100px,0,0);transform:translate3d(100px,0,0)}100%{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes swell-close{0%{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}50%{opacity:1;-webkit-transform:translate3d(-100px,0,0) scale3d(1.1,1.1,1);transform:translate3d(-100px,0,0) scale3d(1.1,1.1,1)}100%{opacity:0;-webkit-transform:translate3d(-webkit-calc(100vw + 50%),0,0);transform:translate3d(calc(100vw + 50%),0,0)}}@keyframes swell-close{0%{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}50%{opacity:1;-webkit-transform:translate3d(-100px,0,0) scale3d(1.1,1.1,1);transform:translate3d(-100px,0,0) scale3d(1.1,1.1,1)}100%{opacity:0;-webkit-transform:translate3d(-webkit-calc(100vw + 50%),0,0);transform:translate3d(calc(100vw + 50%),0,0)}}.custombox-modal-rotatedown{-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-timing-function:cubic-bezier(.7,0,.3,1);animation-timing-function:cubic-bezier(.7,0,.3,1);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-transform-origin:-150% 50%;-ms-transform-origin:-150% 50%;transform-origin:-150% 50%;-webkit-animation-name:rotatedown-close;animation-name:rotatedown-close;overflow:hidden}.custombox-modal-open .custombox-modal-rotatedown{-webkit-animation-name:rotatedown-open;animation-name:rotatedown-open}.custombox-modal-open .custombox-modal-rotatedown div>*{-webkit-animation:rotatedown-elem .4s both;animation:rotatedown-elem .4s both;-webkit-transform-origin:-50% 50%;-ms-transform-origin:-50% 50%;transform-origin:-50% 50%;-webkit-animation-timing-function:cubic-bezier(.7,0,.3,1);animation-timing-function:cubic-bezier(.7,0,.3,1);-webkit-animation-delay:.15s;animation-delay:.15s}@-webkit-keyframes rotatedown-open{0%{opacity:0;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg)}100%{opacity:1;-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes rotatedown-open{0%{opacity:0;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg)}100%{opacity:1;-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@-webkit-keyframes rotatedown-close{0%{opacity:1}100%{opacity:0;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg)}}@keyframes rotatedown-close{0%{opacity:1}100%{opacity:0;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg)}}@-webkit-keyframes rotatedown-elem{0%{opacity:0;-webkit-transform:translate3d(0,-150px,0) rotate3d(0,0,1,-20deg);transform:translate3d(0,-150px,0) rotate3d(0,0,1,-20deg)}100%{opacity:1;-webkit-transform:translate3d(0,0,0) rotate3d(0,0,1,0deg);transform:translate3d(0,0,0) rotate3d(0,0,1,0deg)}}@keyframes rotatedown-elem{0%{opacity:0;-webkit-transform:translate3d(0,-150px,0) rotate3d(0,0,1,-20deg);transform:translate3d(0,-150px,0) rotate3d(0,0,1,-20deg)}100%{opacity:1;-webkit-transform:translate3d(0,0,0) rotate3d(0,0,1,0deg);transform:translate3d(0,0,0) rotate3d(0,0,1,0deg)}}.custombox-modal-flash{-webkit-animation-duration:.4s;animation-duration:.4s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:cubic-bezier(.7,0,.3,1);animation-timing-function:cubic-bezier(.7,0,.3,1);-webkit-animation-name:flash-close;animation-name:flash-close;overflow:hidden}.custombox-modal-open .custombox-modal-flash{-webkit-animation-name:flash-open;animation-name:flash-open}.custombox-modal-open .custombox-modal-flash div>*{-webkit-animation:flash-elem-open .4s cubic-bezier(.7,0,.3,1) both;animation:flash-elem-open .4s cubic-bezier(.7,0,.3,1) both}.custombox-modal-flash div>*{-webkit-animation:flash-elem-close .4s cubic-bezier(.7,0,.3,1) both;animation:flash-elem-close .4s cubic-bezier(.7,0,.3,1) both}@-webkit-keyframes flash-open{0%{opacity:0;-webkit-transform:translate3d(-400px,0,0) scale3d(1.4,0,1);transform:translate3d(-400px,0,0) scale3d(1.4,0,1)}100%{opacity:1;-webkit-transform:translate3d(0,0,0) scale3d(1,1,1);transform:translate3d(0,0,0) scale3d(1,1,1)}}@keyframes flash-open{0%{opacity:0;-webkit-transform:translate3d(-400px,0,0) scale3d(1.4,0,1);transform:translate3d(-400px,0,0) scale3d(1.4,0,1)}100%{opacity:1;-webkit-transform:translate3d(0,0,0) scale3d(1,1,1);transform:translate3d(0,0,0) scale3d(1,1,1)}}@-webkit-keyframes flash-close{0%,20%{opacity:1;-webkit-transform:translate3d(0,0,0) scale3d(1,1,1);transform:translate3d(0,0,0) scale3d(1,1,1)}100%{opacity:0;-webkit-transform:translate3d(-400px,0,0) scale3d(1.4,0,1);transform:translate3d(-400px,0,0) scale3d(1.4,0,1)}}@keyframes flash-close{0%,20%{opacity:1;-webkit-transform:translate3d(0,0,0) scale3d(1,1,1);transform:translate3d(0,0,0) scale3d(1,1,1)}100%{opacity:0;-webkit-transform:translate3d(-400px,0,0) scale3d(1.4,0,1);transform:translate3d(-400px,0,0) scale3d(1.4,0,1)}}@-webkit-keyframes flash-elem-open{0%,20%{opacity:0;-webkit-transform:translate3d(-100px,0,0);transform:translate3d(-100px,0,0)}100%{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes flash-elem-open{0%,20%{opacity:0;-webkit-transform:translate3d(-100px,0,0);transform:translate3d(-100px,0,0)}100%{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes flash-elem-close{0%{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{opacity:0;-webkit-transform:translate3d(-100px,0,0);transform:translate3d(-100px,0,0)}}@keyframes flash-elem-close{0%{opacity:1;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{opacity:0;-webkit-transform:translate3d(-100px,0,0);transform:translate3d(-100px,0,0)}}
--------------------------------------------------------------------------------
/view/common/error_404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Not Found - ThinkJS
5 |
21 |
22 |
23 |
31 |
32 |
33 |
Not Found
34 |
<%if(http.error){%><%=http.error.message%><%}%>
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/view/common/error_400.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bad Request - ThinkJS
5 |
21 |
22 |
23 |
31 |
32 |
33 |
Bad Request
34 |
<%if(http.error){%><%=http.error.message%><%}%>
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------