├── .bin └── jade ├── .gitignore ├── LICENSE ├── README.md ├── app.js ├── bin └── www ├── model ├── core.js ├── dbquery.js ├── judger.js ├── problem.js ├── problems.js └── submission.js ├── package.json ├── public ├── LICENSE.txt ├── css │ ├── font-awesome.min.css │ ├── skel.css │ ├── style-large.css │ ├── style-medium.css │ ├── style-small.css │ ├── style-xlarge.css │ ├── style-xsmall.css │ └── style.css ├── elements.html ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── generic.html ├── images │ ├── bokeh_car_lights_bg.jpg │ ├── dark_tint.png │ ├── pic02.jpg │ ├── pic03.jpg │ ├── pic04.jpg │ ├── pic07.jpg │ ├── pic08.jpg │ └── profile_placeholder.gif ├── index.bak ├── javascripts │ ├── basket.full.min.js │ ├── bootstrap.min.js │ ├── jquery.md5.js │ ├── jquery.min.js │ ├── login │ │ ├── login.js │ │ ├── register.js │ │ └── success.js │ └── rating.js ├── js │ ├── html5shiv.js │ ├── init.js │ ├── jquery.min.js │ ├── skel-layers.min.js │ └── skel.min.js ├── stylesheets │ ├── admin │ │ ├── adminProblem.css │ │ └── adminProblem.less │ ├── bootstrap-theme.min.css │ ├── bootstrap.min.css │ ├── editProblem.css │ ├── editProblem.less │ ├── index.css │ ├── problems.css │ ├── status.css │ ├── status.less │ ├── style.css │ └── style.less └── test ├── routes ├── admin.js ├── index.js ├── login.js ├── problem.js ├── problems.js ├── status.js ├── submit.js └── users.js ├── utils └── stats.js └── views ├── admin.jade ├── admin ├── editProblems.jade ├── logs.jade ├── output.jade ├── problems.jade └── users.jade ├── error.jade ├── index.jade ├── index ├── left.jade └── right.jade ├── layout.jade ├── login.jade ├── login ├── register.jade └── success.jade ├── nav.jade ├── problem.jade ├── problems.jade ├── status.jade ├── status └── view.jade ├── submit.jade ├── submit └── success.jade └── v2 ├── index.jade ├── problem.jade └── utils ├── footer.jade └── nav.jade /.bin/jade: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Module dependencies. 5 | */ 6 | 7 | var fs = require('fs') 8 | , program = require('commander') 9 | , path = require('path') 10 | , basename = path.basename 11 | , dirname = path.dirname 12 | , resolve = path.resolve 13 | , exists = fs.existsSync || path.existsSync 14 | , join = path.join 15 | , monocle = require('monocle')() 16 | , mkdirp = require('mkdirp') 17 | , jade = require('../'); 18 | 19 | // jade options 20 | 21 | var options = {}; 22 | 23 | // options 24 | 25 | program 26 | .version(require('../package.json').version) 27 | .usage('[options] [dir|file ...]') 28 | .option('-O, --obj ', 'javascript options object') 29 | .option('-o, --out ', 'output the compiled html to ') 30 | .option('-p, --path ', 'filename used to resolve includes') 31 | .option('-P, --pretty', 'compile pretty html output') 32 | .option('-c, --client', 'compile function for client-side runtime.js') 33 | .option('-n, --name ', 'The name of the compiled template (requires --client)') 34 | .option('-D, --no-debug', 'compile without debugging (smaller functions)') 35 | .option('-w, --watch', 'watch files for changes and automatically re-render') 36 | .option('--name-after-file', 'Name the template after the last section of the file path (requires --client and overriden by --name)') 37 | 38 | 39 | program.on('--help', function(){ 40 | console.log(' Examples:'); 41 | console.log(''); 42 | console.log(' # translate jade the templates dir'); 43 | console.log(' $ jade templates'); 44 | console.log(''); 45 | console.log(' # create {foo,bar}.html'); 46 | console.log(' $ jade {foo,bar}.jade'); 47 | console.log(''); 48 | console.log(' # jade over stdio'); 49 | console.log(' $ jade < my.jade > my.html'); 50 | console.log(''); 51 | console.log(' # jade over stdio'); 52 | console.log(' $ echo \'h1 Jade!\' | jade'); 53 | console.log(''); 54 | console.log(' # foo, bar dirs rendering to /tmp'); 55 | console.log(' $ jade foo bar --out /tmp '); 56 | console.log(''); 57 | }); 58 | 59 | program.parse(process.argv); 60 | 61 | // options given, parse them 62 | 63 | if (program.obj) { 64 | if (exists(program.obj)) { 65 | options = JSON.parse(fs.readFileSync(program.obj)); 66 | } else { 67 | options = eval('(' + program.obj + ')'); 68 | } 69 | } 70 | 71 | // --filename 72 | 73 | if (program.path) options.filename = program.path; 74 | 75 | // --no-debug 76 | 77 | options.compileDebug = program.debug; 78 | 79 | // --client 80 | 81 | options.client = program.client; 82 | 83 | // --pretty 84 | 85 | options.pretty = program.pretty; 86 | 87 | // --watch 88 | 89 | options.watch = program.watch; 90 | 91 | // --name 92 | 93 | options.name = program.name; 94 | 95 | // left-over args are file paths 96 | 97 | var files = program.args; 98 | 99 | // compile files 100 | 101 | if (files.length) { 102 | console.log(); 103 | if (options.watch) { 104 | // keep watching when error occured. 105 | process.on('uncaughtException', function(err) { 106 | console.error(err); 107 | }); 108 | files.forEach(renderFile); 109 | monocle.watchFiles({ 110 | files: files, 111 | listener: function(file) { 112 | renderFile(file.absolutePath); 113 | } 114 | }); 115 | } else { 116 | files.forEach(renderFile); 117 | } 118 | process.on('exit', function () { 119 | console.log(); 120 | }); 121 | // stdio 122 | } else { 123 | stdin(); 124 | } 125 | 126 | /** 127 | * Compile from stdin. 128 | */ 129 | 130 | function stdin() { 131 | var buf = ''; 132 | process.stdin.setEncoding('utf8'); 133 | process.stdin.on('data', function(chunk){ buf += chunk; }); 134 | process.stdin.on('end', function(){ 135 | var output; 136 | if (options.client) { 137 | output = jade.compileClient(buf, options); 138 | } else { 139 | var fn = jade.compile(buf, options); 140 | var output = fn(options); 141 | } 142 | process.stdout.write(output); 143 | }).resume(); 144 | 145 | process.on('SIGINT', function() { 146 | process.stdout.write('\n'); 147 | process.stdin.emit('end'); 148 | process.stdout.write('\n'); 149 | process.exit(); 150 | }) 151 | } 152 | 153 | /** 154 | * Process the given path, compiling the jade files found. 155 | * Always walk the subdirectories. 156 | */ 157 | 158 | function renderFile(path) { 159 | var re = /\.jade$/; 160 | fs.lstat(path, function(err, stat) { 161 | if (err) throw err; 162 | // Found jade file 163 | if (stat.isFile() && re.test(path)) { 164 | fs.readFile(path, 'utf8', function(err, str){ 165 | if (err) throw err; 166 | options.filename = path; 167 | if (program.nameAfterFile) { 168 | options.name = getNameFromFileName(path); 169 | } 170 | var fn = options.client ? jade.compileClient(str, options) : jade.compile(str, options); 171 | var extname = options.client ? '.js' : '.html'; 172 | path = path.replace(re, extname); 173 | if (program.out) path = join(program.out, basename(path)); 174 | var dir = resolve(dirname(path)); 175 | mkdirp(dir, 0755, function(err){ 176 | if (err) throw err; 177 | try { 178 | var output = options.client ? fn : fn(options); 179 | fs.writeFile(path, output, function(err){ 180 | if (err) throw err; 181 | console.log(' \033[90mrendered \033[36m%s\033[0m', path); 182 | }); 183 | } catch (e) { 184 | if (options.watch) { 185 | console.error(e.stack || e.message || e); 186 | } else { 187 | throw e 188 | } 189 | } 190 | }); 191 | }); 192 | // Found directory 193 | } else if (stat.isDirectory()) { 194 | fs.readdir(path, function(err, files) { 195 | if (err) throw err; 196 | files.map(function(filename) { 197 | return path + '/' + filename; 198 | }).forEach(renderFile); 199 | }); 200 | } 201 | }); 202 | } 203 | 204 | /** 205 | * Get a sensible name for a template function from a file path 206 | * 207 | * @param {String} filename 208 | * @returns {String} 209 | */ 210 | function getNameFromFileName(filename) { 211 | var file = path.basename(filename, '.jade'); 212 | return file.toLowerCase().replace(/[^a-z0-9]+([a-z])/g, function (_, character) { 213 | return character.toUpperCase(); 214 | }) + 'Template'; 215 | } 216 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | cboj_conf.js 2 | *.swp 3 | *.DS_Store 4 | .DS_Store 5 | 6 | node_modules 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 jcpwfloi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OnlineJudge 2 | 3 | ## Installation 4 | You have to install Node.js first. 5 | 6 | For Mac OS: 7 | 8 | ``` 9 | brew install node 10 | ``` 11 | 12 | For Linux OS: 13 | 14 | ``` 15 | git clone https://github.com/joyent/node 16 | ./configure 17 | make 18 | make install 19 | ``` 20 | 21 | Then you have to Install the dependencies: 22 | ``` 23 | npm i 24 | ``` 25 | 26 | ## Database & Session Configuration 27 | 28 | ### Installing Redis 29 | git clone https://github.com/antirez/redis 30 | cd redis 31 | make 32 | make install 33 | 34 | The installation script will be released in the near future. 35 | 36 | ## Judger Configuration 37 | 38 | Place the script file in an folder, for example `/home/OJ/cboj`. You have to create a new folder under `/home/OJ`. 39 | 40 | ``` 41 | cd /home/OJ 42 | mkdir judger 43 | cd judger 44 | apt-get install -y makejail 45 | touch makejail.conf 46 | ``` 47 | 48 | You'll just have to write example programs under `/home/OJ/judger` 49 | 50 | 1.cpp: 51 | ``` 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | 65 | using namespace std; 66 | 67 | int main() { 68 | return 0; 69 | } 70 | ``` 71 | 72 | 1.pas: 73 | ``` 74 | program ex; 75 | uses math; 76 | var a: extended; 77 | begin 78 | readln(a); 79 | writeln(sqrt(a)); 80 | end. 81 | ``` 82 | 83 | 1.c: 84 | ``` 85 | #include 86 | #include 87 | 88 | int a, b; 89 | 90 | int main() { 91 | scanf("%d%d", &a, &b); 92 | printf("%d\n", a + b); 93 | } 94 | ``` 95 | 96 | 1.py: 97 | ``` 98 | import math 99 | a, b = raw_input().split() 100 | a, b = int(a), int(b) 101 | print a + b 102 | a = input() 103 | print math.sqrt(a) 104 | ``` 105 | 106 | Then you have to get prepared with the sandbox configuration, add this to the `makejail.conf`: 107 | 108 | ``` 109 | testCommandsInsideJail = ['g++ -o 1 1.cpp', 'gcc -o 1 1.cpp', 'fpc 1.pas', 'python 1.py'] 110 | ``` 111 | 112 | Then you can build the sandbox! 113 | 114 | ``` 115 | makejail makejail.conf 116 | ``` 117 | 118 | 119 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var session = require('express-session'); 3 | var path = require('path'); 4 | var favicon = require('serve-favicon'); 5 | var logger = require('morgan'); 6 | var cookieParser = require('cookie-parser'); 7 | var bodyParser = require('body-parser'); 8 | 9 | var routes = require('./routes/index'); 10 | var users = require('./routes/users'); 11 | var login = require('./routes/login'); 12 | var problem = require('./routes/problem'); 13 | var problems = require('./routes/problems'); 14 | var admin = require('./routes/admin'); 15 | var submit = require('./routes/submit'); 16 | var stats = require('./routes/status'); 17 | var RedisStore = require('connect-redis')(session); 18 | 19 | var app = express(); 20 | 21 | // view engine setup 22 | app.set('views', path.join(__dirname, 'views')); 23 | app.set('view engine', 'jade'); 24 | 25 | // session support 26 | app.use(cookieParser()); 27 | app.use(session({ 28 | resave: false, 29 | saveUninitialized: true, 30 | secret: 'rhfhgGG77488aguriuy2875', 31 | proxy: 'true', 32 | store: new RedisStore({ 33 | host: '901523a3e35211e4.m.cnhza.kvstore.aliyuncs.com', 34 | pass: '901523a3e35211e4:Czr88159080', 35 | port: '6379' 36 | }) 37 | /*store: new RedisStore({ 38 | host: 'localhost', 39 | port: '6379' 40 | })*/ 41 | /*store: require('sessionstore').createSessionStore({ 42 | type: 'redis', 43 | host: '901523a3e35211e4.m.cnhza.kvstore.aliyuncs.com', 44 | port: 6379, 45 | prefix: 'sess', 46 | ttl: 804600, 47 | timeout: 10000 48 | })*/ 49 | })); 50 | 51 | // uncomment after placing your favicon in /public 52 | //app.use(favicon(__dirname + '/public/favicon.ico')); 53 | app.use(logger('dev')); 54 | app.use(bodyParser.json()); 55 | app.use(bodyParser.urlencoded({ extended: false })); 56 | app.use(require('less-middleware')(path.join(__dirname, 'public'))); 57 | app.use(express.static(path.join(__dirname, 'public'))); 58 | 59 | app.use('/', routes); 60 | app.use('/users', users); 61 | app.use('/login', login); 62 | app.use('/problem', problem); 63 | app.use('/problems', problems); 64 | app.use('/admin', admin); 65 | app.use('/submit', submit); 66 | app.use('/status', stats); 67 | 68 | // catch 404 and forward to error handler 69 | app.use(function(req, res, next) { 70 | var err = new Error('Not Found'); 71 | err.status = 404; 72 | next(err); 73 | }); 74 | 75 | // error handlers 76 | 77 | // development error handler 78 | // will print stacktrace 79 | if (app.get('env') === 'development') { 80 | app.use(function(err, req, res, next) { 81 | res.status(err.status || 500); 82 | res.render('error', { 83 | message: err.message, 84 | error: err 85 | }); 86 | }); 87 | } 88 | 89 | // production error handler 90 | // no stacktraces leaked to user 91 | app.use(function(err, req, res, next) { 92 | res.status(err.status || 500); 93 | res.render('error', { 94 | message: err.message, 95 | error: {} 96 | }); 97 | }); 98 | 99 | 100 | module.exports = app; 101 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var debug = require('debug')('oj'); 3 | var app = require('../app'); 4 | 5 | app.set('port', process.env.PORT || 3000); 6 | 7 | var server = app.listen(app.get('port'), function() { 8 | debug('Express server listening on port ' + server.address().port); 9 | }); 10 | -------------------------------------------------------------------------------- /model/core.js: -------------------------------------------------------------------------------- 1 | var mongo = require('mongodb').MongoClient; 2 | 3 | function querySubmissionNum(callback) { 4 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 5 | db.collection('core', function(err, collection) { 6 | if (err) { 7 | callback(err, null); 8 | 9 | return; 10 | } 11 | collection.findOne({name: 'submissionTotal'}, function(err, doc) { 12 | 13 | if (doc && doc.value) 14 | callback(err, doc.value); 15 | else callback(err, null); 16 | }); 17 | }); 18 | }); 19 | } 20 | 21 | var parCnt; 22 | 23 | function par(callback, db) { 24 | ++ parCnt; 25 | if (parCnt == 2) { 26 | 27 | callback(); 28 | parCnt = 0; 29 | } 30 | } 31 | 32 | function addSubmission(submission, callback) { 33 | parCnt = 0; 34 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 35 | db.collection('submissions', function(err, collection) { 36 | if (err) { 37 | par(callback, db); 38 | return; 39 | } 40 | collection.insert(submission, function(err, doc) { 41 | par(callback, db); 42 | }); 43 | }); 44 | db.collection('core', function(err, collection) { 45 | if (err) { 46 | par(callback, db); 47 | return; 48 | } 49 | collection.update({name: 'submissionTotal'}, {$inc: {value: 1}}, function(err, doc) { 50 | par(callback, db); 51 | }); 52 | }); 53 | }); 54 | } 55 | 56 | exports.querySubmissionNum = querySubmissionNum; 57 | exports.addSubmission = addSubmission; 58 | 59 | -------------------------------------------------------------------------------- /model/dbquery.js: -------------------------------------------------------------------------------- 1 | var mongo = require('mongodb').MongoClient; 2 | 3 | function getUserByName(username, callback) { 4 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 5 | db.collection('users', function(err, collection) { 6 | if (err) { 7 | callback(err, null); 8 | 9 | return; 10 | } 11 | collection.findOne({name: username}, function(err, doc) { 12 | 13 | if (doc) callback(err, doc); 14 | else callback(err, null); 15 | }); 16 | }); 17 | }); 18 | } 19 | 20 | function updateUserByName(username, newuser, callback) { 21 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 22 | db.collection('users', function(err, collection) { 23 | if (err) { 24 | callback(err, null); 25 | 26 | return; 27 | } 28 | collection.update({name: username}, {$set: newuser}, function(err, doc) { 29 | }); 30 | 31 | if (doc) callback(err, doc); 32 | else callback(err, null); 33 | }); 34 | }); 35 | } 36 | 37 | function removeUserByName(username, callback) { 38 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 39 | db.collection('users', function(err, collection) { 40 | if (err) { 41 | callback(err, null); 42 | 43 | return; 44 | } 45 | collection.remove({name: username}, function(err, doc) { 46 | 47 | if (err) callback(err, null); 48 | else callback(err, doc); 49 | }); 50 | }); 51 | }); 52 | } 53 | 54 | function insertUser(newuser, callback) { 55 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 56 | db.collection('users', function(err, collection) { 57 | if (err) { 58 | callback(err, null); 59 | 60 | return; 61 | } 62 | collection.insert(newuser, function(err, doc) { 63 | 64 | if (err) callback(err, null); 65 | else callback(err, doc); 66 | }); 67 | }); 68 | }); 69 | } 70 | 71 | exports.getUserByName = getUserByName; 72 | exports.updateUserByName = updateUserByName; 73 | exports.removeUserByName = removeUserByName; 74 | exports.insertUser = insertUser; 75 | 76 | -------------------------------------------------------------------------------- /model/judger.js: -------------------------------------------------------------------------------- 1 | var mongo = require('mongodb').MongoClient; 2 | var Step = require('step'); 3 | var fs = require('fs'); 4 | var cp = require('child_process'); 5 | var utils = require('../utils/stats'); 6 | var problemId, filelist = [], child, timer, flag, id, result = [], score, startTime, endTime; 7 | var pathname, execpath, outpath, datapath, outpath, regin, regout, inputpath, anspath; 8 | 9 | function endwa(callback) { 10 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 11 | db.collection('submissions', function(err, collection) { 12 | collection.update({submissionId: id}, {$set: {status: 1}}, function(err, doc) { 13 | db.collection('core', function(err, collection) { 14 | collection.update({name: 'completedTotal'}, {$inc: {value: 1}}, function(err, doc) { 15 | 16 | callback(); 17 | }); 18 | }); 19 | }); 20 | }); 21 | }); 22 | } 23 | 24 | function endre(callback) { 25 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 26 | db.collection('submissions', function(err, collection) { 27 | collection.update({submissionId: id}, {$set: {status: 3}}, function(err, doc) { 28 | db.collection('core', function(err, collection) { 29 | collection.update({name: 'completedTotal'}, {$inc: {value: 1}}, function(err, doc) { 30 | 31 | callback(); 32 | }); 33 | }); 34 | }); 35 | }); 36 | }); 37 | } 38 | 39 | function endtle(callback) { 40 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 41 | db.collection('submissions', function(err, collection) { 42 | collection.update({submissionId: id}, {$set: {status: 2}}, function(err, doc) { 43 | db.collection('core', function(err, collection) { 44 | collection.update({name: 'completedTotal'}, {$inc: {value: 1}}, function(err, doc) { 45 | 46 | callback(); 47 | }); 48 | }); 49 | }); 50 | }); 51 | }); 52 | } 53 | 54 | function endce(callback) { 55 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 56 | db.collection('submissions', function(err, collection) { 57 | collection.update({submissionId: id}, {$set: {status: 4}}, function(err, doc) { 58 | db.collection('core', function(err, collection) { 59 | collection.update({name: 'completedTotal'}, {$inc: {value: 1}}, function(err, doc) { 60 | 61 | callback(); 62 | }); 63 | }); 64 | }); 65 | }); 66 | }); 67 | } 68 | 69 | function endac(callback) { 70 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 71 | db.collection('submissions', function(err, collection) { 72 | collection.update({submissionId: id}, {$set: {status: 0}}, function(err, doc) { 73 | db.collection('core', function(err, collection) { 74 | collection.update({name: 'completedTotal'}, {$inc: {value: 1}}, function(err, doc) { 75 | 76 | callback(); 77 | }); 78 | }); 79 | }); 80 | }); 81 | }); 82 | } 83 | 84 | function getCompletedTotal(callback) { 85 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 86 | db.collection('core', function(err, collection) { 87 | if (err) { 88 | callback(err, null); 89 | 90 | return; 91 | } 92 | collection.findOne({name: 'completedTotal'}, function(err, doc) { 93 | 94 | if (doc) callback(err, doc); 95 | else callback(err, null); 96 | }); 97 | }); 98 | }); 99 | } 100 | 101 | function getSubmissionTotal(callback) { 102 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 103 | db.collection('core', function(err, collection) { 104 | if (err) { 105 | callback(err, null); 106 | return; 107 | } 108 | collection.findOne({name: 'submissionTotal'}, function(err, doc) { 109 | if (doc) callback(err, doc); 110 | else callback(err, null); 111 | }); 112 | }); 113 | }); 114 | } 115 | 116 | function getSubmission(submissionId, callback) { 117 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 118 | db.collection('submissions', function(err, collection) { 119 | if (err) { 120 | callback(err, null); 121 | return; 122 | } 123 | collection.findOne({submissionId: submissionId}, function(err, doc) { 124 | 125 | if (doc) callback(err, doc); 126 | else callback(err, null); 127 | }); 128 | }); 129 | }); 130 | } 131 | 132 | function endProgram() { 133 | cp.exec('rm -f ' + __dirname + '/../../judger/judge.lock ' + __dirname + '/../../judger/code.exe ' + __dirname + '/../../judger/code.cpp ' + __dirname + '/../../judger/code.pas ' + __dirname + '/../../judger/tempout', function(err, stdout, stderr) { 134 | }); 135 | } 136 | 137 | function doJudge() { 138 | Step( 139 | function() { 140 | utils.exec(); 141 | this(); 142 | }, 143 | function() { 144 | cp.exec('touch ' + __dirname + '/../../judger/judge.lock', this); 145 | }, 146 | function(err, stdout, stderr) { 147 | getCompletedTotal(this.parallel()); 148 | getSubmissionTotal(this.parallel()); 149 | }, 150 | function(err1, doc1, doc2) { 151 | if (doc1.value >= doc2.value) endProgram(); 152 | else { 153 | id = doc1.value + 1; 154 | //getSubmission(id, this); 155 | var shit = this; 156 | getSubmission(id, function(err, doc) { 157 | mongo.connect('mongodb://localhost/cboj', function(err3, db) { 158 | db.collection('submissions', function(err2, collection) { 159 | collection.update({submissionId: id}, {$set: {status: 5}}, function(err1, res) { 160 | shit(err, doc); 161 | }); 162 | }); 163 | }); 164 | }); 165 | } 166 | }, 167 | function(err, doc) { 168 | var shit = this; 169 | problemId = doc.problemId; 170 | flag = true; 171 | if (doc.language == 0) { //cpp 172 | pathname = __dirname + '/../../judger/code.cpp'; 173 | execpath = __dirname + '/../../judger/code.exe'; 174 | Step( 175 | function() { 176 | fs.writeFile(pathname, doc.code, this); 177 | }, 178 | function() { 179 | cp.exec('g++ -o ' + execpath + ' ' + pathname + ' -DONLINE_JUDGE -lm', {timeout: 5000}, this) 180 | }, 181 | function(err, stdout, stderr) { 182 | var werr = err; 183 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 184 | db.collection('submissions', function(err, collection) { 185 | collection.update({submissionId: id}, {$set: {compilerMessage: stderr}}, function(err, doc) { 186 | 187 | if (werr) { 188 | werr = null; 189 | endce(function() { 190 | doJudge(); 191 | }); 192 | } else shit(); 193 | }); 194 | }); 195 | }); 196 | } 197 | ); 198 | } else if (doc.language == 1) { //pas 199 | pathname = __dirname + '/../../judger/code.pas'; 200 | execpath = __dirname + '/../../judger/code.exe'; 201 | Step( 202 | function() { 203 | fs.writeFile(pathname, doc.code, this); 204 | }, 205 | function() { 206 | cp.exec('fpc -o' + execpath + ' ' + pathname, {timeout: 5000}, this); 207 | }, 208 | function(err, stdout, stderr) { 209 | var werr = err; 210 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 211 | db.collection('submissions', function(err, collection) { 212 | collection.update({submissionId: id}, {$set: {compilerMessage: stdout}}, function(err, doc) { 213 | 214 | if (werr) { 215 | endce(function() { 216 | doJudge(); 217 | }); 218 | } else shit(); 219 | }); 220 | }); 221 | }); 222 | } 223 | ); 224 | } else if (doc.language == 2) { 225 | execpath = __dirname + '/../../judger/code.exe'; 226 | Step( 227 | function() { 228 | doc.code = '#!/usr/bin/python\n' + doc.code; 229 | fs.writeFile(execpath, doc.code, this); 230 | }, function() { 231 | cp.exec('chmod +x ' + execpath, this); 232 | }, function(err, stdout, stderr) { 233 | shit(); 234 | } 235 | ); 236 | } else if (doc.language == 3) { 237 | pathname = __dirname + '/../../judger/code.cpp'; 238 | execpath = __dirname + '/../../judger/code.exe'; 239 | Step( 240 | function() { 241 | fs.writeFile(pathname, doc.code, this); 242 | }, 243 | function() { 244 | cp.exec('g++ -o ' + execpath + ' ' + pathname + ' -DONLINE_JUDGE -lm -std=c++11', {timeout: 5000}, this) 245 | }, 246 | function(err, stdout, stderr) { 247 | var werr = err; 248 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 249 | db.collection('submissions', function(err, collection) { 250 | collection.update({submissionId: id}, {$set: {compilerMessage: stderr}}, function(err, doc) { 251 | 252 | if (werr) { 253 | werr = null; 254 | endce(function() { 255 | doJudge(); 256 | }); 257 | } else shit(); 258 | }); 259 | }); 260 | }); 261 | } 262 | ); 263 | } else if (doc.language == 4) { 264 | execpath = __dirname + '/../../judger/code.exe'; 265 | Step( 266 | function() { 267 | doc.code = '#!/usr/local/bin/node\n' + doc.code; 268 | fs.writeFile(execpath, doc.code, this); 269 | }, function() { 270 | cp.exec('chmod +x ' + execpath, this); 271 | }, function(err, stdout, stderr) { 272 | shit(); 273 | } 274 | ); 275 | } else { 276 | endce(function() { 277 | doJudge(); 278 | }); 279 | } 280 | }, 281 | function() { 282 | datapath = __dirname + '/../../judger/data/' + String(problemId) + '/'; 283 | var files = fs.readdirSync(datapath); 284 | regin = /\.in/, regout = /\.out/; 285 | var name; 286 | filelist = []; 287 | for (var i = 0; i < files.length; ++ i) { 288 | name = files[i]; 289 | if (regin.test(name)) { 290 | name = name.replace(regin, ''); 291 | if (files.indexOf(name + '.out') != -1) filelist.push(name); 292 | } 293 | } 294 | files = null; 295 | this(); 296 | }, 297 | function() { 298 | /*old version 299 | var execpath = __dirname + '/../../judger/code.exe'; 300 | var outpath = __dirname + '/../../judger/tempout'; 301 | var datapath = __dirname + '/../../judger/data/' + String(problemId) + '/'; 302 | */ 303 | execpath = 'chroot /root/oj/judger ./code.exe'; 304 | datapath = __dirname + '/../../judger/data/' + String(problemId) + '/'; 305 | outpath = __dirname + '/../../judger/tempout'; 306 | result = []; 307 | var shit = this; 308 | startTime = new Date().getTime(); 309 | function run(i) { 310 | if (i >= filelist.length) { 311 | shit(); 312 | return; 313 | } else { 314 | inputpath = datapath + filelist[i] + '.in'; 315 | anspath = datapath + filelist[i] + '.out'; 316 | Step( 317 | function() { 318 | child = cp.exec(execpath + ' < ' + inputpath + ' > ' + outpath, {timeout: 2000, maxBuffer: 200*1024*1024, killSignal: 'SIGKILL'}, this); 319 | }, 320 | function(err, stdout, stderr) { 321 | if (err && err.killed && err.signal == 'SIGKILL') { 322 | cp.exec('killall code.exe', function() { 323 | result.push(2); 324 | run(i + 1);}); 325 | return; 326 | } else if (err && !err.killed && err.signal != 'SIGKILL') { 327 | result.push(3); 328 | run(i + 1); 329 | return; 330 | } else { 331 | this(); 332 | } 333 | }, function() { 334 | cp.exec('diff -w -B -q ' + outpath + ' ' + anspath, this); 335 | }, function(err, stdout, stderr) { 336 | if (!err) { 337 | result.push(0); 338 | run(i + 1); 339 | return; 340 | } else { 341 | result.push(1); 342 | run(i + 1); 343 | return; 344 | } 345 | } 346 | ); 347 | } 348 | } 349 | run(0); 350 | }, 351 | function() { 352 | endTime = new Date().getTime(); 353 | var shit = this; 354 | var correctNum = 0; 355 | for (var i = 0; i < result.length; ++ i) { 356 | if (!result[i]) ++ correctNum; 357 | } 358 | if (result.length) score = Math.round(correctNum * 100 / result.length); 359 | else score = 0; 360 | if (score == 100) endac(shit); 361 | else { 362 | var tempnum = 0; 363 | for (var i = 0; i < result.length; ++ i) 364 | if (result[i]) { 365 | tempnum = result[i]; 366 | break; 367 | } 368 | if (tempnum == 1) { 369 | endwa(shit); 370 | } else if (tempnum == 2) { 371 | endtle(shit); 372 | } else if (tempnum == 3) { 373 | endre(shit); 374 | } else { 375 | endwa(shit); 376 | } 377 | } 378 | }, 379 | function() { 380 | giveResult(result, score, this); 381 | }, 382 | function() { 383 | doJudge(); 384 | } 385 | ); 386 | } 387 | 388 | function giveResult(result, score, callback) { 389 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 390 | db.collection('submissions', function(err, collection) { 391 | collection.update({submissionId: id}, {$set: {result: result, score: score, usedTime: endTime - startTime}}, function(err, doc) { 392 | 393 | callback(); 394 | }); 395 | }); 396 | }); 397 | } 398 | 399 | exports.doJudge = doJudge; 400 | exports.getSubmission = getSubmission; 401 | 402 | -------------------------------------------------------------------------------- /model/problem.js: -------------------------------------------------------------------------------- 1 | var mongo = require('mongodb').MongoClient; 2 | 3 | function fetchProblems(from, num, callback) { 4 | from += 1000; 5 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 6 | db.collection('problems', function(err, collection) { 7 | if (err) { 8 | callback(err, null); 9 | return; 10 | } 11 | collection.find({id: {$gte: from, $lt: from + num}, inprivate: {$ne: 1}}, {sort: {id: 1}}, function(err, doc) { 12 | 13 | if (err) { 14 | callback(err, null); 15 | return; 16 | } 17 | doc.toArray(function(err, arr) { 18 | if (err) callback(err, null); 19 | callback(err, arr); 20 | }); 21 | }); 22 | }); 23 | }); 24 | } 25 | 26 | function updateProblems(problemId, newProblem, callback) { 27 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 28 | db.collection('problems', function(err, collection) { 29 | if (err) { 30 | callback(); 31 | return; 32 | } 33 | collection.update({id: problemId}, {$set: newProblem}, function(err, doc) { 34 | 35 | callback(); 36 | }); 37 | }); 38 | }); 39 | } 40 | 41 | exports.fetchProblems = fetchProblems; 42 | exports.updateProblems = updateProblems; 43 | 44 | -------------------------------------------------------------------------------- /model/problems.js: -------------------------------------------------------------------------------- 1 | var mongo = require('mongodb').MongoClient; 2 | var Step = require('step'); 3 | 4 | function fetchProblem(id, callback) { 5 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 6 | db.collection('problem', function(err, collection) { 7 | if (err) { 8 | callback(err, null); 9 | return; 10 | } 11 | collection.findOne({id: id}, function(err, doc) { 12 | if (err) { 13 | callback(err, null); 14 | return; 15 | } 16 | callback(err, doc); 17 | }); 18 | }); 19 | }); 20 | } 21 | 22 | function updateProblem(problemId, newProblem, callback) { 23 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 24 | db.collection('problem', function(err, collection) { 25 | if (err) { 26 | callback(); 27 | return; 28 | } 29 | collection.update({id: problemId}, {$set: newProblem}, function(err, doc) { 30 | callback(); 31 | }); 32 | }); 33 | }); 34 | } 35 | 36 | function addProblem(newProblem, callback) { 37 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 38 | Step( 39 | function() { 40 | db.collection('core', this) 41 | }, 42 | function(err, collection) { 43 | collection.findOne({name: 'problemTotal'}, this); 44 | }, 45 | function(err, doc) { 46 | newProblem.id = doc.value + 1; 47 | this(); 48 | }, 49 | function() { 50 | db.collection('core', this); 51 | }, 52 | function(err, collection) { 53 | collection.update({name: 'problemTotal'}, {$inc: {value: 1}}, this); 54 | }, 55 | function(err, doc) { 56 | this(); 57 | }, 58 | function() { 59 | db.collection('problem', this); 60 | }, 61 | function(err, collection) { 62 | collection.insert(newProblem, this); 63 | }, 64 | function(err, doc) { 65 | db.collection('problems', this); 66 | }, 67 | function(err, collection) { 68 | var problems = { 69 | id: newProblem.id, 70 | name: newProblem.name, 71 | ac: 0, 72 | all: 0, 73 | avail: false 74 | }; 75 | collection.insert(problems, this); 76 | }, 77 | function(err, doc) { 78 | callback(); 79 | } 80 | ); 81 | }); 82 | } 83 | 84 | exports.fetchProblem = fetchProblem; 85 | exports.updateProblem = updateProblem; 86 | exports.addProblem = addProblem; 87 | 88 | -------------------------------------------------------------------------------- /model/submission.js: -------------------------------------------------------------------------------- 1 | var mongo = require('mongodb').MongoClient; 2 | 3 | function getstats(page, callback) { 4 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 5 | db.collection('submissions', function(err, collection) { 6 | if (err) return; 7 | collection.find({}, {sort: {submissionId: -1}, limit: 50, skip: (page - 1) * 50}, function(err, doc) { 8 | if (err) return; 9 | doc.toArray(function(err, arr) { 10 | callback(arr); 11 | }); 12 | }); 13 | }); 14 | }); 15 | } 16 | 17 | function getprob(problemId, callback) { 18 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 19 | db.collection('submissions', function(err, collection) { 20 | if (err) return; 21 | collection.find({problemId: problemId, "status": 0}, {sort: {submissionId: -1}, limit: 50}, function(err, doc) { 22 | if (err) return; 23 | doc.toArray(function(err, arr) { 24 | callback(arr); 25 | }); 26 | }); 27 | }); 28 | }); 29 | } 30 | 31 | function getProbByUser(userId, callback) { 32 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 33 | db.collection('submissions', function(err, collection) { 34 | if (err) return; 35 | collection.find({user: userId}, {sort: {submissionId: -1}, limit: 50}, function(err, doc) { 36 | if (err) return; 37 | doc.toArray(function(err, arr) { 38 | callback(arr); 39 | }); 40 | }); 41 | }); 42 | }); 43 | } 44 | 45 | exports.getstats = getstats; 46 | exports.getprob = getprob; 47 | exports.getProbByUser = getProbByUser; 48 | 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "oj", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "node ./bin/www" 7 | }, 8 | "dependencies": { 9 | "JSON": "^1.0.0", 10 | "body-parser": "~1.8.1", 11 | "connect-redis": "^2.2.0", 12 | "cookie-parser": "~1.3.3", 13 | "debug": "~2.0.0", 14 | "express": "~4.9.0", 15 | "express-session": "^1.9.1", 16 | "jade": "~1.6.0", 17 | "less-middleware": "1.0.x", 18 | "marked": "^0.3.3", 19 | "mongodb": "^1.4.20", 20 | "morgan": "~1.3.0", 21 | "serve-favicon": "~2.1.3", 22 | "step": "0.0.5" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /public/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Attribution 3.0 Unported 2 | http://creativecommons.org/licenses/by/3.0/ 3 | 4 | License 5 | 6 | THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. 7 | 8 | BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. 9 | 10 | 1. Definitions 11 | 12 | 1. "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. 13 | 2. "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License. 14 | 3. "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. 15 | 4. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. 16 | 5. "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. 17 | 6. "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. 18 | 7. "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. 19 | 8. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. 20 | 9. "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. 21 | 22 | 2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. 23 | 24 | 3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: 25 | 26 | 1. to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; 27 | 2. to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; 28 | 3. to Distribute and Publicly Perform the Work including as incorporated in Collections; and, 29 | 4. to Distribute and Publicly Perform Adaptations. 30 | 5. 31 | 32 | For the avoidance of doubt: 33 | 1. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; 34 | 2. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and, 35 | 3. Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License. 36 | 37 | The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved. 38 | 39 | 4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: 40 | 41 | 1. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(b), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(b), as requested. 42 | 2. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4 (b) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. 43 | 3. Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. 44 | 45 | 5. Representations, Warranties and Disclaimer 46 | 47 | UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. 48 | 49 | 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 50 | 51 | 7. Termination 52 | 53 | 1. This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. 54 | 2. Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. 55 | 56 | 8. Miscellaneous 57 | 58 | 1. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. 59 | 2. Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. 60 | 3. If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. 61 | 4. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. 62 | 5. This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. 63 | 6. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. 64 | -------------------------------------------------------------------------------- /public/css/skel.css: -------------------------------------------------------------------------------- 1 | /* Resets (http://meyerweb.com/eric/tools/css/reset/ | v2.0 | 20110126 | License: none (public domain)) */ 2 | 3 | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline;}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block;}body{line-height:1;}ol,ul{list-style:none;}blockquote,q{quotes:none;}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;}table{border-collapse:collapse;border-spacing:0;}body{-webkit-text-size-adjust:none} 4 | 5 | /* Box Model */ 6 | 7 | *, *:before, *:after { 8 | -moz-box-sizing: border-box; 9 | -webkit-box-sizing: border-box; 10 | box-sizing: border-box; 11 | } 12 | 13 | /* Container */ 14 | 15 | .container { 16 | margin-left: auto; 17 | margin-right: auto; 18 | 19 | /* width: (containers) */ 20 | width: 1200px; 21 | } 22 | 23 | /* Modifiers */ 24 | 25 | /* 125% */ 26 | .container.\31 25\25 { 27 | width: 100%; 28 | 29 | /* max-width: (containers * 1.25) */ 30 | max-width: 1500px; 31 | 32 | /* min-width: (containers) */ 33 | min-width: 1200px; 34 | } 35 | 36 | /* 75% */ 37 | .container.\37 5\25 { 38 | 39 | /* width: (containers * 0.75) */ 40 | width: 900px; 41 | 42 | } 43 | 44 | /* 50% */ 45 | .container.\35 0\25 { 46 | 47 | /* width: (containers * 0.50) */ 48 | width: 600px; 49 | 50 | } 51 | 52 | /* 25% */ 53 | .container.\32 5\25 { 54 | 55 | /* width: (containers * 0.25) */ 56 | width: 300px; 57 | 58 | } 59 | 60 | /* Grid */ 61 | 62 | .row { 63 | border-bottom: solid 1px transparent; 64 | } 65 | 66 | .row > * { 67 | float: left; 68 | } 69 | 70 | .row:after, .row:before { 71 | content: ''; 72 | display: block; 73 | clear: both; 74 | height: 0; 75 | } 76 | 77 | .row.uniform > * > :first-child { 78 | margin-top: 0; 79 | } 80 | 81 | .row.uniform > * > :last-child { 82 | margin-bottom: 0; 83 | } 84 | 85 | /* Gutters */ 86 | 87 | /* Normal */ 88 | 89 | .row > * { 90 | /* padding: (gutters.horizontal) 0 0 (gutters.vertical) */ 91 | padding: 0 0 0 2em; 92 | } 93 | 94 | .row { 95 | /* margin: -(gutters.horizontal) 0 -1px -(gutters.vertical) */ 96 | margin: 0 0 -1px -2em; 97 | } 98 | 99 | .row.uniform > * { 100 | /* padding: (gutters.vertical) 0 0 (gutters.vertical) */ 101 | padding: 2em 0 0 2em; 102 | } 103 | 104 | .row.uniform { 105 | /* margin: -(gutters.vertical) 0 -1px -(gutters.vertical) */ 106 | margin: -2em 0 -1px -2em; 107 | } 108 | 109 | /* 200% */ 110 | 111 | .row.\32 00\25 > * { 112 | /* padding: (gutters.horizontal) 0 0 (gutters.vertical) */ 113 | padding: 0 0 0 4em; 114 | } 115 | 116 | .row.\32 00\25 { 117 | /* margin: -(gutters.horizontal) 0 -1px -(gutters.vertical) */ 118 | margin: 0 0 -1px -4em; 119 | } 120 | 121 | .row.uniform.\32 00\25 > * { 122 | /* padding: (gutters.vertical) 0 0 (gutters.vertical) */ 123 | padding: 4em 0 0 4em; 124 | } 125 | 126 | .row.uniform.\32 00\25 { 127 | /* margin: -(gutters.vertical) 0 -1px -(gutters.vertical) */ 128 | margin: -4em 0 -1px -4em; 129 | } 130 | 131 | /* 150% */ 132 | 133 | .row.\31 50\25 > * { 134 | /* padding: (gutters.horizontal) 0 0 (gutters.vertical) */ 135 | padding: 0 0 0 1.5em; 136 | } 137 | 138 | .row.\31 50\25 { 139 | /* margin: -(gutters.horizontal) 0 -1px -(gutters.vertical) */ 140 | margin: 0 0 -1px -1.5em; 141 | } 142 | 143 | .row.uniform.\31 50\25 > * { 144 | /* padding: (gutters.vertical) 0 0 (gutters.vertical) */ 145 | padding: 1.5em 0 0 1.5em; 146 | } 147 | 148 | .row.uniform.\31 50\25 { 149 | /* margin: -(gutters.vertical) 0 -1px -(gutters.vertical) */ 150 | margin: -1.5em 0 -1px -1.5em; 151 | } 152 | 153 | /* 50% */ 154 | 155 | .row.\35 0\25 > * { 156 | /* padding: (gutters.horizontal) 0 0 (gutters.vertical) */ 157 | padding: 0 0 0 1em; 158 | } 159 | 160 | .row.\35 0\25 { 161 | /* margin: -(gutters.horizontal) 0 -1px -(gutters.vertical) */ 162 | margin: 0 0 -1px -1em; 163 | } 164 | 165 | .row.uniform.\35 0\25 > * { 166 | /* padding: (gutters.vertical) 0 0 (gutters.vertical) */ 167 | padding: 1em 0 0 1em; 168 | } 169 | 170 | .row.uniform.\35 0\25 { 171 | /* margin: -(gutters.vertical) 0 -1px -(gutters.vertical) */ 172 | margin: -1em 0 -1px -1em; 173 | } 174 | 175 | /* 25% */ 176 | 177 | .row.\32 5\25 > * { 178 | /* padding: (gutters.horizontal) 0 0 (gutters.vertical) */ 179 | padding: 0 0 0 0.5em; 180 | } 181 | 182 | .row.\32 5\25 { 183 | /* margin: -(gutters.horizontal) 0 -1px -(gutters.vertical) */ 184 | margin: 0 0 -1px -0.5em; 185 | } 186 | 187 | .row.uniform.\32 5\25 > * { 188 | /* padding: (gutters.vertical) 0 0 (gutters.vertical) */ 189 | padding: 0.5em 0 0 0.5em; 190 | } 191 | 192 | .row.uniform.\32 5\25 { 193 | /* margin: -(gutters.vertical) 0 -1px -(gutters.vertical) */ 194 | margin: -0.5em 0 -1px -0.5em; 195 | } 196 | 197 | /* 0% */ 198 | 199 | .row.\30 \25 > * { 200 | padding: 0; 201 | } 202 | 203 | .row.\30 \25 { 204 | margin: 0 0 -1px 0; 205 | } 206 | 207 | /* Cells */ 208 | 209 | .\31 2u, .\31 2u\24 { width: 100%; clear: none; margin-left: 0; } 210 | .\31 1u, .\31 1u\24 { width: 91.6666666667%; clear: none; margin-left: 0; } 211 | .\31 0u, .\31 0u\24 { width: 83.3333333333%; clear: none; margin-left: 0; } 212 | .\39 u, .\39 u\24 { width: 75%; clear: none; margin-left: 0; } 213 | .\38 u, .\38 u\24 { width: 66.6666666667%; clear: none; margin-left: 0; } 214 | .\37 u, .\37 u\24 { width: 58.3333333333%; clear: none; margin-left: 0; } 215 | .\36 u, .\36 u\24 { width: 50%; clear: none; margin-left: 0; } 216 | .\35 u, .\35 u\24 { width: 41.6666666667%; clear: none; margin-left: 0; } 217 | .\34 u, .\34 u\24 { width: 33.3333333333%; clear: none; margin-left: 0; } 218 | .\33 u, .\33 u\24 { width: 25%; clear: none; margin-left: 0; } 219 | .\32 u, .\32 u\24 { width: 16.6666666667%; clear: none; margin-left: 0; } 220 | .\31 u, .\31 u\24 { width: 8.3333333333%; clear: none; margin-left: 0; } 221 | 222 | .\31 2u\24 + *, 223 | .\31 1u\24 + *, 224 | .\31 0u\24 + *, 225 | .\39 u\24 + *, 226 | .\38 u\24 + *, 227 | .\37 u\24 + *, 228 | .\36 u\24 + *, 229 | .\35 u\24 + *, 230 | .\34 u\24 + *, 231 | .\33 u\24 + *, 232 | .\32 u\24 + *, 233 | .\31 u\24 + * { 234 | clear: left; 235 | } 236 | 237 | .\-11u { margin-left: 91.6666666667% } 238 | .\-10u { margin-left: 83.3333333333% } 239 | .\-9u { margin-left: 75% } 240 | .\-8u { margin-left: 66.6666666667% } 241 | .\-7u { margin-left: 58.3333333333% } 242 | .\-6u { margin-left: 50% } 243 | .\-5u { margin-left: 41.6666666667% } 244 | .\-4u { margin-left: 33.3333333333% } 245 | .\-3u { margin-left: 25% } 246 | .\-2u { margin-left: 16.6666666667% } 247 | .\-1u { margin-left: 8.3333333333% } -------------------------------------------------------------------------------- /public/css/style-large.css: -------------------------------------------------------------------------------- 1 | /* 2 | Transit by TEMPLATED 3 | templated.co @templatedco 4 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 5 | */ -------------------------------------------------------------------------------- /public/css/style-medium.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /* 4 | Transit by TEMPLATED 5 | templated.co @templatedco 6 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 7 | */ 8 | 9 | /* Basic */ 10 | 11 | body, input, select, textarea { 12 | font-size: 12pt; 13 | } 14 | 15 | header.major h2 { 16 | font-size: 2.25em; 17 | } 18 | 19 | header.major p { 20 | font-size: 1.25em; 21 | } 22 | 23 | /* Header */ 24 | 25 | #skel-layers-wrapper { 26 | padding-top: 0; 27 | } 28 | 29 | #header { 30 | display: none; 31 | } 32 | 33 | /* Banner */ 34 | 35 | #banner { 36 | padding: 6em 0em 6em; 37 | } 38 | 39 | #banner h2 { 40 | font-size: 2.25em; 41 | } 42 | 43 | #banner p { 44 | font-size: 1.25em; 45 | } 46 | 47 | /* Layers */ 48 | 49 | #navButton .toggle { 50 | text-decoration: none; 51 | height: 100%; 52 | left: 0; 53 | position: absolute; 54 | top: 0; 55 | width: 100%; 56 | } 57 | 58 | #navButton .toggle:before { 59 | content: ""; 60 | -moz-osx-font-smoothing: grayscale; 61 | -webkit-font-smoothing: antialiased; 62 | font-family: FontAwesome; 63 | font-style: normal; 64 | font-weight: normal; 65 | text-transform: none !important; 66 | } 67 | 68 | #navButton .toggle:before { 69 | background: rgba(144, 144, 144, 0.65); 70 | border-radius: 4px; 71 | color: #fff; 72 | display: block; 73 | font-size: 16px; 74 | height: 2.25em; 75 | left: 0.5em; 76 | line-height: 2.25em; 77 | position: absolute; 78 | text-align: center; 79 | top: 0.5em; 80 | width: 3.5em; 81 | } 82 | 83 | #navPanel { 84 | background: rgba(255, 255, 255, 0.975); 85 | color: #444; 86 | border-right: solid 1px rgba(144, 144, 144, 0.25); 87 | box-shadow: 0.5em 0 2em 0 rgba(0, 0, 0, 0.125); 88 | } 89 | 90 | #navPanel nav { 91 | padding: 0.5em 1.25em; 92 | } 93 | 94 | #navPanel nav ul { 95 | list-style: none; 96 | margin: 0; 97 | padding: 0; 98 | } 99 | 100 | #navPanel nav ul li { 101 | padding: 0; 102 | } 103 | 104 | #navPanel nav ul li:first-child a:not(.button), #navPanel nav ul li:first-child span:not(.button) { 105 | border-top: 0; 106 | } 107 | 108 | #navPanel nav ul li a.button, #navPanel nav ul li span.button { 109 | margin-top: 0.5em; 110 | } 111 | 112 | #navPanel nav ul li a:not(.button), #navPanel nav ul li span:not(.button) { 113 | border-top: 1px solid rgba(0, 0, 0, 0.125); 114 | display: block; 115 | padding: 0.75em 0; 116 | text-decoration: none; 117 | } 118 | 119 | #navPanel nav .button { 120 | width: 100%; 121 | } 122 | 123 | /* Footer */ 124 | 125 | #footer .copyright { 126 | margin-top: 0; 127 | text-align: center; 128 | } 129 | 130 | #footer .icons { 131 | text-align: center; 132 | } -------------------------------------------------------------------------------- /public/css/style-small.css: -------------------------------------------------------------------------------- 1 | /* 2 | Transit by TEMPLATED 3 | templated.co @templatedco 4 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 12pt; 11 | } 12 | 13 | /* Banner */ 14 | 15 | #banner { 16 | padding: 8em 2em 8em; 17 | } 18 | 19 | /* Wrapper */ 20 | 21 | .wrapper { 22 | padding: 4em 0em 2em; 23 | /* Style 2 Wrapper */ 24 | } 25 | 26 | .wrapper.style2 footer { 27 | width: 85%; 28 | } 29 | 30 | /* Footer */ 31 | 32 | #footer { 33 | padding: 4em 0em 2em; 34 | } 35 | 36 | #footer .copyright li { 37 | border-left: 0; 38 | margin-left: 0; 39 | padding-left: 0; 40 | display: block; 41 | } -------------------------------------------------------------------------------- /public/css/style-xlarge.css: -------------------------------------------------------------------------------- 1 | /* 2 | Transit by TEMPLATED 3 | templated.co @templatedco 4 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | body, input, select, textarea { 10 | font-size: 11pt; 11 | } -------------------------------------------------------------------------------- /public/css/style-xsmall.css: -------------------------------------------------------------------------------- 1 | /* 2 | Transit by TEMPLATED 3 | templated.co @templatedco 4 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 5 | */ 6 | 7 | /* Basic */ 8 | 9 | html, body { 10 | min-width: 320px; 11 | } 12 | 13 | body, input, select, textarea { 14 | font-size: 12pt; 15 | } 16 | 17 | header.major h2 { 18 | font-size: 2em; 19 | margin-bottom: 1em; 20 | } 21 | 22 | /* List */ 23 | 24 | ul.actions { 25 | margin: 0 0 2em 0; 26 | } 27 | 28 | ul.actions li { 29 | padding: 1em 0 0 0; 30 | display: block; 31 | text-align: center; 32 | width: 100%; 33 | } 34 | 35 | ul.actions li:first-child { 36 | padding-top: 0; 37 | } 38 | 39 | ul.actions li > * { 40 | width: 100%; 41 | margin: 0 !important; 42 | } 43 | 44 | ul.actions li > *.icon:before { 45 | margin-left: -2em; 46 | } 47 | 48 | ul.actions.small li { 49 | padding: 0.5em 0 0 0; 50 | } 51 | 52 | ul.actions.small li:first-child { 53 | padding-top: 0; 54 | } 55 | 56 | /* Button */ 57 | 58 | input[type="submit"], 59 | input[type="reset"], 60 | input[type="button"], 61 | .button { 62 | padding: 0; 63 | } 64 | 65 | /* Banner */ 66 | 67 | #banner { 68 | padding: 8em 2em 8em; 69 | } -------------------------------------------------------------------------------- /public/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /public/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /public/generic.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | Generic - Transit by TEMPLATED 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 |
42 |
43 | 44 |
45 |

Generic

46 |

Lorem ipsum dolor sit amet nullam id egestas urna aliquam

47 |
48 | 49 | 50 |

Vis accumsan feugiat adipiscing nisl amet adipiscing accumsan blandit accumsan sapien blandit ac amet faucibus aliquet placerat commodo. Interdum ante aliquet commodo accumsan vis phasellus adipiscing. Ornare a in lacinia. Vestibulum accumsan ac metus massa tempor. Accumsan in lacinia ornare massa amet. Ac interdum ac non praesent. Cubilia lacinia interdum massa faucibus blandit nullam. Accumsan phasellus nunc integer. Accumsan euismod nunc adipiscing lacinia erat ut sit. Arcu amet. Id massa aliquet arcu accumsan lorem amet accumsan.

51 |

Amet nibh adipiscing adipiscing. Commodo ante vis placerat interdum massa massa primis. Tempus condimentum tempus non ac varius cubilia adipiscing placerat lorem turpis at. Aliquet lorem porttitor interdum. Amet lacus. Aliquam lobortis faucibus blandit ac phasellus. In amet magna non interdum volutpat porttitor metus a ante ac neque. Nisi turpis. Commodo col. Interdum adipiscing mollis ut aliquam id ante adipiscing commodo integer arcu amet Ac interdum ac non praesent. Cubilia lacinia interdum massa faucibus blandit nullam. Accumsan phasellus nunc integer. Accumsan euismod nunc adipiscing lacinia erat ut sit. Arcu amet. Id massa aliquet arcu accumsan lorem amet accumsan commodo odio cubilia ac eu interdum placerat placerat arcu commodo lobortis adipiscing semper ornare pellentesque.

52 |

Amet nibh adipiscing adipiscing. Commodo ante vis placerat interdum massa massa primis. Tempus condimentum tempus non ac varius cubilia adipiscing placerat lorem turpis at. Aliquet lorem porttitor interdum. Amet lacus. Aliquam lobortis faucibus blandit ac phasellus. In amet magna non interdum volutpat porttitor metus a ante ac neque. Nisi turpis. Commodo col. Interdum adipiscing mollis ut aliquam id ante adipiscing commodo integer arcu amet blandit adipiscing arcu ante.

53 | 54 |
55 |
56 | 57 | 58 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /public/images/bokeh_car_lights_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/images/bokeh_car_lights_bg.jpg -------------------------------------------------------------------------------- /public/images/dark_tint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/images/dark_tint.png -------------------------------------------------------------------------------- /public/images/pic02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/images/pic02.jpg -------------------------------------------------------------------------------- /public/images/pic03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/images/pic03.jpg -------------------------------------------------------------------------------- /public/images/pic04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/images/pic04.jpg -------------------------------------------------------------------------------- /public/images/pic07.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/images/pic07.jpg -------------------------------------------------------------------------------- /public/images/pic08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/images/pic08.jpg -------------------------------------------------------------------------------- /public/images/profile_placeholder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/images/profile_placeholder.gif -------------------------------------------------------------------------------- /public/index.bak: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | Transit by TEMPLATED 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | 50 | 51 | 52 |
53 |
54 |
55 |

Consectetur adipisicing elit

56 |

Lorem ipsum dolor sit amet, delectus consequatur, similique quia!

57 |
58 |
59 |
60 |
61 | 62 |

Lorem ipsum dolor

63 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Enim quam consectetur quibusdam magni minus aut modi aliquid.

64 |
65 |
66 |
67 |
68 | 69 |

Consectetur adipisicing

70 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laudantium ullam consequatur repellat debitis maxime.

71 |
72 |
73 |
74 |
75 | 76 |

Adipisicing elit totam

77 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Atque eaque eveniet, nesciunt molestias. Ipsam, voluptate vero.

78 |
79 |
80 |
81 |
82 |
83 | 84 | 85 |
86 |
87 |
88 |

Lorem ipsum dolor sit

89 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio, autem.

90 |
91 |
92 |
93 |
94 | 95 |

Lorem ipsum

96 |

Lorem ipsum dolor

97 |
98 |
99 | 100 |

Voluptatem dolores

101 |

Ullam nihil repudi

102 |
103 |
104 | 105 |

Doloremque quo

106 |

Harum corrupti quia

107 |
108 |
109 | 110 |

Voluptatem dicta

111 |

Et natus sapiente

112 |
113 |
114 |
115 |
116 |

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quibusdam dolore illum, temporibus veritatis eligendi, aliquam, dolor enim itaque veniam aut eaque sequi qui quia vitae pariatur repudiandae ab dignissimos ex!

117 | 122 |
123 |
124 |
125 | 126 | 127 |
128 |
129 |
130 |

Consectetur adipisicing elit

131 |

Lorem ipsum dolor sit amet. Delectus consequatur, similique quia!

132 |
133 |
134 |
135 |
136 |
137 |
138 | 139 |
140 |
141 | 142 |
143 |
144 | 145 |
146 |
147 |
    148 |
  • 149 |
150 |
151 |
152 |
153 |
154 |
155 | 156 | 157 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /public/javascripts/basket.full.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * basket.js 3 | * v0.5.2 - 2015-02-07 4 | * http://addyosmani.github.com/basket.js 5 | * (c) Addy Osmani; License 6 | * Created by: Addy Osmani, Sindre Sorhus, Andrée Hansson, Mat Scales 7 | * Contributors: Ironsjp, Mathias Bynens, Rick Waldron, Felipe Morais 8 | * Uses rsvp.js, https://github.com/tildeio/rsvp.js 9 | */ 10 | (function(){"use strict";function a(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1}function b(a){var b=a._promiseCallbacks;return b||(b=a._promiseCallbacks={}),b}function c(a,b){return"onerror"===a?void rb.on("error",b):2!==arguments.length?rb[a]:void(rb[a]=b)}function d(a){return"function"==typeof a||"object"==typeof a&&null!==a}function e(a){return"function"==typeof a}function f(a){return"object"==typeof a&&null!==a}function g(){}function h(){setTimeout(function(){for(var a,b=0;bh;h++)u(e.resolve(a[h]),void 0,c,d);return f}function E(a,b){var c=this;if(a&&"object"==typeof a&&a.constructor===c)return a;var d=new c(k,b);return q(d,a),d}function F(a,b){var c=this,d=new c(k,b);return t(d,a),d}function G(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}function H(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}function I(a,b){this._id=Jb++,this._label=b,this._state=void 0,this._result=void 0,this._subscribers=[],rb.instrument&&xb("created",this),k!==a&&(e(a)||G(),this instanceof I||H(),z(this,a))}function J(){this.value=void 0}function K(a){try{return a.then}catch(b){return Lb.value=b,Lb}}function L(a,b,c){try{a.apply(b,c)}catch(d){return Lb.value=d,Lb}}function M(a,b){for(var c,d,e={},f=a.length,g=new Array(f),h=0;f>h;h++)g[h]=a[h];for(d=0;dd;d++)c[d-1]=a[d];return c}function O(a,b){return{then:function(c,d){return a.call(b,c,d)}}}function P(a,b){var c=function(){for(var c,d=this,e=arguments.length,f=new Array(e+1),g=!1,h=0;e>h;++h){if(c=arguments[h],!g){if(g=S(c),g===Mb){var i=new Kb(k);return t(i,Mb.value),i}g&&g!==!0&&(c=O(g,c))}f[h]=c}var j=new Kb(k);return f[e]=function(a,c){a?t(j,a):void 0===b?q(j,c):b===!0?q(j,N(arguments)):tb(b)?q(j,M(arguments,b)):q(j,c)},g?R(j,f,a,d):Q(j,f,a,d)};return c.__proto__=a,c}function Q(a,b,c,d){var e=L(c,d,b);return e===Lb&&t(a,e.value),a}function R(a,b,c,d){return Kb.all(b).then(function(b){var e=L(c,d,b);return e===Lb&&t(a,e.value),a})}function S(a){return a&&"object"==typeof a?a.constructor===Kb?!0:K(a):!1}function T(a,b){return Kb.all(a,b)}function U(a,b,c){this._superConstructor(a,b,!1,c)}function V(a,b){return new U(Kb,a,b).promise}function W(a,b){return Kb.race(a,b)}function X(a,b,c){this._superConstructor(a,b,!0,c)}function Y(a,b){return new Rb(Kb,a,b).promise}function Z(a,b,c){this._superConstructor(a,b,!1,c)}function $(a,b){return new Z(Kb,a,b).promise}function _(a){throw setTimeout(function(){throw a}),a}function ab(a){var b={};return b.promise=new Kb(function(a,c){b.resolve=a,b.reject=c},a),b}function bb(a,b,c){return Kb.all(a,c).then(function(a){if(!e(b))throw new TypeError("You must pass a function as map's second argument.");for(var d=a.length,f=new Array(d),g=0;d>g;g++)f[g]=b(a[g]);return Kb.all(f,c)})}function cb(a,b){return Kb.resolve(a,b)}function db(a,b){return Kb.reject(a,b)}function eb(a,b,c){return Kb.all(a,c).then(function(a){if(!e(b))throw new TypeError("You must pass a function as filter's second argument.");for(var d=a.length,f=new Array(d),g=0;d>g;g++)f[g]=b(a[g]);return Kb.all(f,c).then(function(b){for(var c=new Array(d),e=0,f=0;d>f;f++)b[f]&&(c[e]=a[f],e++);return c.length=e,c})})}function fb(a,b){gc[_b]=a,gc[_b+1]=b,_b+=2,2===_b&&Tb()}function gb(){var a=process.nextTick,b=process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);return Array.isArray(b)&&"0"===b[1]&&"10"===b[2]&&(a=setImmediate),function(){a(lb)}}function hb(){return function(){vertxNext(lb)}}function ib(){var a=0,b=new dc(lb),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function jb(){var a=new MessageChannel;return a.port1.onmessage=lb,function(){a.port2.postMessage(0)}}function kb(){return function(){setTimeout(lb,1)}}function lb(){for(var a=0;_b>a;a+=2){var b=gc[a],c=gc[a+1];b(c),gc[a]=void 0,gc[a+1]=void 0}_b=0}function mb(){try{var a=require("vertx");return a.runOnLoop||a.runOnContext,hb()}catch(b){return kb()}}function nb(a,b){rb.async(a,b)}function ob(){rb.on.apply(rb,arguments)}function pb(){rb.off.apply(rb,arguments)}var qb={mixin:function(a){return a.on=this.on,a.off=this.off,a.trigger=this.trigger,a._promiseCallbacks=void 0,a},on:function(c,d){var e,f=b(this);e=f[c],e||(e=f[c]=[]),-1===a(e,d)&&e.push(d)},off:function(c,d){var e,f,g=b(this);return d?(e=g[c],f=a(e,d),void(-1!==f&&e.splice(f,1))):void(g[c]=[])},trigger:function(a,c){var d,e,f=b(this);if(d=f[a])for(var g=0;g1)throw new Error("Second argument not supported");if("object"!=typeof a)throw new TypeError("Argument must be an object");return g.prototype=a,new g},wb=[],xb=i,yb=void 0,zb=1,Ab=2,Bb=new w,Cb=new w,Db=B;B.prototype._validateInput=function(a){return tb(a)},B.prototype._validationError=function(){return new Error("Array Methods must be provided an Array")},B.prototype._init=function(){this._result=new Array(this.length)},B.prototype._enumerate=function(){for(var a=this.length,b=this.promise,c=this._input,d=0;b._state===yb&&a>d;d++)this._eachEntry(c[d],d)},B.prototype._eachEntry=function(a,b){var c=this._instanceConstructor;f(a)?a.constructor===c&&a._state!==yb?(a._onError=null,this._settledAt(a._state,b,a._result)):this._willSettleAt(c.resolve(a),b):(this._remaining--,this._result[b]=this._makeResult(zb,b,a))},B.prototype._settledAt=function(a,b,c){var d=this.promise;d._state===yb&&(this._remaining--,this._abortOnReject&&a===Ab?t(d,c):this._result[b]=this._makeResult(a,b,c)),0===this._remaining&&s(d,this._result)},B.prototype._makeResult=function(a,b,c){return c},B.prototype._willSettleAt=function(a,b){var c=this;u(a,void 0,function(a){c._settledAt(zb,b,a)},function(a){c._settledAt(Ab,b,a)})};var Eb=C,Fb=D,Gb=E,Hb=F,Ib="rsvp_"+ub()+"-",Jb=0,Kb=I;I.cast=Gb,I.all=Eb,I.race=Fb,I.resolve=Gb,I.reject=Hb,I.prototype={constructor:I,_guidKey:Ib,_onError:function(a){rb.async(function(b){setTimeout(function(){b._onError&&rb.trigger("error",a)},0)},this)},then:function(a,b,c){var d=this,e=d._state;if(e===zb&&!a||e===Ab&&!b)return rb.instrument&&xb("chained",this,this),this;d._onError=null;var f=new this.constructor(k,c),g=d._result;if(rb.instrument&&xb("chained",d,f),e){var h=arguments[e-1];rb.async(function(){y(e,f,h,g)})}else u(d,f,a,b);return f},"catch":function(a,b){return this.then(null,a,b)},"finally":function(a,b){var c=this.constructor;return this.then(function(b){return c.resolve(a()).then(function(){return b})},function(b){return c.resolve(a()).then(function(){throw b})},b)}};var Lb=new J,Mb=new J,Nb=P,Ob=T;U.prototype=vb(Db.prototype),U.prototype._superConstructor=Db,U.prototype._makeResult=A,U.prototype._validationError=function(){return new Error("allSettled must be called with an array")};var Pb=V,Qb=W,Rb=X;X.prototype=vb(Db.prototype),X.prototype._superConstructor=Db,X.prototype._init=function(){this._result={}},X.prototype._validateInput=function(a){return a&&"object"==typeof a},X.prototype._validationError=function(){return new Error("Promise.hash must be called with an object")},X.prototype._enumerate=function(){var a=this.promise,b=this._input,c=[];for(var d in b)a._state===yb&&b.hasOwnProperty(d)&&c.push({position:d,entry:b[d]});var e=c.length;this._remaining=e;for(var f,g=0;a._state===yb&&e>g;g++)f=c[g],this._eachEntry(f.entry,f.position)};var Sb=Y;Z.prototype=vb(Rb.prototype),Z.prototype._superConstructor=Db,Z.prototype._makeResult=A,Z.prototype._validationError=function(){return new Error("hashSettled must be called with an object")};var Tb,Ub=$,Vb=_,Wb=ab,Xb=bb,Yb=cb,Zb=db,$b=eb,_b=0,ac=fb,bc="undefined"!=typeof window?window:void 0,cc=bc||{},dc=cc.MutationObserver||cc.WebKitMutationObserver,ec="undefined"!=typeof process&&"[object process]"==={}.toString.call(process),fc="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel,gc=new Array(1e3);if(Tb=ec?gb():dc?ib():fc?jb():void 0===bc&&"function"==typeof require?mb():kb(),rb.async=ac,"undefined"!=typeof window&&"object"==typeof window.__PROMISE_INSTRUMENTATION__){var hc=window.__PROMISE_INSTRUMENTATION__;c("instrument",!0);for(var ic in hc)hc.hasOwnProperty(ic)&&ob(ic,hc[ic])}var jc={race:Qb,Promise:Kb,allSettled:Pb,hash:Sb,hashSettled:Ub,denodeify:Nb,on:ob,off:pb,map:Xb,filter:$b,resolve:Yb,reject:Zb,all:Ob,rethrow:Vb,defer:Wb,EventTarget:qb,configure:c,async:nb};"function"==typeof define&&define.amd?define(function(){return jc}):"undefined"!=typeof module&&module.exports?module.exports=jc:"undefined"!=typeof this&&(this.RSVP=jc)}).call(this),function(a,b){"use strict";var c=b.head||b.getElementsByTagName("head")[0],d="basket-",e=5e3,f=[],g=function(a,b){try{return localStorage.setItem(d+a,JSON.stringify(b)),!0}catch(c){if(c.name.toUpperCase().indexOf("QUOTA")>=0){var e,f=[];for(e in localStorage)0===e.indexOf(d)&&f.push(JSON.parse(localStorage[e]));return f.length?(f.sort(function(a,b){return a.stamp-b.stamp}),basket.remove(f[0].key),g(a,b)):void 0}return}},h=function(a){var b=new RSVP.Promise(function(b,c){var d=new XMLHttpRequest;d.open("GET",a),d.onreadystatechange=function(){4===d.readyState&&(200===d.status||0===d.status&&d.responseText?b({content:d.responseText,type:d.getResponseHeader("content-type")}):c(new Error(d.statusText)))},setTimeout(function(){d.readyState<4&&d.abort()},basket.timeout),d.send()});return b},i=function(a){return h(a.url).then(function(b){var c=j(a,b);return a.skipCache||g(a.key,c),c})},j=function(a,b){var c=+new Date;return a.data=b.content,a.originalType=b.type,a.type=a.type||b.type,a.skipCache=a.skipCache||!1,a.stamp=c,a.expire=c+60*(a.expire||e)*60*1e3,a},k=function(a,b){return!a||a.expire-+new Date<0||b.unique!==a.unique||basket.isValidItem&&!basket.isValidItem(a,b)},l=function(a){var b,c,d;if(a.url)return a.key=a.key||a.url,b=basket.get(a.key),a.execute=a.execute!==!1,d=k(b,a),a.live||d?(a.unique&&(a.url+=(a.url.indexOf("?")>0?"&":"?")+"basket-unique="+a.unique),c=i(a),a.live&&!d&&(c=c.then(function(a){return a},function(){return b}))):(b.type=a.type||b.originalType,b.execute=a.execute,c=new RSVP.Promise(function(a){a(b)})),c},m=function(a){var d=b.createElement("script");d.defer=!0,d.text=a.data,c.appendChild(d)},n={"default":m},o=function(a){return a.type&&n[a.type]?n[a.type](a):n["default"](a)},p=function(a){return a.map(function(a){return a.execute&&o(a),a})},q=function(){var a,b,c=[];for(a=0,b=arguments.length;b>a;a++)c.push(l(arguments[a]));return RSVP.all(c)},r=function(){var a=q.apply(null,arguments),b=this.then(function(){return a}).then(p);return b.thenRequire=r,b};a.basket={require:function(){for(var a=0,b=arguments.length;b>a;a++)arguments[a].execute=arguments[a].execute!==!1,arguments[a].once&&f.indexOf(arguments[a].url)>=0?arguments[a].execute=!1:arguments[a].execute!==!1&&f.indexOf(arguments[a].url)<0&&f.push(arguments[a].url);var c=q.apply(null,arguments).then(p);return c.thenRequire=r,c},remove:function(a){return localStorage.removeItem(d+a),this},get:function(a){var b=localStorage.getItem(d+a);try{return JSON.parse(b||"false")}catch(c){return!1}},clear:function(a){var b,c,e=+new Date;for(b in localStorage)c=b.split(d)[1],c&&(!a||this.get(c).expire<=e)&&this.remove(c);return this},isValidItem:null,timeout:5e3,addHandler:function(a,b){Array.isArray(a)||(a=[a]),a.forEach(function(a){n[a]=b})},removeHandler:function(a){basket.addHandler(a,void 0)}},basket.clear(!0)}(this,document); 11 | //# sourceMappingURL=basket.full.min.js.map -------------------------------------------------------------------------------- /public/javascripts/jquery.md5.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery MD5 Plugin 1.2.1 3 | * https://github.com/blueimp/jQuery-MD5 4 | * 5 | * Copyright 2010, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://creativecommons.org/licenses/MIT/ 10 | * 11 | * Based on 12 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message 13 | * Digest Algorithm, as defined in RFC 1321. 14 | * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 15 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 16 | * Distributed under the BSD License 17 | * See http://pajhome.org.uk/crypt/md5 for more info. 18 | */ 19 | 20 | /*jslint bitwise: true */ 21 | /*global unescape, jQuery */ 22 | 23 | (function ($) { 24 | 'use strict'; 25 | 26 | /* 27 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 28 | * to work around bugs in some JS interpreters. 29 | */ 30 | function safe_add(x, y) { 31 | var lsw = (x & 0xFFFF) + (y & 0xFFFF), 32 | msw = (x >> 16) + (y >> 16) + (lsw >> 16); 33 | return (msw << 16) | (lsw & 0xFFFF); 34 | } 35 | 36 | /* 37 | * Bitwise rotate a 32-bit number to the left. 38 | */ 39 | function bit_rol(num, cnt) { 40 | return (num << cnt) | (num >>> (32 - cnt)); 41 | } 42 | 43 | /* 44 | * These functions implement the four basic operations the algorithm uses. 45 | */ 46 | function md5_cmn(q, a, b, x, s, t) { 47 | return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); 48 | } 49 | function md5_ff(a, b, c, d, x, s, t) { 50 | return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); 51 | } 52 | function md5_gg(a, b, c, d, x, s, t) { 53 | return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); 54 | } 55 | function md5_hh(a, b, c, d, x, s, t) { 56 | return md5_cmn(b ^ c ^ d, a, b, x, s, t); 57 | } 58 | function md5_ii(a, b, c, d, x, s, t) { 59 | return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); 60 | } 61 | 62 | /* 63 | * Calculate the MD5 of an array of little-endian words, and a bit length. 64 | */ 65 | function binl_md5(x, len) { 66 | /* append padding */ 67 | x[len >> 5] |= 0x80 << ((len) % 32); 68 | x[(((len + 64) >>> 9) << 4) + 14] = len; 69 | 70 | var i, olda, oldb, oldc, oldd, 71 | a = 1732584193, 72 | b = -271733879, 73 | c = -1732584194, 74 | d = 271733878; 75 | 76 | for (i = 0; i < x.length; i += 16) { 77 | olda = a; 78 | oldb = b; 79 | oldc = c; 80 | oldd = d; 81 | 82 | a = md5_ff(a, b, c, d, x[i], 7, -680876936); 83 | d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); 84 | c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); 85 | b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); 86 | a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); 87 | d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); 88 | c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); 89 | b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); 90 | a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); 91 | d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); 92 | c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); 93 | b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); 94 | a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); 95 | d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); 96 | c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); 97 | b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); 98 | 99 | a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); 100 | d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); 101 | c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); 102 | b = md5_gg(b, c, d, a, x[i], 20, -373897302); 103 | a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); 104 | d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); 105 | c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); 106 | b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); 107 | a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); 108 | d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); 109 | c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); 110 | b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); 111 | a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); 112 | d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); 113 | c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); 114 | b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); 115 | 116 | a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); 117 | d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); 118 | c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); 119 | b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); 120 | a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); 121 | d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); 122 | c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); 123 | b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); 124 | a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); 125 | d = md5_hh(d, a, b, c, x[i], 11, -358537222); 126 | c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); 127 | b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); 128 | a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); 129 | d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); 130 | c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); 131 | b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); 132 | 133 | a = md5_ii(a, b, c, d, x[i], 6, -198630844); 134 | d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); 135 | c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); 136 | b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); 137 | a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); 138 | d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); 139 | c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); 140 | b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); 141 | a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); 142 | d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); 143 | c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); 144 | b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); 145 | a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); 146 | d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); 147 | c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); 148 | b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); 149 | 150 | a = safe_add(a, olda); 151 | b = safe_add(b, oldb); 152 | c = safe_add(c, oldc); 153 | d = safe_add(d, oldd); 154 | } 155 | return [a, b, c, d]; 156 | } 157 | 158 | /* 159 | * Convert an array of little-endian words to a string 160 | */ 161 | function binl2rstr(input) { 162 | var i, 163 | output = ''; 164 | for (i = 0; i < input.length * 32; i += 8) { 165 | output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF); 166 | } 167 | return output; 168 | } 169 | 170 | /* 171 | * Convert a raw string to an array of little-endian words 172 | * Characters >255 have their high-byte silently ignored. 173 | */ 174 | function rstr2binl(input) { 175 | var i, 176 | output = []; 177 | output[(input.length >> 2) - 1] = undefined; 178 | for (i = 0; i < output.length; i += 1) { 179 | output[i] = 0; 180 | } 181 | for (i = 0; i < input.length * 8; i += 8) { 182 | output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32); 183 | } 184 | return output; 185 | } 186 | 187 | /* 188 | * Calculate the MD5 of a raw string 189 | */ 190 | function rstr_md5(s) { 191 | return binl2rstr(binl_md5(rstr2binl(s), s.length * 8)); 192 | } 193 | 194 | /* 195 | * Calculate the HMAC-MD5, of a key and some data (raw strings) 196 | */ 197 | function rstr_hmac_md5(key, data) { 198 | var i, 199 | bkey = rstr2binl(key), 200 | ipad = [], 201 | opad = [], 202 | hash; 203 | ipad[15] = opad[15] = undefined; 204 | if (bkey.length > 16) { 205 | bkey = binl_md5(bkey, key.length * 8); 206 | } 207 | for (i = 0; i < 16; i += 1) { 208 | ipad[i] = bkey[i] ^ 0x36363636; 209 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 210 | } 211 | hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8); 212 | return binl2rstr(binl_md5(opad.concat(hash), 512 + 128)); 213 | } 214 | 215 | /* 216 | * Convert a raw string to a hex string 217 | */ 218 | function rstr2hex(input) { 219 | var hex_tab = '0123456789abcdef', 220 | output = '', 221 | x, 222 | i; 223 | for (i = 0; i < input.length; i += 1) { 224 | x = input.charCodeAt(i); 225 | output += hex_tab.charAt((x >>> 4) & 0x0F) + 226 | hex_tab.charAt(x & 0x0F); 227 | } 228 | return output; 229 | } 230 | 231 | /* 232 | * Encode a string as utf-8 233 | */ 234 | function str2rstr_utf8(input) { 235 | return unescape(encodeURIComponent(input)); 236 | } 237 | 238 | /* 239 | * Take string arguments and return either raw or hex encoded strings 240 | */ 241 | function raw_md5(s) { 242 | return rstr_md5(str2rstr_utf8(s)); 243 | } 244 | function hex_md5(s) { 245 | return rstr2hex(raw_md5(s)); 246 | } 247 | function raw_hmac_md5(k, d) { 248 | return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)); 249 | } 250 | function hex_hmac_md5(k, d) { 251 | return rstr2hex(raw_hmac_md5(k, d)); 252 | } 253 | 254 | $.md5 = function (string, key, raw) { 255 | if (!key) { 256 | if (!raw) { 257 | return hex_md5(string); 258 | } else { 259 | return raw_md5(string); 260 | } 261 | } 262 | if (!raw) { 263 | return hex_hmac_md5(key, string); 264 | } else { 265 | return raw_hmac_md5(key, string); 266 | } 267 | }; 268 | 269 | }(typeof jQuery === 'function' ? jQuery : this)); -------------------------------------------------------------------------------- /public/javascripts/login/login.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | var username, password; 3 | function login() { 4 | username = $('#username').val(); 5 | password = $.md5($('#password').val()); 6 | $.post("/login/auth", { 7 | username: username, 8 | password: password 9 | }, function(data) { 10 | if (data.stat == "success") { 11 | var str = window.location.href.substr(window.location.href.length - 5, 5); 12 | if (str == 'login') 13 | window.location.href='/'; 14 | else window.history.go(0); 15 | } 16 | else { 17 | var EMessage = '
用户名或密码错误
'; 18 | $('.login-message').html(EMessage); 19 | setInterval("$('.login-message').html('


')", 2000); 20 | } 21 | }); 22 | } 23 | $('#password').keyup(function(event) { 24 | var keycode = event.which; 25 | if (keycode == 13) { 26 | $('#username').focus(); 27 | $('#submit').click(); 28 | } 29 | }); 30 | $('#username').keyup(function(event) { 31 | var keycode = event.which; 32 | if (keycode == 13) { 33 | $('#password').focus(); 34 | } 35 | }); 36 | $('#submit').click(function() { 37 | login(); 38 | }); 39 | }); 40 | 41 | -------------------------------------------------------------------------------- /public/javascripts/login/register.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | function message(msg) { 3 | var RMessage = '
' + msg + '
'; 4 | $('.register-message').html(RMessage); 5 | setTimeout("$('.register-message').html('

')", 2000); 6 | } 7 | function register() { 8 | var user = $('#user').val(); 9 | var pass = $.md5($('#pass').val()); 10 | var reppass = $.md5($('#reppass').val()); 11 | var refer = $('#invite').val(); 12 | if (pass != reppass) { 13 | message('两次输入密码不一致。'); 14 | return; 15 | } 16 | $.post('/login/register', { 17 | user: user, 18 | pass: pass, 19 | refer: refer 20 | }, function(data) { 21 | if (data) { 22 | if (data.stat == 1) window.location.href='/login/register/success'; 23 | else message('注册失败'); 24 | } 25 | }); 26 | } 27 | $('#user').keyup(function(event) { 28 | var keycode = event.which; 29 | if (keycode == 13) $('#pass').focus(); 30 | }); 31 | $('#pass').keyup(function(event) { 32 | var keycode = event.which; 33 | if (keycode == 13) $('#reppass').focus(); 34 | }); 35 | $('#reppass').keyup(function(event) { 36 | var keycode = event.which; 37 | if (keycode == 13) $('#invite').focus(); 38 | }); 39 | $('#invite').keyup(function(event) { 40 | var keycode = event.which; 41 | if (keycode == 13) $('#submit').click(); 42 | }); 43 | $('#submit').click(function() { 44 | register(); 45 | $('#user').focus(); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /public/javascripts/login/success.js: -------------------------------------------------------------------------------- 1 | var cnt = 2; 2 | 3 | function getCount() { 4 | if (!cnt) { 5 | window.location.href='/'; 6 | return; 7 | } 8 | $('#cnt').html(cnt); 9 | -- cnt; 10 | setTimeout("getCount()", 1000); 11 | } 12 | 13 | $(document).ready(function() { 14 | setTimeout("getCount()", 1000); 15 | }); 16 | -------------------------------------------------------------------------------- /public/javascripts/rating.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $('[rating]').each(function() { 3 | var rating = $(this).attr('rating'); 4 | var map = ["gray", "gray", "green", "orange", "red"]; 5 | var color = map[rating / 500]; 6 | $(this).css("color", color); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /public/js/html5shiv.js: -------------------------------------------------------------------------------- 1 | /* 2 | HTML5 Shiv v3.6.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed 3 | */ 4 | (function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); 5 | a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/\w+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; 6 | c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| 7 | "undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);if(g)return a.createDocumentFragment(); 8 | for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d', 54 | position: 'top-left', 55 | side: 'top', 56 | width: '6em' 57 | }, 58 | navPanel: { 59 | animation: 'overlayX', 60 | breakpoints: 'medium', 61 | clickToHide: true, 62 | height: '100%', 63 | hidden: true, 64 | html: '
', 65 | orientation: 'vertical', 66 | position: 'top-left', 67 | side: 'left', 68 | width: 250 69 | } 70 | } 71 | } 72 | }); 73 | 74 | $(function() { 75 | 76 | var $window = $(window), 77 | $body = $('body'); 78 | 79 | // Disable animations/transitions until the page has loaded. 80 | $body.addClass('is-loading'); 81 | 82 | $window.on('load', function() { 83 | $body.removeClass('is-loading'); 84 | }); 85 | 86 | }); 87 | 88 | })(jQuery); -------------------------------------------------------------------------------- /public/js/skel-layers.min.js: -------------------------------------------------------------------------------- 1 | /* skel-layers.js v2.0.2-dev | (c) n33 | getskel.com | MIT licensed */ 2 | (function(e){typeof define=="function"&&define.amd?define(["jquery","skel"],e):e(jQuery,skel)})(function(e,t){var n="config",r="cache",i="setTimeout",s="trigger",o="_skel_layers_translateOrigin",u="position",f="_skel_layers_resetForms",l="$element",c="visibleWrapper",h="_skel_layers_translate",p="skel-layers-moved",d="moveToVisibleWrapper",v="_skel_layers_promote",m="exclusiveLayer",g="_skel_layers_resume",y="_skel_layers_demote",b="exclusive",w="moveToHiddenWrapper",E="center",S="right",x="_skel_layers_cssNumericValue",T="bottom",N="prototype",C="speed",k="css",L="left",A="wrapper",O="_skel_layers_init",M="_skel_layers_suspend",_="skel-layers-css-values",D="overflow-x",P="width",H="_skel_layers_doTranslate",B="transform",j="hidestart",F="layers",I="showstart",q="skel-layers-layer-z-index",R="_height",U="transition",z=null,W="hiddenWrapper",X="scrollTop",V="skel-layers-css",$="children",J="height",K="showend",Q="hideend",G=".skel-layers-fixed:not(.skel-layers-moved)",Y="iterate",Z="auto",et="deviceType",tt="resetForms",nt="unlockView",rt="top",it="touchstart.lock click.lock scroll.lock",st="recalcW",ot="element",ut="hidden",at="_width",ft=!0,lt='
1){for(t=0;t0&&(t[Ut](),t[k](P,(t[pn](Hn)+r)/12*100+"%"))},e.fn[an]=function(){return e(this).parents()[dt]>0},e.fn[Ut]=function(){var t=e(this);t[$n]("class").match(/(\s+|^)([0-9]+)u(\s+|$)/)&&t[pn](Hn,parseInt(RegExp.$2))},e.fn[v]=function(t){var r,i,s;if(this[dt]>1){for(r=0;r-1*f&&n>l;break;case S:a=i-1*f&&n<-1*l;break;case rt:a=n-1*f&&i>l;break;case T:a=n-1*f&&i<-1*l}if(a)return s[Vt]=z,s[$t]=z,s[Jt](),pt}if(r[X]()==0&&i<0||u>o-2&&u0)return pt}),this[l]=r},lr[N][Tt]=function(){return this[l]!==z},lr[N][In]=function(){return this[l].is(":visible")},lr[N][d]=function(){fr[r][c][Ht](this[l])},lr[N][w]=function(){if(!this[l][an]())return;fr[r][W][Ht](this[l])},lr[N].resume=function(t){if(!this[Tt]())return;this[l][qn](Rn).each(function(){fr.parseResume(e(this))}),this[n][ut]||this[gn](t)},lr[N].suspend=function(){if(!this[Tt]())return;this[l][o](),this[l][qn](Rn).each(function(){fr.parseSuspend(e(this))}),this[on]&&this[Jt]()},fr={cache:{visibleWrapper:z,body:z,exclusiveLayer:z,document:z,html:z,htmlbody:z,hiddenWrapper:z,layers:{},parent:z,window:z,wrapper:z},config:{baseZIndex:1e4,layers:{},mode:u,speed:500,easing:"ease",wrap:ft},layerIndex:1,create:function(t,i,s){var o,a;if(t in fr[r][F])return;if(u in i){if(!i[Jn]&&(o=e(Vn+t))[dt]==0)return;return fr[n].wrap||(fr[n].wrap=ft,fr.initWrappers()),a=new lr(t,i,fr.layerIndex++),fr[r][F][t]=a,o&&(o[$]()[wn](a[ot]),o.remove()),s||fr._.updateState(),a}return},destroy:function(i){if(i in fr[r][F]){var s=fr[r][F][i];return s.suspend(),s[n][Tn]&&s[n][Tn]!=fr._.sd&&(a=fr._[Sn](s[n][Tn]),fr._[Y](a,function(e){fr._.removeCachedElementFromState(a[e],i)})),s[n][zt]&&(a=fr._[Sn](s[n][zt]),fr._[Y](a,function(e){fr._.removeCachedElementFromBreakpoint(a[e],i)})),e(s[ot]).remove(),delete fr[r][F][i],t.uncacheElement(i),ft}return},get:function(e){if(e in fr[r][F])return fr[r][F][e];return},hide:function(e){fr[r][F][e][Jt]()},show:function(e){fr[r][F][e][gn]()},toggle:function(e){var t=fr[r][F][e];t[In]()?t[Jt]():t[gn]()},getBaseFontSize:function(){return fr._.vars.IEVersion<9?16.5:parseFloat(getComputedStyle(fr[r][zn].get(0)).fontSize)},getHalf:function(e){var t=parseInt(e);return typeof e=="string"&&e.charAt(e[dt]-1)=="%"?Math.floor(t/2)+"%":Math.floor(t/2)+Dn},lockView:function(e){e==An&&fr[r][Xn][k](D,ut),fr[n][On]!=B&&t.vars[et]==Nn&&fr[r][ht][k](J,fr[r].document[J]()),fr[r][A].on(it,function(e){e[Kt](),e[Xt](),fr[r][m]&&fr[r][m][Jt]()}),fr[r][tn].on(It,function(e){fr[r][m]&&fr[r][m][Jt]()}),fr._.vars.isMobile||window[i](function(){fr[r][tn].on(Ft,function(e){fr[r][m]&&fr[r][m][Jt]()})},fr[n][C]+50)},parseInit:function(t){var n,s,o=t.get(0),u=t[$n]("data-action"),a=t[$n]("data-args"),f,l;u&&a&&(a=a.split(","));switch(u){case"toggleLayer":case"layerToggle":t[k](Lt,mn)[k]("cursor","pointer"),n=function(t){var n=e(this);t[Kt](),t[Xt]();if(n[pn](hn)===ft)return;n[pn](hn,ft),window[i](function(){n.removeData(hn)},500);if(fr[r][m])return fr[r][m][Jt](),pt;var s=fr[r][F][a[0]];s[In]()?s[Jt]():s[gn]()},t.on("touchend click",n);break;case"navList":f=e(Vn+a[0]),n=f[qn]("a"),s=[],n.each(function(){var t=e(this),n,r;n=Math.max(0,t.parents("li")[dt]-1),r=t[$n]("href"),s.push(''+t.text()+"")}),s[dt]>0&&t[Jn]("");break;case"copyText":f=e(Vn+a[0]),t[Jn](f.text());break;case"copyHTML":f=e(Vn+a[0]),t[Jn](f[Jn]());break;case"moveElementContents":f=e(Vn+a[0]),o[g]=function(){f[$]().each(function(){var n=e(this);if(n[qt](p))return;t[Ht](n),n[sn](p),n[Et]()})},o[M]=function(){t[$]().each(function(){var t=e(this);if(!t[qt](p))return;f[Ht](t),t[yn](p),fr.refresh(t),t[St]()})},o[g]();break;case"moveElement":f=e(Vn+a[0]),o[g]=function(){if(f[qt](p))return;e(lt+f[$n]("id")+'" />').insertBefore(f),t[Ht](f),f[sn](p),f[Et]()},o[M]=function(){if(!f[qt](p))return;e(Ot+f[$n]("id")).replaceWith(f),f[yn](p),fr.refresh(f),f[St]()},o[g]();break;case"moveCell":f=e(Vn+a[0]),l=e(Vn+a[1]),o[g]=function(){e(lt+f[$n]("id")+'" />').insertBefore(f),t[Ht](f),f[k](P,Z),l&&l[nn]()},o[M]=function(){e(Ot+f[$n]("id")).replaceWith(f),f[k](P,""),l&&l[k](P,"")},o[g]();break;default:}},parseResume:function(e){var t=e.get(0);t[g]&&t[g]()},parseSuspend:function(e){var t=e.get(0);t[M]&&t[M]()},recalc:function(e,t){var n=fr._.parseMeasurement(e),r;switch(n[1]){case"%":r=Math.floor(t*(n[0]/100));break;case"em":r=fr.getBaseFontSize()*n[0];break;default:case Dn:r=n[0]}return r},recalcH:function(t){return fr.recalc(t,e(window)[J]())},recalcW:function(t){return fr.recalc(t,e(window)[P]())},refresh:function(t){var n;t?n=t.filter(G):n=e(G),n[O](ft)[wn](fr[r][c])},unlockView:function(e){e==An&&fr[r][Xn][k](D,""),fr[n][On]!=B&&t.vars[et]==Nn&&fr[r][ht][k](J,""),fr[r][A].off(it),fr[r][tn].off(It),fr._.vars.isMobile||fr[r][tn].off(Ft)},init:function(){n in fr[n]&&(fr._.extend(fr[n],fr[n][n]),delete fr[n][n]),fr._[Y](fr[n],function(e){fr[n][e]&&typeof fr[n][e]==Cn&&u in fr[n][e]&&(fr[n][F][e]=fr[n][e],delete fr[n][e])}),typeof fr[n][On]=="function"&&(fr[n][On]=fr[n][On]()),fr[n][On]==B&&(!fr._[Qt](B)||!fr._[Qt](U))&&(fr[n][On]=u),fr[n][On]==u&&!fr._[Qt](U)&&(fr[n][On]=Dt),fr._.vars[et]=="wp"&&(fr[n][On]=Dt),fr[r][tn]=e(window),e(function(){fr.initAnimation(),fr.initObjects(),fr[n].wrap&&fr.initWrappers(),fr.initLayers(),fr.initIncludes(),fr._.updateState()})},initIncludes:function(){e(".skel-layers-include").each(function(){fr.parseInit(e(this))})},initLayers:function(){fr._[Y](fr[n][F],function(e){fr.create(e,fr[n][F][e],ft)})},initObjects:function(){fr[r].document=e(document),fr[r][Jn]=e(Jn),fr[r][zn]=e(zn),fr[r][Xn]=e("html,body")},initAnimation:function(){fr[n][On]==Dt?(e.fn[vt]=function(t){e(this).fadeTo(fr[n][C],1,t)},e.fn[ct]=function(t){e(this).fadeTo(fr[n][C],0,t)}):(e.fn[vt]=function(t){e(this)[k](vn,1),t&&window[i](t,fr[n][C]+50)},e.fn[ct]=function(t){e(this)[k](vn,0),t&&window[i](t,fr[n][C]+50)});if(fr[n][On]==B)e.fn[o]=function(){return e(this)[h](0,0)},e.fn[h]=function(t,n){return e(this)[k](B,"translate("+t+"px, "+n+"px)")},e.fn[O]=function(){return e(this)[k](Gt,ut)[k](Ln,"500")[kn](U,"transform "+fr[n][C]/1e3+xn+fr[n][xt]+","+Wn+fr[n][C]/1e3+xn+fr[n][xt])[pn](V,[Gt,Ln,cn,Zt,bn,dn,U])};else{var s=[];fr[n][On]==Dt?(fr[r][tn].resize(function(){if(fr[n][C]!=0){var e=fr[n][C];fr[n][C]=0,window[i](function(){fr[n][C]=e,s=[]},0)}}),fr[n][xt].substr(0,4)=="ease"?(fr[n][xt]="swing",fr[n][C]=fr[n][C]*.65):fr[n][xt]="linear",e.fn[H]=function(t,r){e(this)[Dt](t,fr[n][C],fr[n][xt],r)},e.fn[O]=function(t){return e(this)[k](u,t?Mn:fn)[pn](V,[u])}):(fr[r][tn].resize(function(){window[i](function(){s=[]},0)}),e.fn[H]=function(t,r){var s=e(this);fr._[Y](t,function(e){s[k](e,t[e])}),window[i](r,fr[n][C])},e.fn[O]=function(t){return e(this)[k](U,"top "+fr[n][C]/1e3+xn+fr[n][xt]+","+"right "+fr[n][C]/1e3+xn+fr[n][xt]+","+"bottom "+fr[n][C]/1e3+xn+fr[n][xt]+","+"left "+fr[n][C]/1e3+xn+fr[n][xt]+","+Wn+fr[n][C]/1e3+xn+fr[n][xt])[k](u,t?Mn:fn)[pn](V,[cn,Zt,bn,dn,U,u])}),e[x]=function(e){return e&&e.slice(-1)=="%"?e:parseInt(e)},e.fn[o]=function(){for(var t=0;t'),fr[r][ht]=e("#skel-layers-parent"),fr[r][ht][k](u,fn)[k](L,0)[k](rt,0)[k]("min-height",mt)[k](P,mt)):fr[r][ht]=fr[r][zn],fr[r][ht].wrapInner('
'),fr[r][A]=e("#skel-layers-wrapper"),fr[r][A][k](u,Un)[k](L,0)[k](S,0)[k](rt,0)[O](),fr[r][W]=e('
')[wn](fr[r][ht]),fr[r][W][k](J,mt),fr[r][c]=e('
')[wn](fr[r][ht]),fr[r][c][k](u,Un),fr._[Bt](Mt,fr[r][W][0]),fr._[Bt]("skel_layers_visibleWrapper",fr[r][c][0]),fr._[Bt]("skel_layers_wrapper",fr[r][A][0]),e("[autofocus]").focus(),fr.refresh()}},fr)}(jQuery))}); -------------------------------------------------------------------------------- /public/stylesheets/admin/adminProblem.css: -------------------------------------------------------------------------------- 1 | .statn{padding-top:0px;padding-bottom:0px;padding-left:8px;padding-right:8px} -------------------------------------------------------------------------------- /public/stylesheets/admin/adminProblem.less: -------------------------------------------------------------------------------- 1 | .statn { 2 | padding-top: 0px; 3 | padding-bottom: 0px; 4 | padding-left: 8px; 5 | padding-right: 8px; 6 | } 7 | -------------------------------------------------------------------------------- /public/stylesheets/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.2.0 (http://getbootstrap.com) 3 | * Copyright 2011-2014 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:-o-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#2d6ca2));background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-primary:disabled,.btn-primary[disabled]{background-color:#2d6ca2;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#357ebd;background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-o-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#357ebd));background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f3f3f3));background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:-o-linear-gradient(top,#222 0,#282828 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#222),to(#282828));background-image:linear-gradient(to bottom,#222 0,#282828 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:-o-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#3071a9));background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:-o-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#3278b3));background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);background-repeat:repeat-x;border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-o-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#357ebd));background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} 6 | -------------------------------------------------------------------------------- /public/stylesheets/editProblem.css: -------------------------------------------------------------------------------- 1 | .smallI{padding-top:0px;padding-bottom:0px;padding-left:6px;padding-right:6px}.smallB{margin-top:0px;margin-bottom:0px}.HR{margin-top:3px;margin-bottom:10px} -------------------------------------------------------------------------------- /public/stylesheets/editProblem.less: -------------------------------------------------------------------------------- 1 | .smallI { 2 | padding-top: 0px; 3 | padding-bottom: 0px; 4 | padding-left: 6px; 5 | padding-right: 6px; 6 | } 7 | 8 | .smallB { 9 | margin-top: 0px; 10 | margin-bottom: 0px; 11 | } 12 | 13 | .HR { 14 | margin-top: 3px; 15 | margin-bottom: 10px; 16 | } 17 | 18 | -------------------------------------------------------------------------------- /public/stylesheets/index.css: -------------------------------------------------------------------------------- 1 | .author-right { 2 | font-family: Courier; 3 | position: relative; 4 | } 5 | .author { 6 | font-family: Courier; 7 | } 8 | -------------------------------------------------------------------------------- /public/stylesheets/problems.css: -------------------------------------------------------------------------------- 1 | h3 { 2 | margin-top: 10px; 3 | margin-bottom: 0px; 4 | } 5 | 6 | hr { 7 | margin-top: 10px; 8 | margin-bottom: 10px; 9 | } 10 | 11 | div.cont { 12 | margin-left: 10px; 13 | } 14 | -------------------------------------------------------------------------------- /public/stylesheets/status.css: -------------------------------------------------------------------------------- 1 | .btnsmall{padding:0 10px 0 10px}th{text-align:center}td{text-align:center} -------------------------------------------------------------------------------- /public/stylesheets/status.less: -------------------------------------------------------------------------------- 1 | .btnsmall { 2 | padding: 0 10px 0 10px 3 | } 4 | 5 | th { 6 | text-align: center 7 | } 8 | 9 | td { 10 | text-align: center 11 | } 12 | -------------------------------------------------------------------------------- /public/stylesheets/style.css: -------------------------------------------------------------------------------- 1 | body{font-family:"Helvetica Neue",Helvetica,Microsoft Yahei,Hiragino Sans GB,WenQuanYi Micro Hei,sans-serif} -------------------------------------------------------------------------------- /public/stylesheets/style.less: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Helvetica Neue", Helvetica, Microsoft Yahei, Hiragino Sans GB, WenQuanYi Micro Hei, sans-serif; 3 | } 4 | 5 | //p, div, h2, h3 { 6 | // font-family: "微软雅黑", Helvetica, sans-serif; 7 | //} 8 | 9 | -------------------------------------------------------------------------------- /public/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jcpwfloi/cboj/112583863e231e861f1f1c29faaf1c90bcbbe24c/public/test -------------------------------------------------------------------------------- /routes/admin.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var p = require('../model/problem'); 4 | var ps = require('../model/problems'); 5 | var Step = require('step'); 6 | var fs = require('fs'); 7 | 8 | var db = require('../model/dbquery'); 9 | 10 | var nav = [ 11 | { name: '管理首页', ref: '/admin', active: true }, 12 | { name: '管理用户', ref: '/admin/users', active: false }, 13 | { name: '管理问题', ref: '/admin/problems', active: false }, 14 | { name: '管理比赛', ref: '/admin/contests', active: false }, 15 | ]; 16 | 17 | function checkAvail(req, res, callback) { 18 | if (!req.session.user) { 19 | res.render('login', { title: '登陆 - CodeBursts!', nav: nav }); 20 | return; 21 | } 22 | var username = req.session.user.username; 23 | db.getUserByName(username, function(err, doc) { 24 | if (doc.admin == true) callback(); 25 | else { 26 | res.render('login', { title: '登陆 - CodeBursts!', nav: nav }); 27 | return; 28 | } 29 | }); 30 | } 31 | 32 | router.get('/', function(req, res) { 33 | checkAvail(req, res, function() { 34 | for (x in nav) { 35 | nav[x].active = false; 36 | } 37 | nav[0].active = true; 38 | res.render('admin', { title: '管理 - CodeBursts!', nav: nav }); 39 | }); 40 | }); 41 | 42 | router.get('/serverControl/:action', function(req, res) { 43 | checkAvail(req, res, function() { 44 | var action = req.params.action; 45 | if (action == "restart") { 46 | res.redirect('/admin'); 47 | setTimeout(function() { 48 | require('child_process').exec('pm2 reload all', function(err, stdout, stderr) { 49 | }); 50 | }, 2000); 51 | } 52 | if (action == "backup") { 53 | var date = new Date(); 54 | var path = 'backup/' + date.getFullYear().toString() + date.getMonth().toString() + '-' + date.getDay().toString() + '_' + date.getHours().toString() + '_' + date.getMinutes().toString() + '_' + date.getSeconds().toString(); 55 | require('child_process').exec('mongodump; tar czf dump.tar.gz dump; rm -r dump; mkdir ' + path + '; mv dump.tar.gz ' + path, {cwd: '/root'}, function(err, stdout, stderr) { 56 | res.render('admin/output', {nav: nav, err: err, stdout: stdout, stderr: stderr}); 57 | }); 58 | } 59 | if (action == "logs") { 60 | var path = '/root/.pm2/logs'; 61 | var files = fs.readdirSync(path); 62 | res.render('admin/logs', {nav: nav, files: files}); 63 | } 64 | }); 65 | }); 66 | 67 | router.get('/serverControl/logs/:logFile', function(req, res) { 68 | fs.readFile('/root/.pm2/logs/' + req.params.logFile, function(err, doc) { 69 | res.render('admin/output', {nav: nav, err: err, stdout: doc}); 70 | }); 71 | }); 72 | 73 | router.get('/users', function(req, res) { 74 | checkAvail(req, res, function() { 75 | for (x in nav) { 76 | nav[x].active = false; 77 | } 78 | nav[1].active = true; 79 | res.render('admin/users', { title: '管理用户 - CodeBursts!', nav: nav}); 80 | }); 81 | }); 82 | 83 | var perPage = 100; 84 | var problems = {}; 85 | var problem = {}; 86 | 87 | function getProblems(pageId, callback) { 88 | p.fetchProblems(1 + perPage * (pageId - 1), perPage, function(err, doc) { 89 | if (err) return; 90 | problems = doc; 91 | callback(); 92 | }); 93 | } 94 | 95 | function getProblemIndex(problemId, callback) { 96 | p.fetchProblems(problemId - 1000, 1, function(err, doc) { 97 | if (err) return; 98 | if (doc) callback(err, doc[0]); 99 | else callback(err, null); 100 | }); 101 | } 102 | 103 | function getProblem(problemId, callback) { 104 | ps.fetchProblem(problemId, function(err, doc) { 105 | if (err) return; 106 | problem = doc; 107 | callback(); 108 | }); 109 | } 110 | 111 | router.get('/problems', function(req, res) { 112 | checkAvail(req, res, function() { 113 | for (x in nav) nav[x].active = false; 114 | nav[2].active = true; 115 | getProblems(1, function() { 116 | res.render('admin/problems', { title: '管理问题 - CodeBursts!', nav: nav, problems: problems }); 117 | }); 118 | }); 119 | }); 120 | 121 | router.post('/problems/add', function(req, res) { 122 | checkAvail(req, res, function() { 123 | var info = { 124 | name: req.param('index'), 125 | description: req.param('description'), 126 | input: req.param('input'), 127 | output: req.param('output'), 128 | sampleInput: req.param('sampleInput'), 129 | sampleOutput: req.param('sampleOutput'), 130 | title: req.param('title'), 131 | avail: false, 132 | all: 0, 133 | ac: 0 134 | }; 135 | ps.addProblem(info, function() { 136 | res.redirect('back'); 137 | }); 138 | }); 139 | }); 140 | 141 | router.post('/problems/edit/submit/:problemId', function(req, res) { 142 | var problemId = Number(req.params.problemId); 143 | checkAvail(req, res, function() { 144 | var info = { 145 | description: req.param('description'), 146 | input: req.param('input'), 147 | output: req.param('output'), 148 | sampleInput: req.param('sampleInput'), 149 | sampleOutput: req.param('sampleOutput'), 150 | title: req.param('title'), 151 | }; 152 | ps.updateProblem(problemId, info, function() { 153 | res.redirect('back'); 154 | }); 155 | }); 156 | }); 157 | 158 | router.get('/problems/edit/:problemId', function(req, res) { 159 | checkAvail(req, res, function() { 160 | for (x in nav) nav[x].active = false; 161 | nav[2].active = true; 162 | var problemId = req.params.problemId; 163 | Step( 164 | function() { 165 | getProblemIndex(Number(problemId), this.parallel()); 166 | getProblem(Number(problemId), this.parallel()); 167 | }, 168 | function(err, doc) { 169 | res.render('admin/editProblems', { title: problemId + ' - 编辑问题 - CodeBursts!', nav: nav, problem: problem, problemIndex: doc }); 170 | } 171 | ); 172 | }); 173 | }); 174 | 175 | router.get('/problems/:problemId/:action', function(req, res) { 176 | checkAvail(req, res, function() { 177 | var problemId = Number(req.params.problemId); 178 | var action = req.params.action; 179 | setTimeout(function() { 180 | res.redirect('/admin/problems'); 181 | }, 500); 182 | if (action == "unavail") { 183 | require('mongodb').MongoClient.connect('mongodb://localhost/cboj', function(err, db) { 184 | db.collection('problem', function(err, collection) { 185 | collection.update({id: problemId}, {$set: {avail: false}}, function(err, res) {}); 186 | }); 187 | db.collection('problems', function(err, collection) { 188 | collection.update({id: problemId}, {$set: {avail: false}}, function(err, res) {}); 189 | }); 190 | }); 191 | } else if (action == "avail") { 192 | require('mongodb').MongoClient.connect('mongodb://localhost/cboj', function(err, db) { 193 | db.collection('problem', function(err, collection) { 194 | collection.update({id: problemId}, {$set: {avail: true}}, function(err, res) {}); 195 | }); 196 | db.collection('problems', function(err, collection) { 197 | collection.update({id: problemId}, {$set: {avail: true}}, function(err, res) {}); 198 | }); 199 | }); 200 | } 201 | }); 202 | }); 203 | 204 | module.exports = router; 205 | 206 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | var nav = [ 5 | { name: '首页', ref: '/', active: true }, 6 | { name: '问题', ref: '/problem', active: false }, 7 | { name: '状态', ref: '/status', active: false }, 8 | { name: '比赛', ref: '/contest', active: false }, 9 | { name: '排名', ref: '/ranklist', active: false } 10 | ]; 11 | 12 | var login; 13 | var ranklist; 14 | 15 | /* GET home page. */ 16 | router.get('/', function(req, res) { 17 | if (req.session.user) 18 | login = req.session.user; 19 | else login = null; 20 | res.render('v2/index', 21 | { 22 | title: '首页 - CodeBursts!', 23 | nav: nav, 24 | ranklist: ranklist, 25 | login: login 26 | }); 27 | }); 28 | 29 | module.exports = router; 30 | 31 | -------------------------------------------------------------------------------- /routes/login.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var JSON = require('JSON'); 3 | var router = express.Router(); 4 | var db = require('../model/dbquery'); 5 | 6 | var nav = [ 7 | { name: '首页', ref: '/', active: true }, 8 | { name: '问题', ref: '/problem', active: false }, 9 | { name: '状态', ref: '/status', active: false }, 10 | { name: '比赛', ref: '/contest', active: false }, 11 | { name: '排名', ref: '/ranklist', active: false } 12 | ]; 13 | 14 | router.get('/', function(req, res) { 15 | res.render('login', { title: '登陆 - CodeBursts!', nav: nav }); 16 | }); 17 | 18 | router.get('/register', function(req, res) { 19 | res.render('login/register', { title: '注册 - CodeBursts!', nav: nav }); 20 | }); 21 | 22 | router.post('/register', function(req, res) { 23 | var username = req.param('user'); 24 | var password = req.param('pass'); 25 | if (!(/^[a-zA-Z0-9_]{3,16}$/.test(username))) { 26 | res.send({stat: 0}); 27 | res.end(); 28 | } else { 29 | db.getUserByName(username, function(err, docs) { 30 | if (err) throw err; 31 | if (docs) { 32 | res.send({stat: 0}); 33 | res.end(); 34 | return; 35 | } else { 36 | db.insertUser({name: username, pass: password}, function(err, doc) { 37 | if (err) throw err; 38 | res.send({stat: 1}); 39 | res.end(); 40 | }); 41 | } 42 | }); 43 | } 44 | }); 45 | 46 | router.get('/register/success', function(req, res) { 47 | res.render('login/success', { title: '注册成功 - CodeBursts!', nav: nav }); 48 | }); 49 | 50 | router.get('/logout', function(req, res) { 51 | req.session.user = null; 52 | res.redirect('back'); 53 | }); 54 | 55 | router.post('/auth', function(req, res) { 56 | req.session.user = null; 57 | var password = req.param('password'); 58 | var username = req.param('username'); 59 | db.getUserByName(username, function(err, docs) { 60 | if (err) throw err; 61 | if (!docs) { 62 | res.send({stat: "failed"}); 63 | res.end(); 64 | return; 65 | } 66 | if (docs.pass == password) { 67 | req.session.user = { 68 | username: username, 69 | password: password, 70 | admin: docs.admin 71 | }; 72 | res.send({stat: "success"}); 73 | res.end(); 74 | } else { 75 | res.send({stat: "failed"}); 76 | res.end(); 77 | } 78 | }); 79 | }); 80 | 81 | module.exports = router; 82 | 83 | -------------------------------------------------------------------------------- /routes/problem.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var p = require('../model/problem'); 4 | 5 | var nav = [ 6 | { name: '首页', ref: '/', active: false }, 7 | { name: '问题', ref: '/problem', active: true }, 8 | { name: '状态', ref: '/status', active: false }, 9 | { name: '比赛', ref: '/contest', active: false }, 10 | { name: '排名', ref: '/ranklist', active: false } 11 | ]; 12 | 13 | var problems, login; 14 | 15 | var perPage = 100; 16 | 17 | function getProblems(pageId, callback) { 18 | p.fetchProblems(1 + perPage * (pageId - 1), perPage, function(err, doc) { 19 | if (err) return; 20 | problems = doc; 21 | callback(); 22 | }); 23 | } 24 | 25 | router.get('/', function(req, res) { 26 | if (req.session.user) login = req.session.user; 27 | else login = null; 28 | getProblems(1, function() { 29 | for (var i = 0; i < problems.length; ++ i) { 30 | if (problems[i].avail == false && !(req.session.user && req.session.user.admin)) { 31 | problems[i].name = '这是权限题'; 32 | } 33 | } 34 | res.render('v2/problem', { title: '问题 - CodeBursts!', nav: nav, problems: problems, login: login }); 35 | }); 36 | }); 37 | 38 | router.get('/:pageId', function(req, res) { 39 | if (req.session.user) login = req.session.user; 40 | else login = null; 41 | getProblems(req.params.pageId, function() { 42 | res.render('v2/problem', { title: '问题 - CodeBursts!', nav: nav, problems: problems, login: login }); 43 | }); 44 | }); 45 | 46 | module.exports = router; 47 | 48 | -------------------------------------------------------------------------------- /routes/problems.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var md = require('marked'); 4 | var p = require('../model/problems'); 5 | 6 | 7 | var nav = [ 8 | { name: '首页', ref: '/', active: false }, 9 | { name: '问题', ref: '/problem', active: true }, 10 | { name: '状态', ref: '/status', active: false }, 11 | { name: '比赛', ref: '/contest', active: false }, 12 | { name: '排名', ref: '/ranklist', active: false } 13 | ]; 14 | 15 | var problemId, user; 16 | 17 | router.get('/:problemId', function(req, res) { 18 | problemId = Number(req.params.problemId); 19 | if (req.session.user) 20 | user = req.session.user; 21 | else user = null; 22 | p.fetchProblem(problemId, function(err, doc) { 23 | if ((doc && doc.avail) || (doc && doc.avail == false && user && user.admin)) res.render('problems', { problemId: problemId, title: problemId + ' - 问题 - CodeBursts!', nav: nav, md: md, doc: doc, login: user}); 24 | else { 25 | if (doc && doc.avail == false) { 26 | var error = {status: '权限狗专用入口', stack: '玛雅这是权限题!少侠请回吧……要权限请联系jcpwfloi@163.com'}; 27 | res.render('error', {error: error}); 28 | error = null; 29 | } else { 30 | var error = {status: 404, stack: '404 not found'}; 31 | res.render('error', {error: error}); 32 | error = null; 33 | } 34 | } 35 | }); 36 | }); 37 | 38 | module.exports = router; 39 | 40 | -------------------------------------------------------------------------------- /routes/status.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var stats = require('../model/submission'); 4 | var judger = require('../model/judger'); 5 | var Step = require('step'); 6 | 7 | var nav = [ 8 | { name: '首页', ref: '/', active: false }, 9 | { name: '问题', ref: '/problem', active: false }, 10 | { name: '状态', ref: '/status', active: true }, 11 | { name: '比赛', ref: '/contest', active: false }, 12 | { name: '排名', ref: '/ranklist', active: false } 13 | ]; 14 | 15 | router.get('/', function(req, res) { 16 | stats.getstats(1, function(arr) { 17 | res.render('status', {status: arr, nav: nav, title: '状态 - CodeBursts!'}); 18 | }); 19 | }); 20 | 21 | router.get('/problem/:problemId', function(req, res) { 22 | var problemId = req.params.problemId; 23 | stats.getprob(problemId, function(arr) { 24 | res.render('status', {status: arr, nav: nav, title: '状态 - CodeBursts!'}); 25 | }); 26 | }); 27 | 28 | router.get('/page/:pageId', function(req, res) { 29 | var pageId = req.params.pageId; 30 | stats.getstats(pageId, function(arr) { 31 | res.render('status', {status: arr, nav: nav, title: '状态 - CodeBursts!'}); 32 | }); 33 | }); 34 | 35 | router.get('/user/:userId', function(req, res) { 36 | stats.getProbByUser(req.params.userId, function(arr) { 37 | res.render('status', {status: arr, nav: nav, title: '状态 - CodeBursts!'}); 38 | }); 39 | }); 40 | 41 | router.get('/:submissionId', function(req, res) { 42 | var submissionId = req.params.submissionId; 43 | submissionId = Number(submissionId); 44 | Step( 45 | function() { 46 | judger.getSubmission(Number(submissionId), this); 47 | }, 48 | function(err, doc) { 49 | if ((req.session.user && doc && (req.session.user.username == doc.user || req.session.user.admin)) || (doc && doc.pub)) { 50 | res.render('status/view', { nav: nav, title: submissionId + ' - 记录 - CodeBursts!', doc: doc}); 51 | } else res.redirect('back'); 52 | } 53 | ); 54 | }); 55 | 56 | module.exports = router; 57 | 58 | -------------------------------------------------------------------------------- /routes/submit.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var cr = require('../model/core'); 4 | var fs = require('fs'); 5 | var cp = require('child_process'); 6 | var Step = require('step'); 7 | var judger = require('../model/judger'); 8 | 9 | var nav = [ 10 | { name: '首页', ref: '/', active: true }, 11 | { name: '问题', ref: '/problem', active: false }, 12 | { name: '状态', ref: '/status', active: false }, 13 | { name: '比赛', ref: '/contest', active: false }, 14 | { name: '排名', ref: '/ranklist', active: false } 15 | ]; 16 | 17 | var submission, problemId, title; 18 | 19 | router.get('/', function(req, res) { 20 | if (!req.session.user) 21 | res.render('login', { title: '登陆 - CodeBursts!', nav: nav }); 22 | else { 23 | var title = '提交 - CodeBursts!'; 24 | res.render('submit', { title: title, problemId: '', nav: nav }); 25 | } 26 | }); 27 | 28 | router.get('/success', function(req, res) { 29 | res.render('submit/success', { title: '提交成功 - CodeBursts!', nav: nav }); 30 | }); 31 | 32 | router.get('/failure', function(req, res) { 33 | res.render('submit/failure', { title: '提交失败 - CodeBursts!', nav: nav }); 34 | }); 35 | 36 | router.post('/', function(req, res) { 37 | if (!req.session.user) { 38 | res.redirect(302, '/submit/failure'); 39 | res.end(); 40 | return; 41 | } 42 | //res.redirect(302, '/status'); 43 | //res.end(); 44 | var problemId = req.param('problemId'); 45 | var language = req.param('Language'); 46 | var code = req.param('code'); 47 | Step( 48 | function() { 49 | require('../model/problems').fetchProblem(Number(problemId), this); 50 | }, 51 | function(err, doc) { 52 | if (!doc || (!doc.avail && !(req.session.user && req.session.user.admin))) { 53 | res.render('error', {error: {status: 404, stack: '根本没有这种问题!是假的!'}}); 54 | doc = null; 55 | return; 56 | } 57 | this(); 58 | }, 59 | function() { 60 | res.redirect('/status'); 61 | res.end(); 62 | this(); 63 | }, 64 | function() { 65 | cr.querySubmissionNum(this); 66 | }, 67 | function(err, sum) { 68 | submission = 69 | { 70 | problemId: problemId, 71 | language: language, 72 | code: code, 73 | submissionId: sum + 1, 74 | user: req.session.user.username 75 | }; 76 | cr.addSubmission(submission, this); 77 | }, 78 | function() { 79 | fs.exists(__dirname + '/../../judger/judge.lock', this); 80 | }, 81 | function(exists) { 82 | if (!exists) { 83 | judger.doJudge(); 84 | } 85 | } 86 | ); 87 | }); 88 | 89 | router.get('/:problemId', function(req, res) { 90 | if (!req.session.user) { 91 | res.render('login', { title: '登陆 - CodeBursts!', nav: nav }); 92 | return; 93 | } 94 | problemId = req.params.problemId; 95 | title = problemId + ' - 提交 - CodeBursts!'; 96 | res.render('submit', { title: title, problemId: problemId, nav: nav }); 97 | }); 98 | 99 | module.exports = router; 100 | -------------------------------------------------------------------------------- /routes/users.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | /* GET users listing. */ 5 | router.get('/', function(req, res) { 6 | res.send('respond with a resource'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /utils/stats.js: -------------------------------------------------------------------------------- 1 | var mongo = require('mongodb').MongoClient; 2 | 3 | function setresult(id, ac, all) { 4 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 5 | db.collection('problem', function(err, collection) { 6 | collection.update({id: id}, {$set: {ac: ac, all: all}}, function(err, doc) {}); 7 | }); 8 | db.collection('problems', function(err, collection) { 9 | collection.update({id: id}, {$set: {ac: ac, all: all}}, function(err, doc) {}); 10 | }); 11 | }); 12 | } 13 | 14 | function addall(id) { 15 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 16 | db.collection('problem', function(err, collection) { 17 | collection.update({id: id}, {$inc: {all: 1}}, function(err, doc) {}); 18 | }); 19 | db.collection('problems', function(err, collection) { 20 | collection.update({id: id}, {$inc: {all: 1}}, function(err, doc) {}); 21 | }); 22 | }); 23 | } 24 | 25 | function addac(id) { 26 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 27 | db.collection('problem', function(err, collection) { 28 | collection.update({id: id}, {$inc: {ac: 1}}, function(err, doc) {}); 29 | }); 30 | db.collection('problems', function(err, collection) { 31 | collection.update({id: id}, {$inc: {ac: 1}}, function(err, doc) {}); 32 | }); 33 | }); 34 | } 35 | 36 | function execu() { 37 | mongo.connect('mongodb://localhost/cboj', function(err, db) { 38 | db.collection('submissions', function(err, collection) { 39 | collection.find({processed: {$ne: true}}, function(err, doc) { 40 | doc.toArray(function(err, doc1) { 41 | for (var i = 0; i < doc1.length; ++ i) { 42 | if (doc1[i].status != undefined) { 43 | if (Number(doc1[i].status) == 0) addac(Number(doc1[i].problemId)); 44 | addall(Number(doc1[i].problemId)); 45 | collection.update({submissionId: doc1[i].submissionId}, {$set: {processed: true}}, function(err, doc) {}); 46 | } 47 | } 48 | }); 49 | }); 50 | }); 51 | }); 52 | } 53 | 54 | exports.exec = execu; 55 | 56 | -------------------------------------------------------------------------------- /views/admin.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | include nav 5 | div.col-md-3 6 | ul.nav.nav-pills.nav-stacked#tabs 7 | li.active 8 | a(href='#home') 运营状态 9 | span.badge 基本完成 10 | li 11 | a(href='#params') 参数设置 12 | span.badge 未完成 13 | li 14 | a(href='#notice') 发布公告 15 | span.badge 未完成 16 | li 17 | a(href='#graph') 提交图表 18 | span.badge 未完成 19 | li 20 | a(href='#judger') 评测机状态 21 | span.badge 未完成 22 | div.col-md-9 23 | .tab-content 24 | .tab-pane.fade.in.active#home 25 | .panel.panel-info 26 | .panel-heading 27 | | 运营状态 28 | .panel-body 29 | | 服务器: Express.js 30 | br 31 | - var dateObj = new Date(); 32 | - var dateStr = dateObj.toDateString(); 33 | - var timeStr = dateObj.toTimeString(); 34 | | 服务器时间: #{dateStr + ' ' + timeStr} 35 | br 36 | br 37 | | 服务器控制:   38 | span.badge 未实现 39 | br 40 | hr(style='margin-top: 3px; margin-bottom: 5px') 41 | a.btn.btn-success 开启 42 | a.btn.btn-danger 关闭 43 | a.btn.btn-info(href='/admin/serverControl/restart') 重启 44 | a.btn.btn-primary(href='/admin/serverControl/logs' style='margin-left: 20px') 监控日志 45 | hr(style='margin-top: 5px; margin-bottom: 5px') 46 | br 47 | | 服务器后台权限分级:   48 | span.badge 未实现 49 | p(style='margin-left: 15px') 管理员: jcpwfloi, arcGravitus 50 | | 数据库备份:   51 | hr(style='margin-top: 5px; margin-bottom: 5px') 52 | a.btn.btn-success(href='/admin/serverControl/backup') 备份 53 | a.btn.btn-danger 还原 54 | a.btn.btn-info 查看云端备份 55 | .panel-footer 56 | div(style='text-align: right; position: relative') version: v0.1 by arcGravitus 57 | .tab-pane.fade#params 58 | .panel.panel-info 59 | .panel-heading 60 | | 参数设置 61 | .panel-body 62 | .panel-footer 63 | div(style='text-align: right; position: relative') version: v0.1 by arcGravitus 64 | .tab-pane.fade#notice 65 | .tab-pane.fade#graph 66 | .tab-pane.fade#judger 67 | script. 68 | $(document).ready(function() { 69 | $('#tabs a').click(function(e) { 70 | e.preventDefault(); 71 | $(this).tab('show'); 72 | }); 73 | }); 74 | 75 | -------------------------------------------------------------------------------- /views/admin/editProblems.jade: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | include ../nav 5 | link(rel='stylesheet', href='/stylesheets/editProblem.css') 6 | .col-md-3 7 | ul.nav.nav-pills.nav-stacked#tabs 8 | li.active 9 | a#detailA(href='#detail') 编辑问题 10 | li 11 | a(href='#list') 编辑问题索引 12 | .col-md-9 13 | .tab-content 14 | .tab-pane.fade#list 15 | form(action!='/admin/problems/edit/submitIndex/' + problem.id, method='POST') 16 | | 题目编号:#{problem.id}    17 | a(href!='/problems/' + problem.id) 预览 18 | hr.HR 19 | | 索引名字: 20 | input.form-control(type='text', name='name', value!=problemIndex.name) 21 | .tab-pane.fade.in.active#detail 22 | form(action!='/admin/problems/edit/submit/' + problem.id, method='POST') 23 | | 题目编号:#{problem.id}    24 | a(href!='/problems/' + problem.id) 预览 25 | br 26 | | 可用性: 27 | if problem.avail 28 | a.btn.btn-success.smallI 可用 29 | else 30 | a.btn.btn-danger.smallI 不可用 31 | br 32 | br 33 | h4.smallB 题目名称   34 | small Title 35 | hr.smallB.HR 36 | textarea.form-control(name='title', rows='1')= problem.title 37 | br 38 | br 39 | h4.smallB 题目描述   40 | small Description 41 | hr.smallB.HR 42 | textarea.form-control(name='description', rows='4')= problem.description 43 | br 44 | h4.smallB 输入格式   45 | small Input 46 | hr.smallB.HR 47 | textarea.form-control(name='input', rows='4')= problem.input 48 | br 49 | h4.smallB 输出格式   50 | small Output 51 | hr.smallB.HR 52 | textarea.form-control(name='output', rows='4')= problem.output 53 | br 54 | h4.smallB 样例输入   55 | small Sample Input 56 | hr.smallB.HR 57 | textarea.form-control(name='sampleInput', rows='4')= problem.sampleInput 58 | br 59 | h4.smallB 样例输出   60 | small Sample Output 61 | hr.smallB.HR 62 | textarea.form-control(name='sampleOutput', rows='4')= problem.sampleOutput 63 | br 64 | input.form-control(type='submit', value='提交', style='width: 60px') 65 | br 66 | script. 67 | $(document).ready(function() { 68 | $('#tabs a').click(function(e) { 69 | e.preventDefault(); 70 | $(this).tab('show'); 71 | }); 72 | }); 73 | 74 | 75 | -------------------------------------------------------------------------------- /views/admin/logs.jade: -------------------------------------------------------------------------------- 1 | mixin giveTable(i) 2 | tr 3 | td 4 | center 5 | a(href!='/admin/serverControl/logs/' + i)= i 6 | extends ../layout 7 | 8 | block content 9 | include ../nav 10 | .container-fluid 11 | .col-md-2 12 | table.table.table-striped(style='width:30%') 13 | tr 14 | th 15 | center 文件名 16 | each i in files 17 | + giveTable(i) 18 | 19 | -------------------------------------------------------------------------------- /views/admin/output.jade: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | include ../nav 5 | .container-fluid 6 | h3 err 7 | pre= err 8 | h3 stdout 9 | pre= stdout 10 | h3 stderr 11 | pre= stderr 12 | 13 | -------------------------------------------------------------------------------- /views/admin/problems.jade: -------------------------------------------------------------------------------- 1 | mixin problem(d) 2 | tr 3 | td 4 | - if (d.avail) 5 | a.statn.btn.btn-success(href!='/admin/problems/' + d.id + '/unavail', problemId!=d.id) 可用 6 | - else 7 | a.statn.btn.btn-danger(href!='/admin/problems/' + d.id + '/avail', problemId!=d.id) 不可用 8 | td= d.id 9 | td 10 | a(href='/admin/problems/edit/' + d.id)= d.name 11 | td= d.all 12 | td= d.ac 13 | td 14 | - if (d.all && d.ac) 15 | | #{Math.round(d.ac * 10000 / d.all) / 100}% 16 | - else 17 | | 0% 18 | extends ../layout 19 | 20 | block content 21 | include ../nav 22 | link(rel='stylesheet', href='/stylesheets/admin/adminProblem.css') 23 | div.col-md-3 24 | ul.nav.nav-pills.nav-stacked#tabs 25 | li.active 26 | a(href='#list') 问题列表 27 | span.badge Problems 28 | li 29 | a(href='#add') 添加问题 30 | span.badge Add Problems 31 | li 32 | a(href='#del') 删除问题 33 | span.badge 未完成 34 | div.col-md-9 35 | .tab-content 36 | .tab-pane.fade.in.active#list 37 | h2 问题列表   38 | small ProblemSet 39 | hr 40 | table.table.table-striped.table-hover 41 | th(width='9%') 可用 42 | th(width='10%') # 43 | th(width='35%') 题目名字 44 | th 提交次数 45 | th 通过次数 46 | th 通过比率 47 | each p in problems 48 | + problem(p) 49 | .tab-pane.fade#add 50 | h2 添加问题   51 | small Add Problems 52 | hr 53 | form(action='/admin/problems/add', method='POST') 54 | | 问题索引: 55 | input.form-control(name='index') 56 | br 57 | | 题目名称: 58 | input.form-control(name='title') 59 | br 60 | | 题目描述: 61 | textarea.form-control(rows='4', name='description') 62 | br 63 | | 输入格式: 64 | textarea.form-control(rows='4', name='input') 65 | br 66 | | 输出格式: 67 | textarea.form-control(rows='4', name='output') 68 | br 69 | | 样例输入: 70 | textarea.form-control(rows='4', name='sampleInput') 71 | br 72 | | 样例输出: 73 | textarea.form-control(rows='4', name='sampleOutput') 74 | br 75 | input.form-control(type='submit', value='添加', style='width: 60px') 76 | br 77 | .tab-pane.fade#del 78 | script $(document).ready(function(){$('#tabs a').click(function(e){e.preventDefault();$(this).tab('show');});}); 79 | 80 | -------------------------------------------------------------------------------- /views/admin/users.jade: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | include ../nav 5 | -------------------------------------------------------------------------------- /views/error.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | .container-fluid 5 | h1= message 6 | h2= error.status 7 | pre #{error.stack} 8 | -------------------------------------------------------------------------------- /views/index.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | include nav 5 | div.container-fluid 6 | div.col-md-9 7 | include index/left 8 | div.col-md-3 9 | include index/right 10 | h5(style='position: relative; bottom: 0') 11 | center 12 | small 备案信息:沪ICP备15007332号-1 13 | -------------------------------------------------------------------------------- /views/index/left.jade: -------------------------------------------------------------------------------- 1 | mixin notice(data) 2 | .panel.panel-info 3 | .panel-heading 4 | .panel-body 5 | .panel-footer 6 | div.jumbotron 7 | h1 CodeBursts! 8 | p 这是一个非盈利性的程序在线评测系统 9 | p 10 | if !login || !login.username 11 | a.btn.btn-primary.btn-lg(href='/login/register') 点此注册 12 | a.btn.btn-success.btn-lg(href='/login') 点此登陆 13 | else 14 | a.btn.btn-primary.btn-lg(href='#') 欢迎您, 15 | span(style='font-family: courier') #{login.username} 16 | a.btn.btn-success.btn-lg(href='/login/logout', style='margin-left: 10px') 登出 17 | if login.admin 18 | a.btn.btn-danger.btn-lg(href='/admin', style='margin-left: 10px') 进入管理后台 19 | a.btn.btn-info.btn-lg(href='/v2', style='margin-left: 10px') CodeBursts! v2 20 | h2   公告    21 | small notice 22 | hr 23 | 24 | if notice && notice.cnt 25 | - for (var i = 0; i < notice.cnt; ++ i) 26 | else 27 | h5(align='center') 木有公告 28 | -------------------------------------------------------------------------------- /views/index/right.jade: -------------------------------------------------------------------------------- 1 | h3 分数排名    2 | small rating ranklist 3 | hr 4 | table.table-striped.table 5 | tr 6 | th(width='70px') # 7 | th name 8 | th rating 9 | - for (var i = 0; i < 10; ++ i) 10 | if ranklist[i] && ranklist[i].name 11 | tr 12 | td= i + 1 13 | td(rating!=ranklist[i].rating)= ranklist[i].name 14 | td= ranklist[i].rating 15 | else 16 | tr 17 | td= i + 1 18 | td / 19 | td / 20 | 21 | -------------------------------------------------------------------------------- /views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title= title 5 | meta(http-equiv='Content-Type' content='text/html; charset=utf8') 6 | script(src='https://dn-codebursts.qbox.me/jquery.min.js') 7 | script(src='https://dn-codebursts.qbox.me/jquery.md5.js') 8 | script(src='https://dn-codebursts.qbox.me/bootstrap.min.js') 9 | script(src='https://dn-codebursts.qbox.me/rating.js') 10 | script(src='//cdnjscn.b0.upaiyun.com/libs/mathjax/2.4.0/MathJax.js?config=TeX-AMS_HTML') 11 | script(type='text/x-mathjax-config') 12 | script. 13 | MathJax.Hub.Config({ 14 | showProcessingMessages: false, 15 | tex2jax: { 16 | inlineMath: [["$", "$"]], 17 | processEscapes: true 18 | }, 19 | menuSettings: { 20 | zoom: "Hover" 21 | }, 22 | messageStyle: "none" 23 | }); 24 | link(rel='stylesheet', href='https://dn-codebursts.qbox.me/bootstrap.min.css') 25 | link(rel='stylesheet', href='https://dn-codebursts.qbox.me/style.css') 26 | body 27 | block content 28 | div(style='display:none') 29 | script var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1254769757'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s11.cnzz.com/z_stat.php%3Fid%3D1254769757' type='text/javascript'%3E%3C/script%3E")); 30 | -------------------------------------------------------------------------------- /views/login.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | script(src='/javascripts/login/login.js') 5 | include nav 6 | .container-fluid 7 | .col-md-4 8 | .col-md-4 9 | .col-md-2 10 | .col-md-8 11 | br 12 | div.login-message 13 | br 14 | br 15 | br 16 | .form-group 17 | label 邮箱地址/用户名 18 | input.form-control#username(type='email') 19 | .form-group 20 | label 密码 21 | input.form-control#password(type='password') 22 | .checkbox 23 | label 24 | input(type='checkbox') 25 | | 记住我(10天) 26 | button.btn.btn-default#submit 提交 27 | a.btn.btn-success(href='/login/register') 立即注册 28 | 29 | -------------------------------------------------------------------------------- /views/login/register.jade: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | script(src='/javascripts/login/register.js') 5 | include ../nav 6 | .container-fluid 7 | .col-md-4 8 | .col-md-4 9 | .col-md-2 10 | .col-md-8 11 | div.register-message 12 | br 13 | br 14 | .form-group 15 | label 用户名 16 | input.form-control#user(type='email') 17 | .form-group 18 | label 密码 19 | input.form-control#pass(type='password') 20 | .form-group 21 | label 重复密码 22 | input.form-control#reppass(type='password') 23 | .checkbox 24 | label 25 | input(type='checkbox') 26 | | 同意以下 27 | a(href='/tos') 协议 28 | button.btn.btn-default#submit 注册 29 | button.btn.btn-success.disabled GitHub登陆(未开通) 30 | 31 | -------------------------------------------------------------------------------- /views/login/success.jade: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | include ../nav 5 | script(src='/javascripts/login/success.js') 6 | br 7 | br 8 | h1(style='text-align: center; position: relative') 恭喜您注册成功! 9 | h3(style='text-align: center; position: relative') 10 | span#cnt 3 11 | | 秒后将自动跳转到首页...... 12 | -------------------------------------------------------------------------------- /views/nav.jade: -------------------------------------------------------------------------------- 1 | script $(document).ready(function(){$('.tooltip1').tooltip({});}); 2 | nav.navbar.navbar-default.navbar-inverse 3 | div.container-fluid 4 | div.navbar-header 5 | a.navbar-brand(href='/') CodeBursts! 6 | div.collapse.navbar-collapse 7 | ul.nav.navbar-nav 8 | - each navli in nav 9 | case navli.active 10 | when false 11 | li 12 | a.tooltip1(href!=navli.ref, data-toggle='tooltip', data-placement='bottom', data-original-title!=navli.name)= navli.name 13 | - //a(href!=navli.ref)= navli.name 14 | when true 15 | li.active 16 | a.tooltip1(href!=navli.ref, data-toggle='tooltip', data-placement='bottom', data-original-title!=navli.name)= navli.name 17 | - //a(href!=navli.ref)= navli.name 18 | 19 | -------------------------------------------------------------------------------- /views/problem.jade: -------------------------------------------------------------------------------- 1 | mixin problem(d) 2 | tr(class!=d.styl) 3 | td= d.stat 4 | td= d.id 5 | td 6 | a(href!='/problems/' + d.id)= d.name 7 | td= d.ac 8 | td= d.all 9 | td 10 | - if (d.all && d.ac) 11 | | #{Math.round(d.ac * 10000 / d.all) / 100}% 12 | - else 13 | | 0% 14 | 15 | extends layout 16 | 17 | block content 18 | include nav 19 | div.col-md-9 20 | h2 问题列表   21 | small problemset 22 | hr 23 | table.table.table-striped.table-hover 24 | th(width='9%') 状态 25 | th(width='10%') # 26 | th(width='35%') 题目名字 27 | th 通过次数 28 | th 提交次数 29 | th 通过比率 30 | each p in problems 31 | + problem(p) 32 | div.col-md-3 33 | 34 | -------------------------------------------------------------------------------- /views/problems.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | link(rel='stylesheet', href='/stylesheets/problems.css') 5 | include nav 6 | div.col-md-9 7 | h3(style='position: relative;text-align: center') 8 | - if (doc && doc.title) 9 | | #{doc.title} 10 | center 11 | | 时间限制: 1 Second(s) 12 | br 13 | | 内存限制: 256 MegaByte(s) 14 | h3 题目描述   15 | small Description 16 | hr 17 | div.cont 18 | span.markdown-text 19 | - if (doc && doc.description) 20 | | !{md(doc.description)} 21 | h3 输入要求   22 | small Input 23 | hr 24 | div.cont 25 | span.markdown-text 26 | - if (doc && doc.input) 27 | | !{md(doc.input)} 28 | h3 输出要求   29 | small Output 30 | hr 31 | div.cont 32 | span.markdown-text 33 | - if (doc && doc.output) 34 | | !{md(doc.output)} 35 | h3 样例输入   36 | small Sample Input 37 | hr 38 | div.cont 39 | pre 40 | - if (doc && doc.sampleInput) 41 | | #{doc.sampleInput} 42 | h3 样例输出   43 | small Sample Output 44 | hr 45 | div.cont 46 | pre 47 | - if (doc && doc.sampleOutput) 48 | | #{doc.sampleOutput} 49 | div.col-md-3 50 | .panel.panel-info 51 | .panel-heading 52 | | 题目信息 53 | .panel-body 54 | | 提交次数:   55 | - if (doc && doc.all) 56 | - var all = doc.all; 57 | | #{doc.all} 58 | - else 59 | | 0 60 | br 61 | | 通过次数:   62 | - if (doc && doc.ac) 63 | - var ac = doc.ac; 64 | | #{doc.ac} 65 | - else 66 | | 0 67 | br 68 | | 通过比率:   69 | - if (ac && all) 70 | | #{Math.round(ac * 10000 / all) / 100}% 71 | - else 72 | | 0% 73 | br 74 | br 75 | a.btn.btn-primary.btn-large(href!='/submit/' + problemId) 提交 76 | a.btn.btn-success.btn-large(href!='/status/problem/' + problemId) 查看统计信息 77 | if (login && login.username && login.admin) 78 | a.btn.btn-info.btn-danger(href!='/admin/problems/edit/' + problemId) 编辑问题 79 | .panel-footer 80 | div(style='position: relative; text-align: right') 本题由CodeBursts!提供 81 | 82 | -------------------------------------------------------------------------------- /views/status.jade: -------------------------------------------------------------------------------- 1 | mixin giveTable(stat) 2 | tr 3 | td 4 | a.btn.btn-primary.btnsmall(href!='/status/' + stat.submissionId)= stat.submissionId 5 | td 6 | a(href!='/status/user/' + stat.user)= stat.user 7 | td 8 | a(href!='/problems/' + stat.problemId)= stat.problemId 9 | case stat.language 10 | when '0' 11 | td C++ 12 | when '1' 13 | td Pascal 14 | when '2' 15 | td Python 2 16 | when '3' 17 | td C++11 18 | when '4' 19 | td JavaScript 20 | case stat.status 21 | when undefined 22 | td 等待评测 23 | when 0 24 | td 25 | a.btn.btn-success.btnsmall 答案正确 26 | when 1 27 | td 28 | a.btn.btn-danger.btnsmall 错误的答案 29 | when 2 30 | td 31 | a.btn.btn-warning.btnsmall 超过时间限制 32 | when 3 33 | td 34 | a.btn.btn-warning.btnsmall 运行时错误 35 | when 4 36 | td 37 | a.btn.btn-default.btnsmall 编译错误 38 | when 5 39 | td 正在评测.... 40 | td= stat.score 41 | if stat.usedTime 42 | td= stat.usedTime.toString() + 'ms' 43 | else 44 | td / 45 | extends layout 46 | 47 | block content 48 | include nav 49 | link(rel='stylesheet', href='/stylesheets/status.css') 50 | .col-md-9 51 | h3 状态显示   52 | small Status 53 | hr(style='margin: 0 0 0 0') 54 | br 55 | table.table-striped.table 56 | tr 57 | th(style='width: 80px') 提交编号 58 | th(style='width: 120px') 提交人 59 | th(style='width: 80px') 题目编号 60 | th(style='width: 80px') 语言 61 | th(style='width: 150px') 状态 62 | th(style='width: 60px') 分数 63 | th 用时 64 | each stat in status 65 | + giveTable(stat) 66 | .col-md-3 67 | 68 | -------------------------------------------------------------------------------- /views/status/view.jade: -------------------------------------------------------------------------------- 1 | mixin giveStatus(id, stat) 2 | tr 3 | td= id 4 | case stat 5 | when 0 6 | td Accepted 7 | when 1 8 | td Wrong Answer 9 | when 2 10 | td Time limit Exceeded 11 | when 3 12 | td Runtime Error 13 | when 4 14 | td Compile Error 15 | extends ../layout 16 | 17 | block content 18 | include ../nav 19 | .col-md-9 20 | h3 提交的代码   21 | small Submitted Code 22 | hr 23 | case doc.language 24 | when '0' 25 | pre 26 | code.sh_cpp= doc.code 27 | when '1' 28 | pre 29 | code.sh_pas= doc.code 30 | when '2' 31 | pre 32 | code.sh_py= doc.code 33 | when '3' 34 | pre 35 | code.sh_cpp= doc.code 36 | when '4' 37 | pre 38 | code.sh_js= doc.code 39 | if doc.compilerMessage 40 | h3 编译信息   41 | small Compiler Message 42 | hr 43 | pre= doc.compilerMessage 44 | h3 数据点状态   45 | small Data Status 46 | hr 47 | table.table.table-striped 48 | tr 49 | th(style='width: 100px') 数据点编号 50 | th 数据点状态 51 | - var len = doc.result ? doc.result.length : 0; 52 | - for (var i = 0; i < len; ++ i) 53 | + giveStatus(i, doc.result[i]) 54 | .col-md-3 55 | 56 | -------------------------------------------------------------------------------- /views/submit.jade: -------------------------------------------------------------------------------- 1 | extends layout 2 | 3 | block content 4 | include nav 5 | .col-md-3 6 | .col-md-6 7 | form(action='/submit', method='POST') 8 | br 9 | | 题目编号   10 | span.badge Problem Id 11 | input.form-control(type='text', name='problemId', value!=problemId, style='width: 200px; margin-top: 5px; margin-bottom: 5px') 12 | | 语言选择   13 | span.badge Language 14 | select.form-control(name='Language', style='width: 200px; margin-top: 5px; margin-bottom: 5px') 15 | option(value='0') GNU C++ 16 | option(value='1') Pascal 17 | option(value='2') Python 2 18 | option(value='3') GNU C++ 11 19 | option(value='4') Node.js 20 | | 程序提交   21 | textarea.form-control(name='code', rows='15') 22 | br 23 | input.form-control(type='submit', value='提交', style='width: 60px') 24 | .col-md-3 25 | 26 | -------------------------------------------------------------------------------- /views/submit/success.jade: -------------------------------------------------------------------------------- 1 | extends ../layout 2 | 3 | block content 4 | include ../nav 5 | br 6 | br 7 | br 8 | center 9 | h2 提交成功 10 | 11 | -------------------------------------------------------------------------------- /views/v2/index.jade: -------------------------------------------------------------------------------- 1 | doctype html 2 | //- 3 | Transit by TEMPLATED 4 | templated.co @templatedco 5 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 6 | html(lang='en') 7 | head 8 | meta(charset='UTF-8') 9 | title Index Page - CodeBursts 10 | meta(http-equiv='content-type', content='text/html; charset=utf-8') 11 | meta(name='description', content='OnlineJudge') 12 | meta(name='keywords', content='NOI,NOIP,OI,评测,评测系统,CodeBursts,在线评测') 13 | //if lte IE 8 14 | script(src='https://ostatic-codebursts-com.alikunlun.com/js/html5shiv.js') 15 | script(src='https://ostatic-codebursts-com.alikunlun.com/js/jquery.min.js') 16 | script(src='https://ostatic-codebursts-com.alikunlun.com/js/skel.min.js') 17 | script(src='https://ostatic-codebursts-com.alikunlun.com/js/skel-layers.min.js') 18 | script(src='https://ostatic-codebursts-com.alikunlun.com/js/init.js') 19 | script var cnzz_protocol = (("https:" == document.location.protocol) ? "https://" : "http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1254769757', style='display: none'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s11.cnzz.com/z_stat.php%3Fid%3D1254769757' type='text/javascript'%3E%3C/script%3E")); 20 | noscript 21 | link(rel='stylesheet', href='css/skel.css') 22 | link(rel='stylesheet', href='css/style.css') 23 | link(rel='stylesheet', href='css/style-xlarge.css') 24 | body.landing 25 | // Header 26 | header#header 27 | h1 28 | a(href='/') CodeBursts 29 | include utils/nav 30 | // Banner 31 | section#banner 32 | h2 Welcome to CodeBursts! 33 | p This is an OnlineJudge System hosted for OIers. 34 | ul.actions 35 | if login && login.username 36 | li 37 | a.button.big(href='#') Welcome, #{login.username}! 38 | if login.admin 39 | li 40 | a.button(href='/admin', style='background-color: red') Admin Panel 41 | else 42 | li 43 | a.button(href='/login/logout', style='background-color: red') Logout 44 | else 45 | li 46 | a.button.big(href='/login/register') 立即注册 47 | li 48 | a.button(href='/login', style='background-color: red') 登陆 49 | // One 50 | section#one.wrapper.style1.special 51 | .container 52 | header.major 53 | h2 Latest Notice 54 | p Latest Notice of CodeBursts 55 | .row(class='150%') 56 | .4u(class='12u$(medium)') 57 | section.box 58 | i.icon.big.rounded.color1.fa-cloud 59 | h3 OJ开业辣! 60 | p 上面刚刚放了3道题,2题是CERC2014的,好像挺有意思的= = 61 | .4u(class='12u$(medium)') 62 | section.box 63 | i.icon.big.rounded.color9.fa-desktop 64 | h3 Nothing 65 | p Nothing 66 | div(class='4u$ 12u$(medium)') 67 | section.box 68 | i.icon.big.rounded.color6.fa-rocket 69 | h3 Nothing 70 | p Nothing 71 | // Two 72 | section#two.wrapper.style2.special 73 | .container 74 | header.major 75 | h2 Ranklist 76 | p These are people who are top 8 of the OnlineJudge, if you want to be here, just compete in the contests! 77 | section.profiles 78 | .row 79 | section.3u.profile(class='6u(medium) 12u$(xsmall)') 80 | img(src='images/profile_placeholder.gif', alt='') 81 | h4 Nobody 82 | p NULL 83 | section.3u.profile(class='6u$(medium) 12u$(xsmall)') 84 | img(src='images/profile_placeholder.gif', alt='') 85 | h4 Nobody 86 | p NULL 87 | section.3u.profile(class='6u(medium) 12u$(xsmall)') 88 | img(src='images/profile_placeholder.gif', alt='') 89 | h4 Nobody 90 | p NULL 91 | section.profile(class='3u$ 6u$(medium) 12u$(xsmall)') 92 | img(src='images/profile_placeholder.gif', alt='') 93 | h4 Nobody 94 | p NULL 95 | .row 96 | section.3u.profile(class='6u(medium) 12u$(xsmall)') 97 | img(src='images/profile_placeholder.gif', alt='') 98 | h4 Nobody 99 | p NULL 100 | section.3u.profile(class='6u$(medium) 12u$(xsmall)') 101 | img(src='images/profile_placeholder.gif', alt='') 102 | h4 Nobody 103 | p NULL 104 | section.3u.profile(class='6u(medium) 12u$(xsmall)') 105 | img(src='images/profile_placeholder.gif', alt='') 106 | h4 Nobody 107 | p NULL 108 | section.profile(class='3u$ 6u$(medium) 12u$(xsmall)') 109 | img(src='images/profile_placeholder.gif', alt='') 110 | h4 Nobody 111 | p NULL 112 | footer 113 | p 114 | | If you want to host a contest or generate your own problem, feel free to join our problem-generating platform! According to our Terms of Service, we must keep the privacy of your problems, and your communication with the server is under an HTTPS secured environment, if you want to host an official contest, just feel free to contact us. 115 | ul.actions 116 | li 117 | a.button.big(href='#') Join the platform!(Developing....) 118 | // Three 119 | section#three.wrapper.style3.special 120 | .container 121 | header.major 122 | h2 Some suggestions 123 | p If you have any suggestions to this OnlineJudge System, just feel free to reply us! 124 | .container(class='50%') 125 | form(action='/suggestions', method='post') 126 | .row.uniform 127 | .6u(class='12u$(small)') 128 | input#name(name='name', value='', placeholder='Name', type='text') 129 | div(class='6u$ 12u$(small)') 130 | input#email(name='email', value='', placeholder='Email', type='email') 131 | div(class='12u$') 132 | textarea#message(name='message', placeholder='Message', rows='6') 133 | div(class='12u$') 134 | ul.actions 135 | li 136 | input.special.big(value='Send Message', type='submit') 137 | // Footer 138 | include utils/footer 139 | -------------------------------------------------------------------------------- /views/v2/problem.jade: -------------------------------------------------------------------------------- 1 | mixin problem(d) 2 | tr(class!=d.styl) 3 | td= d.stat 4 | td= d.id 5 | td 6 | a(href!='/problems/' + d.id)= d.name 7 | td= d.ac 8 | td= d.all 9 | td 10 | if d.all && d.ac 11 | | #{Math.round(d.ac * 10000 / d.all) / 100}% 12 | else 13 | | 0% 14 | 15 | doctype html 16 | //- 17 | Transit by TEMPLATED 18 | templated.co @templatedco 19 | Released for free under the Creative Commons Attribution 3.0 license (templated.co/license) 20 | html(lang='en') 21 | head 22 | meta(charset='UTF-8') 23 | title= title 24 | meta(http-equiv='content-type', content='text/html; charset=utf-8') 25 | meta(name='description', content='') 26 | meta(name='keywords', content='') 27 | //if lte IE 8 28 | script(src='js/html5shiv.js') 29 | script(src='js/jquery.min.js') 30 | script(src='js/skel.min.js') 31 | script(src='js/skel-layers.min.js') 32 | script(src='js/init.js') 33 | noscript 34 | link(rel='stylesheet', href='css/skel.css') 35 | link(rel='stylesheet', href='css/style.css') 36 | link(rel='stylesheet', href='css/style-xlarge.css') 37 | body 38 | // Header 39 | header#header 40 | h1 41 | a(href='/') CodeBursts 42 | include utils/nav 43 | // Main 44 | section#main 45 | .container 46 | section 47 | br 48 | h3 ProblemSet 49 | .table-wrapper 50 | table 51 | thead 52 | tr 53 | th(width='9%') Status 54 | th(width='10%') # 55 | th(width='35%') Name 56 | th Accepted 57 | th Submission 58 | th Ratio 59 | tbody 60 | each p in problems 61 | + problem(p) 62 | // Footer 63 | include utils/footer 64 | -------------------------------------------------------------------------------- /views/v2/utils/footer.jade: -------------------------------------------------------------------------------- 1 | footer#footer 2 | .container 3 | section.links 4 | .row 5 | section.3u(class='6u(medium) 12u$(small)') 6 | h3 Nice OnlineJudge Systems 7 | ul.unstyled 8 | li 9 | a(href='http://codeforces.com/') Codeforces 10 | li 11 | a(href='http://www.topcoder.com/tc') TopCoder 12 | li 13 | a(href='http://uoj.ac/') Universal Online Judge 14 | li 15 | a(href='http://www.codechef.com/') Codechef 16 | li 17 | a(href='http://bestcoder.hdu.edu.cn/') BestCoder 18 | section.3u(class='6u$(medium) 12u$(small)') 19 | h3 Hosting Environment 20 | ul.unstyled 21 | li 22 | a(href='#') Server: Express.js on Ubuntu 14.04.2 LTS 23 | li 24 | a(href='#') Session: Aliyun KVStore 25 | li 26 | a(href='#') Database: MongoDB v2.4.9 27 | li 28 | a(href='#') Template Engine: Jade 29 | section.3u(class='6u(medium) 12u$(small)') 30 | h3 Resources 31 | ul.unstyled 32 | li 33 | a(href='http://gnu.org/') GNU 34 | li 35 | a(href='https://github.com/') GitHub 36 | li 37 | a(href='https://coding.net/') Coding.net 38 | section(class='3u$ 6u$(medium) 12u$(small)') 39 | h3 Contact Info 40 | ul.unstyled 41 | li 42 | a(href='#') Address: 555 Chenhui Rd., Pudong District, Shanghai, China 43 | li 44 | a(href='#') Postal Code: 201203 45 | li 46 | a(href='#') Tel: 021-50801890 47 | li 48 | a(href='#') Fax: 021-50804338 49 | li 50 | a(href='mailto:jcpwfloi@gmail.com') Email: jcpwfloi@gmail.com 51 | .row 52 | .8u(class='12u$(medium)') 53 | ul.copyright 54 | li CodeBursts©2015. All rights reserved. 55 | li 56 | | Design: 57 | a(href='http://templated.co') TEMPLATED 58 | li 59 | | Images: 60 | a(href='http://unsplash.com') Unsplash 61 | li 62 | | 备案信息: 63 | a(href='http://www.miitbeian.gov.cn/') 沪ICP备15007332号-1 64 | div(class='4u$ 12u$(medium)') 65 | ul.icons 66 | li 67 | a.icon.rounded.fa-facebook 68 | span.label Facebook 69 | li 70 | a.icon.rounded.fa-twitter 71 | span.label Twitter 72 | li 73 | a.icon.rounded.fa-google-plus 74 | span.label Google+ 75 | li 76 | a.icon.rounded.fa-linkedin 77 | span.label LinkedIn 78 | -------------------------------------------------------------------------------- /views/v2/utils/nav.jade: -------------------------------------------------------------------------------- 1 | nav#nav 2 | ul 3 | li 4 | a(href='/') 首页 5 | li 6 | a(href='/problem') 问题 7 | li 8 | a(href='/status') 状态 9 | if login && login.username 10 | li 11 | a(href='#') 欢迎您, #{login.username}! 12 | li 13 | a.button.special(href='/login/logout') 注销 14 | else 15 | li 16 | a.button.special(href='/login') 登陆 17 | --------------------------------------------------------------------------------