mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-17 09:36:08 +08:00
template: problem_detail
This commit is contained in:
1 parent
2e23d05a59
commit
ffa193b5dd
43 files changed
+263
-240
No files matched your search
@@ -16,6 +16,11 @@ process.on('restart', async () => {
|
||||
delete require.cache;
|
||||
run();
|
||||
});
|
||||
const path = require('path');
|
||||
const i18n = require('./lib/i18n');
|
||||
i18n(path.resolve(__dirname, '..', 'locales', 'zh_CN.yaml'), 'zh_CN');
|
||||
|
||||
|
||||
const EventEmitter = require('events');
|
||||
global.bus = new EventEmitter();
|
||||
async function run() {
|
||||
@@ -27,13 +32,14 @@ async function run() {
|
||||
});
|
||||
});
|
||||
let server = require('./service/server');
|
||||
require('./lib/i18n');
|
||||
|
||||
require('./handler/ui');
|
||||
require('./handler/base');
|
||||
require('./handler/home');
|
||||
require('./handler/problem');
|
||||
require('./handler/record');
|
||||
require('./handler/judge');
|
||||
require('./handler/user');
|
||||
server.start();
|
||||
}
|
||||
run().catch(e => {
|
||||
|
||||
@@ -15,13 +15,9 @@ MIDDLEWARE(async (ctx, next) => {
|
||||
let sid = ctx.cookies.get('sid');
|
||||
let save = ctx.cookies.get('save');
|
||||
let tokenType, expireSeconds;
|
||||
if (save) {
|
||||
tokenType = token.TYPE_SAVED_SESSION;
|
||||
expireSeconds = options.session.saved_expire_seconds;
|
||||
} else {
|
||||
tokenType = token.TYPE_UNSAVED_SESSION;
|
||||
expireSeconds = options.session.unsaved_expire_seconds;
|
||||
}
|
||||
tokenType = token.TYPE_SESSION;
|
||||
if (save) expireSeconds = options.session.saved_expire_seconds;
|
||||
else expireSeconds = options.session.unsaved_expire_seconds;
|
||||
ctx.session = sid ?
|
||||
await token.update(sid, tokenType, expireSeconds, Object.assign({
|
||||
update_ip: ctx.request.ip,
|
||||
@@ -48,6 +44,7 @@ MIDDLEWARE(async (ctx, next) => {
|
||||
}
|
||||
}
|
||||
};
|
||||
console.log(ctx.session.uid);
|
||||
await next();
|
||||
if (ctx.session.sid)
|
||||
await token.update(ctx.session.sid, tokenType, expireSeconds, Object.assign({
|
||||
@@ -61,7 +58,8 @@ MIDDLEWARE(async (ctx, next) => {
|
||||
update_ip: ctx.request.ip,
|
||||
update_ua: ctx.request.headers['user-agent'] || ''
|
||||
}, ctx.session));
|
||||
let cookie = { domain: options.session.domain, secure: options.session.secure, httponly: true };
|
||||
console.log(ctx.session.sid, ctx.session.uid);
|
||||
let cookie = { secure: options.session.secure, httponly: true };
|
||||
if (save) {
|
||||
cookie.expires = ctx.session.expireAt, cookie.maxAge = expireSeconds;
|
||||
ctx.cookies.set('save', 'true', cookie);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const
|
||||
{ CONTEXT } = require('../service/server'),
|
||||
{ GET, POST } = require('../service/server'),
|
||||
queue = require('../service/queue'),
|
||||
record = require('../model/record'),
|
||||
{ requirePerm } = require('./tools'),
|
||||
@@ -7,12 +7,10 @@ const
|
||||
|
||||
queue.assert('judge');
|
||||
|
||||
const { MIDDLEWARE, GET, POST } = CONTEXT();
|
||||
MIDDLEWARE(requirePerm(PERM_JUDGE));
|
||||
GET('/judge/noop', async ctx => {
|
||||
GET('/judge/noop', requirePerm(PERM_JUDGE), async ctx => {
|
||||
ctx.body = {};
|
||||
});
|
||||
GET('/judge/fetch', async ctx => {
|
||||
GET('/judge/fetch', requirePerm(PERM_JUDGE), async ctx => {
|
||||
let rid = await queue.get('judge', false);
|
||||
if (rid) {
|
||||
let rdoc = await record.get(rid);
|
||||
@@ -27,9 +25,9 @@ GET('/judge/fetch', async ctx => {
|
||||
ctx.body = data;
|
||||
}
|
||||
});
|
||||
POST('/judge/next', async ctx => {
|
||||
POST('/judge/next', requirePerm(PERM_JUDGE), async ctx => {
|
||||
console.log(ctx.request.body);
|
||||
});
|
||||
POST('/judge/end', async ctx => {
|
||||
POST('/judge/end', requirePerm(PERM_JUDGE), async ctx => {
|
||||
console.log(ctx.request.body);
|
||||
});
|
||||
@@ -38,6 +38,7 @@ GET('/p/:pid', requirePerm(PERM_VIEW_PROBLEM), async ctx => {
|
||||
let pdoc = await problem.get({ pid, uid });
|
||||
if (pdoc.hidden) ctx.checkPerm(PERM_VIEW_PROBLEM_HIDDEN);
|
||||
let udoc = await user.getById(pdoc.owner);
|
||||
ctx.templateName = 'problem_detail.html';
|
||||
ctx.body = { pdoc, udoc, title: pdoc.title };
|
||||
});
|
||||
POST('/p/:pid/submit', requirePerm(PERM_SUBMIT_PROBLEM), async ctx => {
|
||||
|
||||
+48
-8
@@ -1,25 +1,58 @@
|
||||
const
|
||||
path = require('path'),
|
||||
md5 = require('blueimp-md5'),
|
||||
static = require('koa-static'),
|
||||
nunjucks = require('nunjucks'),
|
||||
hljs = require('hljs'),
|
||||
MarkdownIt = require('markdown-it'),
|
||||
katex = require('markdown-it-katex'),
|
||||
options = require('../options'),
|
||||
perm = require('../permission'),
|
||||
builtin = require('../model/builtin'),
|
||||
{ MIDDLEWARE } = require('../service/server'),
|
||||
{ NotFoundError } = require('../error');
|
||||
{ NotFoundError } = require('../error'),
|
||||
MD5_REGEX = /^[0-9a-f]{32}$/;
|
||||
|
||||
function getHash(email) {
|
||||
email = (typeof email === 'string') ? email.trim().toLowerCase() : 'unspecified';
|
||||
return email.match(MD5_REGEX) ? email : md5(email);
|
||||
}
|
||||
|
||||
class Markdown extends MarkdownIt {
|
||||
constructor() {
|
||||
super({
|
||||
linkify: true,
|
||||
highlight: function (str, lang) {
|
||||
if (lang && hljs.getLanguage(lang))
|
||||
try {
|
||||
return hljs.highlight(lang, str).value;
|
||||
} catch (__) { } // eslint-disable-line no-empty
|
||||
return '';
|
||||
}
|
||||
});
|
||||
this.linkify.tlds('.py', false);
|
||||
this.use(katex);
|
||||
}
|
||||
}
|
||||
const md = new Markdown();
|
||||
class Nunjucks extends nunjucks.Environment {
|
||||
constructor() {
|
||||
super(
|
||||
new nunjucks.FileSystemLoader(path.resolve(options.template.path)),
|
||||
{ autoescape: true, trimBlocks: true }
|
||||
);
|
||||
this.addFilter('json', function (data) {
|
||||
return JSON.stringify(data);
|
||||
this.addFilter('json', function (self) {
|
||||
return JSON.stringify(self);
|
||||
}, false);
|
||||
this.addFilter('assign', function (self, data) {
|
||||
return Object.assign(self, data);
|
||||
});
|
||||
this.addFilter('markdown', function (self) {
|
||||
return md.render(self);
|
||||
});
|
||||
this.addFilter('gravatar_url', function (email, size) {
|
||||
return `//gravatar.loli.net/avatar/${getHash(email)}?d=mm&s=${size}`;
|
||||
});
|
||||
this.addGlobal('static_url', str => `/${str}`);
|
||||
this.addGlobal('reverse_url', str => str);
|
||||
this.addGlobal('perm', perm);
|
||||
@@ -30,8 +63,10 @@ const env = new Nunjucks();
|
||||
MIDDLEWARE(static(path.resolve(process.cwd(), '.uibuild')));
|
||||
MIDDLEWARE(async (ctx, next) => {
|
||||
ctx.render_title = str => str;
|
||||
ctx.ui_context = {};
|
||||
ctx.user_context = {};
|
||||
ctx.UIContext = {
|
||||
cdn_prefix: '/',
|
||||
url_prefix: '/'
|
||||
};
|
||||
ctx.render = async (name, context) => {
|
||||
ctx.user = ctx.state.user;
|
||||
ctx.translate = str => {
|
||||
@@ -53,12 +88,17 @@ MIDDLEWARE(async (ctx, next) => {
|
||||
try {
|
||||
await next();
|
||||
if (!ctx.body) throw new NotFoundError();
|
||||
if (ctx.query.template || ctx.templateName) {
|
||||
Object.assign(ctx.body, JSON.parse(ctx.query.data || '{}'));
|
||||
await ctx.render(ctx.query.template || ctx.templateName, ctx.body);
|
||||
} else if (ctx.setRedirect) {
|
||||
ctx.response.type = 'application/octet-stream';
|
||||
ctx.redirect(ctx.setRedirect);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.toString().startsWith('Template render error')) throw error;
|
||||
await ctx.render('error.html', { error });
|
||||
}
|
||||
Object.assign(ctx.body, JSON.parse(ctx.query.data || '{}'));
|
||||
console.log(ctx.body);
|
||||
if (ctx.query.template || ctx.templateName) await ctx.render(ctx.query.template || ctx.templateName, ctx.body);
|
||||
} catch (error) {
|
||||
await ctx.render('bsod.html', { error });
|
||||
}
|
||||
|
||||
+13
-11
@@ -12,12 +12,16 @@ const
|
||||
|
||||
GET('/user', async ctx => {
|
||||
let udoc = await user.getById(ctx.session.uid);
|
||||
ctx.templateName = 'user_detail.html';
|
||||
ctx.body = { udoc };
|
||||
});
|
||||
GET('/login', async ctx => {
|
||||
ctx.templateName = 'user_login.html';
|
||||
});
|
||||
POST('/login', async ctx => {
|
||||
let { username, password, rememberme } = ctx.request.body;
|
||||
let udoc = await user.getByUname(username);
|
||||
if (!udoc) throw new LoginError(username);
|
||||
let { uname, password, rememberme = false } = ctx.request.body;
|
||||
let udoc = await user.getByUname(uname);
|
||||
if (!udoc) throw new LoginError(uname);
|
||||
if (udoc) udoc.checkPassword(password);
|
||||
await user.setById(udoc._id, { loginat: new Date(), loginip: ctx.request.ip });
|
||||
udoc.salt = '';
|
||||
@@ -25,22 +29,20 @@ POST('/login', async ctx => {
|
||||
console.log(udoc);
|
||||
ctx.session.uid = udoc._id;
|
||||
ctx.session.rememberme = rememberme;
|
||||
ctx.body = { udoc };
|
||||
ctx.body = {};
|
||||
ctx.setRedirect = ctx.request.headers.referer || '/';
|
||||
});
|
||||
POST('/logout', requirePerm(PERM_LOGGEDIN), async ctx => {
|
||||
ctx.session = { uid: 1 };
|
||||
ctx.body = {};
|
||||
});
|
||||
let { GET: _GET, POST: _POST, MIDDLEWARE: _MIDDLEWARE } = CONTEXT();
|
||||
_MIDDLEWARE(requirePerm(PERM_REGISTER_USER));
|
||||
|
||||
_GET('/register/:code', async ctx => {
|
||||
GET('/register/:code', requirePerm(PERM_REGISTER_USER), async ctx => {
|
||||
let code = ctx.request.body.code;
|
||||
let { mail } = await token.get(code, token.TYPE_REGISTRATION);
|
||||
if (!mail) throw new InvalidTokenError(token.TYPE_REGISTRATION, code);
|
||||
ctx.body = { mail };
|
||||
});
|
||||
_GET('/register/:code', async ctx => {
|
||||
GET('/register/:code', requirePerm(PERM_REGISTER_USER), async ctx => {
|
||||
let { code, password, verify_password, uname } = ctx.request.body;
|
||||
let { mail } = await token.get(code, token.TYPE_REGISTRATION);
|
||||
if (!mail) throw new InvalidTokenError(token.TYPE_REGISTRATION, code);
|
||||
@@ -53,7 +55,7 @@ _GET('/register/:code', async ctx => {
|
||||
});
|
||||
|
||||
if (options.smtp.user) {
|
||||
_POST('/register', limitRate('send_mail', 3600, 30), async ctx => {
|
||||
POST('/register', requirePerm(PERM_REGISTER_USER), limitRate('send_mail', 3600, 30), async ctx => {
|
||||
let email = ctx.request.body.email;
|
||||
validator.check_mail(email);
|
||||
if (await user.get_by_mail(email)) throw new UserAlreadyExistError(email);
|
||||
@@ -95,7 +97,7 @@ if (options.smtp.user) {
|
||||
ctx.redirect('/');
|
||||
});
|
||||
} else
|
||||
_POST('/register', async ctx => {
|
||||
POST('/register', requirePerm(PERM_REGISTER_USER), async ctx => {
|
||||
let email = ctx.request.body.email;
|
||||
validator.check_mail(email);
|
||||
if (await user.get_by_mail(email)) throw new UserAlreadyExistError(email);
|
||||
|
||||
+2
-2
@@ -25,8 +25,8 @@ String.prototype.rawformat = function (object) {
|
||||
let res = this.split('{@}');
|
||||
return [res[0], object, res[1]];
|
||||
};
|
||||
String.prototype.translate = function (language = 'zh-CN') {
|
||||
if (locales[language]) return this;
|
||||
String.prototype.translate = function (language = 'zh_CN') {
|
||||
if (locales[language]) return locales[language][this] || this;
|
||||
else return this;
|
||||
};
|
||||
|
||||
|
||||
@@ -13,37 +13,7 @@ let server = http.createServer(app.callback());
|
||||
app.keys = options.session.keys;
|
||||
app.use(morgan(':method :url :status :res[content-length] - :response-time ms'));
|
||||
app.use(Body());
|
||||
|
||||
let router = new Router();
|
||||
let contexts = [];
|
||||
function CONTEXT() {
|
||||
this.router = new Router();
|
||||
/**
|
||||
* @param {import('koa').Middleware} middleware
|
||||
*/
|
||||
function MIDDLEWARE(middleware) {
|
||||
router.use(middleware);
|
||||
}
|
||||
/**
|
||||
* @param {string} route
|
||||
* @param {...import('koa').Middleware} handler
|
||||
*/
|
||||
function GET(route, ...handler) {
|
||||
router.get(route, ...handler);
|
||||
}
|
||||
/**
|
||||
* @param {string} route
|
||||
* @param {...import('koa').Middleware} handler
|
||||
*/
|
||||
function POST(route, ...handler) {
|
||||
router.post(route, ...handler);
|
||||
}
|
||||
this.MIDDLEWARE = MIDDLEWARE;
|
||||
this.GET = GET;
|
||||
this.POST = POST;
|
||||
contexts.push(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('koa').Middleware} middleware
|
||||
@@ -78,15 +48,12 @@ function SOCKET(prefix, handler) {
|
||||
sock.on('connection', handler);
|
||||
sock.installHandlers(server);
|
||||
}
|
||||
exports.CONTEXT = CONTEXT;
|
||||
exports.MIDDLEWARE = MIDDLEWARE;
|
||||
exports.GET = GET;
|
||||
exports.POST = POST;
|
||||
exports.SOCKET = SOCKET;
|
||||
exports.start = function start() {
|
||||
app.use(router.routes()).use(router.allowedMethods());
|
||||
for (let c of contexts)
|
||||
app.use(c.router.routes()).use(c.router.allowedMethods());
|
||||
app.listen(options.listen.port);
|
||||
console.log('Server listening at: %s', options.listen.port);
|
||||
};
|
||||
@@ -7,7 +7,9 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^0.19.0",
|
||||
"blueimp-md5": "^2.13.0",
|
||||
"bson": "^4.0.2",
|
||||
"hljs": "^6.2.3",
|
||||
"js-yaml": "^3.13.1",
|
||||
"koa": "^2.11.0",
|
||||
"koa-body": "^4.1.1",
|
||||
@@ -15,6 +17,8 @@
|
||||
"koa-router": "^7.4.0",
|
||||
"koa-static": "^5.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"markdown-it": "^10.0.0",
|
||||
"markdown-it-katex": "^2.0.3",
|
||||
"mongodb": "^3.3.4",
|
||||
"nodemailer": "^6.3.1",
|
||||
"nunjucks": "^3.2.1",
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<div class="media__left top">
|
||||
{% if not mode_create %}
|
||||
<div class="vote vote--discussion">
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_VOTE_PROBLEM_SOLUTION) %}
|
||||
{% if handler.has_perm(perm.PERM_VOTE_PROBLEM_SOLUTION) %}
|
||||
<div class="vote-number rotator--enabled">{{ doc['vote'] }}</div>
|
||||
<div class="vote-op clearfix">
|
||||
<form method="post">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{%- if not invalid %}
|
||||
<a
|
||||
{%- if tdoc is none %}
|
||||
href="{{ reverse_url('problem_detail', domain_id=pdoc['domain_id'], pid=pdoc['_id']) }}"
|
||||
href="/p/{{ pdoc.pid }}"
|
||||
{%- elif tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST %}
|
||||
href="{{ reverse_url('contest_detail_problem', domain_id=pdoc['domain_id'], pid=pdoc['_id'], tid=tdoc['doc_id']) }}"
|
||||
{%- elif tdoc['doc_type'] == vj4.model.document.TYPE_HOMEWORK %}
|
||||
@@ -29,7 +29,7 @@
|
||||
{%- if pdoc['tag']|length > 0 %}
|
||||
<ul class="problem__tags">
|
||||
{%- for tag in pdoc['tag'] %}
|
||||
<li class="problem__tag"><a class="problem__tag-link" href="{{ reverse_url('problem_category', category=tag) }}">{{ tag }}</a></li>
|
||||
<li class="problem__tag"><a class="problem__tag-link" href="/p?category={{ tag }}">{{ tag }}</a></li>
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
{%- else %}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</a>
|
||||
{% if badge %}
|
||||
<a class="user-profile-badge v-center badge--lv{{ dudoc['level']|default(0) }}" href="{{ reverse_url('user_detail', uid=udoc['_id']|default(0)) }}" title="LV {{ dudoc['level']|default(0) }}: Top {{ vj4.model.builtin.LEVELS[dudoc['level']|default(0)]|default('N/A') }}%">LV {{ dudoc['level']|default(0) }}</a>
|
||||
{% if modbadge and handler.dudoc_has_perm(udoc, dudoc, vj4.model.builtin.PERM_MOD_BADGE) %}
|
||||
{% if modbadge and handler.dudoc_has_perm(udoc, dudoc, perm.PERM_MOD_BADGE) %}
|
||||
<span class="user-profile-badge v-center badge--mod" title="Moderator">MOD</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="medium-3 columns">
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_CREATE_CONTEST) %}
|
||||
{% if handler.has_perm(perm.PERM_CREATE_CONTEST) %}
|
||||
<div class="section side">
|
||||
<div class="section__header">
|
||||
<h1 class="section__title">
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<ul class="section__footer supplementary dot list">
|
||||
{% if handler.own(ddoc, vj4.model.builtin.PERM_EDIT_DISCUSSION_SELF) or handler.has_perm(vj4.model.builtin.PERM_EDIT_DISCUSSION) %}
|
||||
{% if handler.own(ddoc, perm.PERM_EDIT_DISCUSSION_SELF) or handler.has_perm(perm.PERM_EDIT_DISCUSSION) %}
|
||||
<li>
|
||||
<a href="{{ reverse_url('discussion_edit', did=ddoc['doc_id']) }}"><span class="icon icon-edit"></span> {{ _('Edit') }}</a>
|
||||
</li>
|
||||
@@ -63,16 +63,16 @@
|
||||
udict = udict,
|
||||
comment_ref = 'drid',
|
||||
reply_ref = 'drrid',
|
||||
comment_post_perm = vj4.model.builtin.PERM_REPLY_DISCUSSION,
|
||||
comment_edit_perm = vj4.model.builtin.PERM_NONE if handler.own(ddoc, vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY_SELF_DISCUSSION) else vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY,
|
||||
comment_edit_self_perm = vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY_SELF,
|
||||
comment_delete_perm = vj4.model.builtin.PERM_NONE if handler.own(ddoc, vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY_SELF_DISCUSSION) else vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY,
|
||||
comment_delete_self_perm = vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY_SELF,
|
||||
reply_post_perm = vj4.model.builtin.PERM_REPLY_DISCUSSION,
|
||||
reply_edit_perm = vj4.model.builtin.PERM_NONE if handler.own(ddoc, vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY_SELF_DISCUSSION) else vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY,
|
||||
reply_edit_self_perm = vj4.model.builtin.PERM_EDIT_DISCUSSION_REPLY_SELF,
|
||||
reply_delete_perm = vj4.model.builtin.PERM_NONE if handler.own(ddoc, vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY_SELF_DISCUSSION) else vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY,
|
||||
reply_delete_self_perm = vj4.model.builtin.PERM_DELETE_DISCUSSION_REPLY_SELF
|
||||
comment_post_perm = perm.PERM_REPLY_DISCUSSION,
|
||||
comment_edit_perm = perm.PERM_NONE if handler.own(ddoc, perm.PERM_EDIT_DISCUSSION_REPLY_SELF_DISCUSSION) else perm.PERM_EDIT_DISCUSSION_REPLY,
|
||||
comment_edit_self_perm = perm.PERM_EDIT_DISCUSSION_REPLY_SELF,
|
||||
comment_delete_perm = perm.PERM_NONE if handler.own(ddoc, perm.PERM_DELETE_DISCUSSION_REPLY_SELF_DISCUSSION) else perm.PERM_DELETE_DISCUSSION_REPLY,
|
||||
comment_delete_self_perm = perm.PERM_DELETE_DISCUSSION_REPLY_SELF,
|
||||
reply_post_perm = perm.PERM_REPLY_DISCUSSION,
|
||||
reply_edit_perm = perm.PERM_NONE if handler.own(ddoc, perm.PERM_EDIT_DISCUSSION_REPLY_SELF_DISCUSSION) else perm.PERM_EDIT_DISCUSSION_REPLY,
|
||||
reply_edit_self_perm = perm.PERM_EDIT_DISCUSSION_REPLY_SELF,
|
||||
reply_delete_perm = perm.PERM_NONE if handler.own(ddoc, perm.PERM_DELETE_DISCUSSION_REPLY_SELF_DISCUSSION) else perm.PERM_DELETE_DISCUSSION_REPLY,
|
||||
reply_delete_self_perm = perm.PERM_DELETE_DISCUSSION_REPLY_SELF
|
||||
) }}
|
||||
{{ paginator.render(page, pcount) }}
|
||||
{% if drcount == 0 %}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<button name="operation" value="update" type="submit" class="rounded primary button">
|
||||
{{ _('Update') }} (Ctrl+Enter)
|
||||
</button>
|
||||
{% if handler.own(ddoc, vj4.model.builtin.PERM_DELETE_DISCUSSION_SELF) or handler.has_perm(vj4.model.builtin.PERM_DELETE_DISCUSSION) %}
|
||||
{% if handler.own(ddoc, perm.PERM_DELETE_DISCUSSION_SELF) or handler.has_perm(perm.PERM_DELETE_DISCUSSION) %}
|
||||
<button name="operation" value="delete" type="submit" class="rounded button">
|
||||
{{ _('Delete') }}
|
||||
</button>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</div>
|
||||
<div class="section__body">
|
||||
{% if vnode %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_CREATE_DISCUSSION) %}
|
||||
{% if handler.has_perm(perm.PERM_CREATE_DISCUSSION) %}
|
||||
<p><a href="{{ reverse_url('discussion_create', doc_id=vnode['doc_id']) }}" class="expanded primary button">{{ _('Create a Discussion') }}</a></p>
|
||||
{% else %}
|
||||
{% if not handler.has_perm(perm.PERM_LOGGEDIN) %}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
<ol class="menu collapsed">
|
||||
{{ sidemenu.render_item(null, 'domain_manage_dashboard') }}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_EDIT_DESCRIPTION) %}
|
||||
{% if handler.has_perm(perm.PERM_EDIT_DESCRIPTION) %}
|
||||
{{ sidemenu.render_item(null, 'domain_manage_edit') }}
|
||||
{{ sidemenu.render_item(null, 'domain_manage_join_applications') }}
|
||||
{{ sidemenu.render_item(null, 'domain_manage_discussion') }}
|
||||
@@ -21,7 +21,7 @@
|
||||
<!-- Ranking Settings -->
|
||||
</ol>
|
||||
</li>
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_EDIT_PERM) %}
|
||||
{% if handler.has_perm(perm.PERM_EDIT_PERM) %}
|
||||
<li class="menu__item">
|
||||
<div class="menu__link expandable">
|
||||
<span class="icon icon-user"></span> {{ _('Access Control') }}
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="large-3 columns">
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_VIEW_DISCUSSION) %}
|
||||
{% if handler.has_perm(perm.PERM_VIEW_DISCUSSION) %}
|
||||
{% include 'discussion_nodes_widget.html' %}
|
||||
{% endif %}
|
||||
{% if domain_id == vj4.model.builtin.DOMAIN_ID_SYSTEM %}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
{% for family, perms in vj4.model.builtin.PERMS_BY_FAMILY.items() %}
|
||||
{% for family, perms in perm.PERMS_BY_FAMILY.items() %}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="col--family" colspan="{{ (roles|length)+1 }}">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{% set no_path_section = true %}
|
||||
{% set page_name = "error" %}
|
||||
{% extends "layout/basic.html" %}
|
||||
{% block content %}
|
||||
<div class="error__container clearfix">
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<option value="list">{{ _('List View') }}</option>
|
||||
</select>
|
||||
</span>
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_CREATE_HOMEWORK) %}
|
||||
{% if handler.has_perm(perm.PERM_CREATE_HOMEWORK) %}
|
||||
<a class="compact button" href="{{ reverse_url('homework_create') }}">{{ _('Create Homework') }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
<script>
|
||||
var _htmlNode = document.documentElement;
|
||||
_htmlNode.className = _htmlNode.className.replace(' nojs', ' hasjs');
|
||||
var UiContext = {{ handler.ui_context|json|safe }};
|
||||
var UserContext = {{ handler.user_context|json|safe }};
|
||||
var UiContext = {{ handler.UIContext|json|safe }};
|
||||
var UserContext = {{ handler.user|json|safe }};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<div>
|
||||
<ol class="menu">
|
||||
{% if page_name == 'discussion_node' %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_CREATE_DISCUSSION) %}
|
||||
{% if handler.has_perm(perm.PERM_CREATE_DISCUSSION) %}
|
||||
<li class="menu__item"><a class="menu__link highlight" href="{{ reverse_url('discussion_create_document_as_node', doc_type=tdoc['doc_type'], doc_id=tdoc['doc_id']) }}">
|
||||
<span class="icon icon-add"></span> {{ _('Create a Discussion') }}
|
||||
</a></li>
|
||||
@@ -40,7 +40,7 @@
|
||||
{% endif %}
|
||||
{% if not attended and not handler.is_done(tdoc) %}
|
||||
<li class="menu__item">
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_ATTEND_CONTEST) and handler.has_perm(perm.PERM_LOGGEDIN) %}
|
||||
{% if handler.has_perm(perm.PERM_ATTEND_CONTEST) and handler.has_perm(perm.PERM_LOGGEDIN) %}
|
||||
<form action="{{ reverse_url('contest_detail', tid=tdoc['doc_id']) }}" method="POST">
|
||||
<input type="hidden" name="operation" value="attend">
|
||||
<input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}">
|
||||
@@ -68,12 +68,12 @@
|
||||
<span class="icon icon-statistics"></span> {{ _('Scoreboard (Hidden)') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.own(tdoc, vj4.model.builtin.PERM_EDIT_CONTEST_SELF) or handler.has_perm(vj4.model.builtin.PERM_EDIT_CONTEST) %}
|
||||
{% if handler.own(tdoc, perm.PERM_EDIT_CONTEST_SELF) or handler.has_perm(perm.PERM_EDIT_CONTEST) %}
|
||||
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('contest_edit', tid=tdoc['doc_id']) }}">
|
||||
<span class="icon icon-edit"></span> {{ _('Edit Contest') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_READ_RECORD_CODE) %}
|
||||
{% if handler.has_perm(perm.PERM_READ_RECORD_CODE) %}
|
||||
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('contest_code', tid=tdoc['doc_id']) }}">
|
||||
<span class="icon icon-download"></span> {{ _('Export All Code') }}
|
||||
</a></li>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% import "components/form.html" as form with context %}
|
||||
{% if ddoc['highlight'] or handler.has_perm(vj4.model.builtin.PERM_HIGHLIGHT_DISCUSSION) %}
|
||||
{% if ddoc['highlight'] or handler.has_perm(perm.PERM_HIGHLIGHT_DISCUSSION) %}
|
||||
{{ form.form_checkbox(label='Highlight', name='highlight', value=ddoc['highlight']|default(false)) }}
|
||||
{% endif %}
|
||||
{{ form.form_text(label='Title', name='title', value=ddoc['title']|default(''), autofocus=true, required=true) }}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
{% endif %}
|
||||
{% if not attended and not handler.is_done(tdoc) %}
|
||||
<li class="menu__item">
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_ATTEND_HOMEWORK) and handler.has_perm(perm.PERM_LOGGEDIN) %}
|
||||
{% if handler.has_perm(perm.PERM_ATTEND_HOMEWORK) and handler.has_perm(perm.PERM_LOGGEDIN) %}
|
||||
<form action="{{ reverse_url('homework_detail', tid=tdoc['doc_id']) }}" method="POST">
|
||||
<input type="hidden" name="operation" value="attend">
|
||||
<input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}">
|
||||
@@ -52,12 +52,12 @@
|
||||
<span class="icon icon-statistics"></span> {{ _('Scoreboard (Hidden)') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.own(tdoc, vj4.model.builtin.PERM_EDIT_HOMEWORK_SELF) or handler.has_perm(vj4.model.builtin.PERM_EDIT_HOMEWORK) %}
|
||||
{% if handler.own(tdoc, perm.PERM_EDIT_HOMEWORK_SELF) or handler.has_perm(perm.PERM_EDIT_HOMEWORK) %}
|
||||
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('homework_edit', tid=tdoc['doc_id']) }}">
|
||||
<span class="icon icon-edit"></span> {{ _('Edit Homework') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_READ_RECORD_CODE) %}
|
||||
{% if handler.has_perm(perm.PERM_READ_RECORD_CODE) %}
|
||||
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('homework_code', tid=tdoc['doc_id']) }}">
|
||||
<span class="icon icon-download"></span> {{ _('Export All Code') }}
|
||||
</a></li>
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
<div class="dialog__content">
|
||||
<div class="dialog--signin__bg">
|
||||
<div class="dialog--signin__side">
|
||||
<h1>{{ _('Don\'t have an account?') }}</h1>
|
||||
<h1>{{ _("Don\'t have an account?") }}</h1>
|
||||
<p>{{ _('By signing up a Vijos universal account, you can submit code and join discussions in all online judging services provided by us.') }}</p>
|
||||
<div><a href="{{ reverse_url('user_register') }}" class="inverse rounded button">{{ _('Sign Up Now') }}</a></div>
|
||||
<div><a href="/register" class="inverse rounded button">{{ _('Sign Up Now') }}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog--signin__main">
|
||||
<form action="{{ reverse_url('user_login') }}" method="post">
|
||||
<form action="/login" method="post">
|
||||
<div class="dialog--signin__close-container supplementary">
|
||||
<a name="dialog--signin__close" href="javascript:;">{{ _('CLOSE') }}</a>
|
||||
</div>
|
||||
@@ -36,7 +36,7 @@
|
||||
</div></div>
|
||||
<div class="row"><div class="columns">
|
||||
<div class="supplementary text-center">
|
||||
<a href="{{ reverse_url('user_lostpass') }}">{{ _('Forgot password or username?') }}</a>
|
||||
<a href="/lostpass">{{ _('Forgot password or username?') }}</a>
|
||||
</div>
|
||||
</div></div>
|
||||
</form>
|
||||
|
||||
+19
-35
@@ -1,6 +1,6 @@
|
||||
{% macro nav_item(target_page_name, target_page_prefix) %}
|
||||
{% macro nav_item(target_page_url, target_page_name, target_page_prefix) %}
|
||||
<li class="nav__list-item">
|
||||
<a href="{{ reverse_url(target_page_name) }}" class="nav__item{% if page_name.startsWith(target_page_prefix) %} nav--active{% endif %}">
|
||||
<a href="{{ target_page_url }}" class="nav__item{% if page_name.startsWith(target_page_prefix) %} nav--active{% endif %}">
|
||||
{{ _(target_page_name) }}
|
||||
</a>
|
||||
</li>
|
||||
@@ -9,80 +9,64 @@
|
||||
<nav class="nav slideout-menu" id="menu">
|
||||
<div class="row"><div class="columns clearfix">
|
||||
<ol class="nav__list nav__list--main clearfix">
|
||||
<li class="nav__list-item"><a href="{{ reverse_url('domain_main', domain_id=vj4.model.builtin.DOMAIN_ID_SYSTEM) }}" class="nav__logo"> </a></li>
|
||||
{{ nav_item('domain_main', 'domain_main') }}
|
||||
<li class="nav__list-item"><a href="/" class="nav__logo"> </a></li>
|
||||
{{ nav_item('/', 'domain_main', 'domain_main') }}
|
||||
{% if handler.has_perm(perm.PERM_VIEW_PROBLEM) %}
|
||||
{{ nav_item('problem_main', 'problem') }}
|
||||
{{ nav_item('/p', 'problem_main', 'problem') }}
|
||||
{% endif %}
|
||||
{% if handler.has_perm(perm.PERM_VIEW_TRAINING) %}
|
||||
{{ nav_item('training_main', 'training') }}
|
||||
{{ nav_item('/t', 'training_main', 'training') }}
|
||||
{% endif %}
|
||||
{% if handler.has_perm(perm.PERM_VIEW_DISCUSSION) %}
|
||||
{{ nav_item('discussion_main', 'discussion') }}
|
||||
{{ nav_item('/d', 'discussion_main', 'discussion') }}
|
||||
{% endif %}
|
||||
{% if handler.has_perm(perm.PERM_VIEW_CONTEST) %}
|
||||
{{ nav_item('contest_main', 'contest') }}
|
||||
{{ nav_item('/c', 'contest_main', 'contest') }}
|
||||
{% endif %}
|
||||
{% if handler.has_perm(perm.PERM_VIEW_HOMEWORK) %}
|
||||
{{ nav_item('homework_main', 'homework') }}
|
||||
{{ nav_item('/h', 'homework_main', 'homework') }}
|
||||
{% endif %}
|
||||
{% if handler.has_perm(perm.PERM_EDIT_DESCRIPTION) or handler.has_perm(perm.PERM_EDIT_PERM) %}
|
||||
{{ nav_item('domain_manage', 'domain_manage') }}
|
||||
{{ nav_item('/d', 'domain_manage', 'domain_manage') }}
|
||||
{% endif %}
|
||||
</ol>
|
||||
<ol class="nav__list nav__list--secondary clearfix">
|
||||
{% if not handler.has_perm(perm.PERM_LOGGEDIN) %}
|
||||
<li class="nav__list-item"><a href="{{ reverse_url('user_login') }}" class="nav__item" name="nav_login">{{ _('Login') }}</a></li>
|
||||
<li class="nav__list-item"><a href="{{ reverse_url('user_register') }}" class="nav__item--round">{{ _('Sign Up') }}</a></li>
|
||||
<li class="nav__list-item"><a href="/login" class="nav__item" name="nav_login">{{ _('Login') }}</a></li>
|
||||
<li class="nav__list-item"><a href="/register" class="nav__item--round">{{ _('Sign Up') }}</a></li>
|
||||
{% else %}
|
||||
<li class="nav__list-item" data-dropdown-pos="bottom right" data-dropdown-target="#menu-nav-user" data-dropdown-trigger-desktop-only>
|
||||
<a href="{{ reverse_url('user_detail', uid=handler.user['_id']) }}" class="nav__item">{{ handler.user.uname }} <span class="icon icon-expand_more nojs--hide"></span></a>
|
||||
<a href="/user/{{ handler.user._id }}" class="nav__item">{{ handler.user.uname }} <span class="icon icon-expand_more nojs--hide"></span></a>
|
||||
<ol class="dropdown-target menu" id="menu-nav-user">
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('user_detail', uid=handler.user['_id']) }}" class="menu__link">
|
||||
<a href="/user/{{ handler.user._id }}" class="menu__link">
|
||||
<span class="icon icon-account--circle"></span> {{ _('My Profile') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('home_messages') }}" class="menu__link">
|
||||
<a href="/home/messages" class="menu__link">
|
||||
<span class="icon icon-comment--multiple"></span> {{ _('home_messages') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu__seperator"></li>
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('home_account') }}" class="menu__link">
|
||||
<a href="/home/account" class="menu__link">
|
||||
<span class="icon icon-wrench"></span> {{ _('home_account') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('home_domain_account') }}" class="menu__link">
|
||||
<span class="icon icon-web"></span> @ {{ handler.domain['name'] }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('home_preference') }}" class="menu__link">
|
||||
<a href="/home/preference" class="menu__link">
|
||||
<span class="icon icon-sliders"></span> {{ _('home_preference') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('home_security') }}" class="menu__link">
|
||||
<a href="/home/security" class="menu__link">
|
||||
<span class="icon icon-security"></span> {{ _('home_security') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu__seperator"></li>
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('home_file') }}" class="menu__link">
|
||||
<span class="icon icon-file"></span> {{ _('My Files') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('home_domain') }}" class="menu__link">
|
||||
<span class="icon icon-web"></span> {{ _('My Domains') }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu__seperator"></li>
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('user_logout') }}" class="menu__link" name="nav_logout">
|
||||
<a href="/logout" class="menu__link" name="nav_logout">
|
||||
<span class="icon icon-logout"></span> {{ _('Logout') }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{% if tdoc %}
|
||||
{% if tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST %}
|
||||
{% include "partials/problem_sidebar_contest.html" %}
|
||||
{% with owner_udoc=udoc, owner_dudoc=dudoc %}
|
||||
{% set owner_udoc=udoc %}
|
||||
{% set owner_dudoc=dudoc %}
|
||||
{% include "partials/contest_sidebar.html" %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% include "partials/problem_sidebar_homework.html" %}
|
||||
{% with owner_udoc=udoc, owner_dudoc=dudoc %}
|
||||
{% set owner_udoc=udoc %}
|
||||
{% set owner_dudoc=dudoc %}
|
||||
{% include "partials/homework_sidebar.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% include "partials/problem_sidebar_normal.html" %}
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
<span class="icon icon-send"></span> {{ _('Submit') }}
|
||||
</a></li>
|
||||
{% elif handler.is_done(tdoc) %}
|
||||
<li class="menu__item scratchpad--hide"><a class="menu__link" href="{{ reverse_url('problem_detail', pid=pdoc['_id']) }}">
|
||||
<li class="menu__item scratchpad--hide"><a class="menu__link" href="/p/{{ pdoc.pid }}">
|
||||
<span class="icon icon-send"></span> {{ _('Open in Problem Set') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.own(pdoc, vj4.model.builtin.PERM_EDIT_PROBLEM_SELF) or handler.has_perm(vj4.model.builtin.PERM_EDIT_PROBLEM) %}
|
||||
{% if handler.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.has_perm(perm.PERM_EDIT_PROBLEM) %}
|
||||
<li class="menu__seperator"></li>
|
||||
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_edit' %} active{% endif %}" href="{{ reverse_url('problem_edit', pid=pdoc['_id']) }}">
|
||||
<span class="icon icon-edit"></span> {{ _('Edit') }}
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
<span class="icon icon-send"></span> {{ _('Submit') }}
|
||||
</a></li>
|
||||
{% elif handler.is_done(tdoc) %}
|
||||
<li class="menu__item scratchpad--hide"><a class="menu__link" href="{{ reverse_url('problem_detail', pid=pdoc['_id']) }}">
|
||||
<li class="menu__item scratchpad--hide"><a class="menu__link" href="/p/{{ pdoc.pid }}">
|
||||
<span class="icon icon-send"></span> {{ _('Open in Problem Set') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.own(pdoc, vj4.model.builtin.PERM_EDIT_PROBLEM_SELF) or handler.has_perm(vj4.model.builtin.PERM_EDIT_PROBLEM) %}
|
||||
{% if handler.own(pdoc, perm.PERM_EDIT_PROBLEM_SELF) or handler.has_perm(perm.PERM_EDIT_PROBLEM) %}
|
||||
<li class="menu__seperator"></li>
|
||||
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_edit' %} active{% endif %}" href="{{ reverse_url('problem_edit', pid=pdoc['_id']) }}">
|
||||
<span class="icon icon-edit"></span> {{ _('Edit') }}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div>
|
||||
<ol class="menu">
|
||||
{% if page_name == 'discussion_node' or page_name == 'discussion_detail' %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_CREATE_DISCUSSION) %}
|
||||
{% if handler.has_perm(perm.PERM_CREATE_DISCUSSION) %}
|
||||
<li class="menu__item"><a class="menu__link highlight" href="{{ reverse_url('discussion_create_document_as_node', doc_type=pdoc['doc_type'], doc_id=pdoc['_id']) }}">
|
||||
<span class="icon icon-add"></span> {{ _('Create a Discussion') }}
|
||||
</a></li>
|
||||
@@ -25,7 +25,7 @@
|
||||
<li class="menu__seperator"></li>
|
||||
{% endif %}
|
||||
{% if page_name == 'problem_detail' %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_SUBMIT_PROBLEM) %}
|
||||
{% if handler.has_perm(perm.PERM_SUBMIT_PROBLEM) %}
|
||||
<li class="menu__item scratchpad--hide"><a class="menu__link highlight" name="problem-sidebar__open-scratchpad" href="javascript:;" data-global-hotkey="alt+e">
|
||||
<span class="icon icon-enlarge"></span> {{ _('Open Scratchpad') }} (Alt+E)
|
||||
</a></li>
|
||||
@@ -34,11 +34,11 @@
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('problem_detail', pid=pdoc['_id']) }}">
|
||||
<li class="menu__item"><a class="menu__link" href="/p/{{ pdoc.pid }}">
|
||||
<span class="icon icon-flag"></span> {{ _('View Problem') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_SUBMIT_PROBLEM) %}
|
||||
{% if handler.has_perm(perm.PERM_SUBMIT_PROBLEM) %}
|
||||
<li class="menu__item scratchpad--hide"><a class="menu__link{% if page_name == 'problem_submit' %} active{% endif %}" href="{{ reverse_url('problem_submit', pid=pdoc['_id']) }}">
|
||||
<span class="icon icon-send"></span> {{ _('Submit') }}
|
||||
</a></li>
|
||||
@@ -51,15 +51,15 @@
|
||||
<span class="icon icon-send"></span> {{ _('No Permission to Submit') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_VIEW_DISCUSSION) or handler.has_perm(vj4.model.builtin.PERM_VIEW_PROBLEM_SOLUTION) %}
|
||||
{% if handler.has_perm(perm.PERM_VIEW_DISCUSSION) or handler.has_perm(perm.PERM_VIEW_PROBLEM_SOLUTION) %}
|
||||
<li class="menu__seperator"></li>
|
||||
{% endif %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_VIEW_DISCUSSION) %}
|
||||
{% if handler.has_perm(perm.PERM_VIEW_DISCUSSION) %}
|
||||
<li class="menu__item"><a class="menu__link{% if page_name == 'discussion_node' or page_name == 'discussion_detail' %} active{% endif %}" href="{{ reverse_url('discussion_node_document_as_node', doc_type=pdoc['doc_type'], doc_id=pdoc['_id']) }}">
|
||||
<span class="icon icon-comment--text"></span> {{ _('Discussions') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_VIEW_PROBLEM_SOLUTION) %}
|
||||
{% if handler.has_perm(perm.PERM_VIEW_PROBLEM_SOLUTION) %}
|
||||
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_solution' %} active{% endif %}" href="{{ reverse_url('problem_solution', pid=pdoc['_id']) }}">
|
||||
<span class="icon icon-comment--text"></span> {{ _('Solutions') }}
|
||||
</a></li>
|
||||
@@ -70,7 +70,7 @@
|
||||
<span class="icon icon-copy"></span> {{ _('Copy Problem') }}
|
||||
</a></li>
|
||||
{% endif %}
|
||||
{% if handler.own(pdoc, vj4.model.builtin.PERM_EDIT_PROBLEM_SELF) or handler.has_perm(vj4.model.builtin.PERM_EDIT_PROBLEM) %}
|
||||
{% if handler.user._id == pdoc.owner or handler.has_perm(perm.PERM_EDIT_PROBLEM) %}
|
||||
<li class="menu__seperator"></li>
|
||||
<li class="menu__item"><a class="menu__link{% if page_name == 'problem_edit' %} active{% endif %}" href="{{ reverse_url('problem_edit', pid=pdoc['_id']) }}">
|
||||
<span class="icon icon-edit"></span> {{ _('Edit') }}
|
||||
|
||||
@@ -1,43 +1,15 @@
|
||||
{% set page_name = "problem_detail" %}
|
||||
{% extends "layout/basic.html" %}
|
||||
{% block content %}
|
||||
<div style="display: none" class="dialog__body--copy-to">
|
||||
<div>
|
||||
<div class="row"><div class="columns">
|
||||
<h1>{{ _('Copy Problem To') }}</h1>
|
||||
</div></div>
|
||||
<div class="row">
|
||||
<div class="medium-12 columns">
|
||||
<label>
|
||||
{{ _('Destination Domain') }}
|
||||
<input name="domain_id" placeholder="{{ _('Domain ID') }}" type="text" class="textbox" autocomplete="off" data-autofocus>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="medium-12 columns">
|
||||
<label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="numeric_pid" checked>{{ _('Numeric PID') }}
|
||||
</label>
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="hidden">{{ _('Hidden') }}
|
||||
</label>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var Context = {{ {
|
||||
'problemId': pdoc['_id'],
|
||||
'socketUrl': '{}-conn'.format(reverse_url('problem_pretest', pid=pdoc['_id'])),
|
||||
'postPretestUrl': reverse_url('problem_pretest', pid=pdoc['_id']),
|
||||
'postSubmitUrl': reverse_url('problem_submit', pid=pdoc['_id']) if not tdoc else reverse_url('contest_detail_problem_submit' if tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST else 'homework_detail_problem_submit', tid=tdoc['doc_id'], pid=pdoc['_id']),
|
||||
'getSubmissionsUrl': reverse_url('problem_submit', pid=pdoc['_id']) if not tdoc else reverse_url('contest_detail_problem_submit' if tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST else 'homework_detail_problem_submit', tid=tdoc['doc_id'], pid=pdoc['_id']),
|
||||
'getRecordDetailUrl': reverse_url('record_detail', rid='{rid}'),
|
||||
'code_lang': handler.get_setting('code_lang'),
|
||||
'code_template': handler.get_code_template(),
|
||||
}|json|safe }};
|
||||
var Context = {
|
||||
'problemId': "{{ pdoc.pid }}",
|
||||
'postSubmitUrl': "/p/{{ pdoc.pid }}",
|
||||
'getSubmissionsUrl': "/p/{{ pdoc.pid }}",
|
||||
'getRecordDetailUrl': "/r/{{ rid }}",
|
||||
'code_lang': "{{ handler.user.codeLang }}",
|
||||
'code_template': "{{ handler.user.codeTemplate }}",
|
||||
};
|
||||
</script>
|
||||
<div class="row">
|
||||
<div class="medium-9 columns">
|
||||
@@ -51,10 +23,9 @@
|
||||
<blockquote class="warn">
|
||||
<p>{{ _('No dataset at present.') }}</p>
|
||||
</blockquote>
|
||||
{% endif %}
|
||||
{% if pdoc['data'] is mapping %}
|
||||
{% elif pdoc.data.startsWith('from:') %}
|
||||
<blockquote class="note">
|
||||
<p>{{ _('Test data comes from') }} <a href="{{ reverse_url('problem_detail', domain_id=pdoc['data']['domain'], pid=pdoc['data']['pid']) }}" target="_blank">{{ pdoc['data']['domain'] }}/{{ pdoc['data']['pid'] }}</a></p>
|
||||
<p>{{ _('Test data comes from') }} <a href="#" target="_blank">{{ pdoc.data.split(':')[1] }}</a></p>
|
||||
</blockquote>
|
||||
{% endif %}
|
||||
{% if tdoc %}
|
||||
@@ -64,27 +35,17 @@
|
||||
<p>{{ _('You cannot submit for this problem because the contest is ended. You can click "Open in Problem Set" to view this problem in normal mode.') }}</p>
|
||||
</blockquote>
|
||||
{% endif %}{# handler.is_done(tdoc) #}
|
||||
{% else %}{# tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST #}
|
||||
{% if handler.is_homework_extended(tdoc) %}
|
||||
<blockquote class="note">
|
||||
<p>{{ _('The homework\'s deadline is due but in extension. You can still submit for this problem but your score will be penalized.') }}</p>
|
||||
</blockquote>
|
||||
{% elif handler.is_done(tdoc) %}{# handler.is_homework_extended(tdoc) #}
|
||||
<blockquote class="note">
|
||||
<p>{{ _('You cannot submit for this problem because the homework\'s deadline is due.') }}</p>
|
||||
</blockquote>
|
||||
{% endif %}{# handler.is_homework_extended(tdoc) #}
|
||||
{% endif %}{# tdoc['doc_type'] == vj4.model.document.TYPE_CONTEST #}
|
||||
{% endif %}{# tdoc #}
|
||||
{{ pdoc['content']|markdown }}
|
||||
{{ pdoc['content']|markdown|safe }}
|
||||
</div>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="medium-3 columns">
|
||||
{% with owner_udoc=udoc, owner_dudoc=dudoc %}
|
||||
{% set owner_udoc=udoc %}
|
||||
{% set owner_dudoc=dudoc %}
|
||||
{% include "partials/problem_sidebar.html" %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="scratchpad-container" style="display:none">
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
{% for sub_categories in category %}
|
||||
<li class="group-list__item">
|
||||
<h2 class="section__title">
|
||||
<a href="{{ reverse_url('problem_category', category=category|urlencode) }}">{{ category }}</a>
|
||||
<a href="/p?category={{ category|urlencode }}">{{ category }}</a>
|
||||
</h2>
|
||||
{% if sub_categories | length > 0 %}
|
||||
<ol class="chip-list">
|
||||
{% for sub_category in sub_categories %}
|
||||
<li class="chip-list__item">
|
||||
<a class="typo-a" href="{{ reverse_url('problem_category', category=(category|urlencode + ',' + sub_category|urlencode)) }}">{{ sub_category }}</a>
|
||||
<a class="typo-a" href="/p?category={{ category|urlencode + ',' + sub_category|urlencode }}">{{ sub_category }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
@@ -52,9 +52,8 @@
|
||||
<div class="section__header">
|
||||
<h1 class="section__title">{{ _('Search') }}</h1>
|
||||
</div>
|
||||
<form method="get" action="{{ reverse_url('problem_search') }}">
|
||||
<form method="get" action="/problem/search">
|
||||
<div class="section__body">
|
||||
<!-- TODO: replace with form_builder -->
|
||||
<label>
|
||||
<input name="q" type="text" class="textbox" value="" placeholder="1001">
|
||||
</label>
|
||||
@@ -62,21 +61,21 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_CREATE_PROBLEM) %}
|
||||
{% if handler.has_perm(perm.PERM_CREATE_PROBLEM) %}
|
||||
<div class="section side">
|
||||
<div class="section__header">
|
||||
<h1 class="section__title">{{ _('Create Problem') }}</h1>
|
||||
</div>
|
||||
<ol class="menu">
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('problem_create') }}" class="menu__link">
|
||||
<a href="/problem/create" class="menu__link">
|
||||
<span class="icon icon-add"></span>
|
||||
{{ _('Create Problem') }}</a>
|
||||
</li>
|
||||
<li class="menu__item">
|
||||
<a href="{{ reverse_url('problem_copy') }}" class="menu__link">
|
||||
<a href="/problem/import" class="menu__link">
|
||||
<span class="icon icon-copy"></span>
|
||||
{{ _('Copy Problem') }}</a>
|
||||
{{ _('Import Problem') }}</a>
|
||||
</li>
|
||||
</ol>
|
||||
<div class="section__body">
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="section__body">
|
||||
<iframe src="{{ reverse_url('problem_upload', pid=pdoc['_id']) }}" frameborder="0" style="width: 100%; height: 100px;"></iframe>
|
||||
<p class="help-text">{{ _('Hint') }}: <a href="{{ reverse_url('wiki_help') }}#upload">{{ _('Dataset Format') }}</a>, {{ _('An example of dataset') }}: <a href="https://github.com/vijos/jd4/blob/master/jd4/testdata/aplusb-legacy.zip?raw=true">{{ _('Download') }}</a></p>
|
||||
{% if pdoc and (handler.own(pdoc, vj4.model.builtin.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(vj4.model.builtin.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %}
|
||||
{% if pdoc and (handler.own(pdoc, perm.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(perm.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %}
|
||||
<p><a href="{{ reverse_url('problem_data', pid=pdoc['_id']) }}" class="expanded button">{{ _('Download Dataset') }}</a></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -22,16 +22,16 @@
|
||||
reply_edit_op = 'edit_reply',
|
||||
comment_delete_op = 'delete_solution',
|
||||
reply_delete_op = 'delete_reply',
|
||||
comment_post_perm = vj4.model.builtin.PERM_CREATE_PROBLEM_SOLUTION,
|
||||
comment_edit_perm = vj4.model.builtin.PERM_EDIT_PROBLEM_SOLUTION,
|
||||
comment_edit_self_perm = vj4.model.builtin.PERM_EDIT_PROBLEM_SOLUTION_SELF,
|
||||
comment_delete_perm = vj4.model.builtin.PERM_DELETE_PROBLEM_SOLUTION,
|
||||
comment_delete_self_perm = vj4.model.builtin.PERM_DELETE_PROBLEM_SOLUTION_SELF,
|
||||
reply_post_perm = vj4.model.builtin.PERM_REPLY_PROBLEM_SOLUTION,
|
||||
reply_edit_perm = vj4.model.builtin.PERM_EDIT_PROBLEM_SOLUTION_REPLY,
|
||||
reply_edit_self_perm = vj4.model.builtin.PERM_EDIT_PROBLEM_SOLUTION_REPLY_SELF,
|
||||
reply_delete_perm = vj4.model.builtin.PERM_DELETE_PROBLEM_SOLUTION_REPLY,
|
||||
reply_delete_self_perm = vj4.model.builtin.PERM_DELETE_PROBLEM_SOLUTION_REPLY_SELF
|
||||
comment_post_perm = perm.PERM_CREATE_PROBLEM_SOLUTION,
|
||||
comment_edit_perm = perm.PERM_EDIT_PROBLEM_SOLUTION,
|
||||
comment_edit_self_perm = perm.PERM_EDIT_PROBLEM_SOLUTION_SELF,
|
||||
comment_delete_perm = perm.PERM_DELETE_PROBLEM_SOLUTION,
|
||||
comment_delete_self_perm = perm.PERM_DELETE_PROBLEM_SOLUTION_SELF,
|
||||
reply_post_perm = perm.PERM_REPLY_PROBLEM_SOLUTION,
|
||||
reply_edit_perm = perm.PERM_EDIT_PROBLEM_SOLUTION_REPLY,
|
||||
reply_edit_self_perm = perm.PERM_EDIT_PROBLEM_SOLUTION_REPLY_SELF,
|
||||
reply_delete_perm = perm.PERM_DELETE_PROBLEM_SOLUTION_REPLY,
|
||||
reply_delete_self_perm = perm.PERM_DELETE_PROBLEM_SOLUTION_REPLY_SELF
|
||||
) }}
|
||||
{{ paginator.render(page, pcount) }}
|
||||
{% if drcount == 0 %}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<div class="section__header">
|
||||
<h1 class="section__title">{{ _('Information') }}</h1>
|
||||
</div>
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_REJUDGE) %}
|
||||
{% if handler.has_perm(perm.PERM_REJUDGE) %}
|
||||
<div class="section__body no-padding">
|
||||
<ol class="menu">
|
||||
<li class="menu__item">
|
||||
@@ -79,7 +79,7 @@
|
||||
{% if rdoc['type'] == vj4.constant.record.TYPE_PRETEST and (handler.own(rdoc, priv=vj4.model.builtin.PRIV_READ_PRETEST_DATA_SELF, field='uid') or handler.has_priv(vj4.model.builtin.PRIV_READ_PRETEST_DATA)) %}
|
||||
<dt>{{ _('Pretest Data') }}</dt>
|
||||
<dd><a href="{{ reverse_url('record_pretest_data', rid=rdoc['_id']) }}"><span class="icon icon-download"></span> {{ _('Download') }}</a></dd>
|
||||
{% elif rdoc['type'] == vj4.constant.record.TYPE_SUBMISSION and pdoc and (handler.own(pdoc, vj4.model.builtin.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(vj4.model.builtin.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %}
|
||||
{% elif rdoc['type'] == vj4.constant.record.TYPE_SUBMISSION and pdoc and (handler.own(pdoc, perm.PERM_READ_PROBLEM_DATA_SELF) or handler.has_perm(perm.PERM_READ_PROBLEM_DATA) or handler.has_priv(vj4.model.builtin.PRIV_READ_PROBLEM_DATA)) %}
|
||||
<dt>{{ _('Problem Data') }}</dt>
|
||||
<dd><a href="{{ reverse_url('problem_data', pid=pdoc['_id']) }}"><span class="icon icon-download"></span> {{ _('Download') }}</a></dd>
|
||||
{% endif %}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<tr data-rid="{{ rdoc['_id'] }}">
|
||||
{{ record.render_status_td(rdoc) }}
|
||||
<td class="col--problem col--problem-name">
|
||||
{% if (rdoc['domain_id'] == handler.domain_id and handler.has_perm(vj4.model.builtin.PERM_REJUDGE)) or handler.has_priv(vj4.model.builtin.PRIV_REJUDGE) %}
|
||||
{% if (rdoc['domain_id'] == handler.domain_id and handler.has_perm(perm.PERM_REJUDGE)) or handler.has_priv(vj4.model.builtin.PRIV_REJUDGE) %}
|
||||
<form class="form--inline" method="post" action="{{ reverse_url('record_rejudge', rid=rdoc['_id']) }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ handler.csrf_token }}">
|
||||
<button type="submit" class="link text-maroon lighter">
|
||||
@@ -15,7 +15,7 @@
|
||||
{% if rdoc['type'] == vj4.constant.record.TYPE_PRETEST %}
|
||||
({{ _('Pretest') }})
|
||||
{% endif %}
|
||||
{% if pdoc and (not pdoc['hidden'] or (pdoc['domain_id'] == handler.domain_id and handler.has_perm(vj4.model.builtin.PERM_VIEW_PROBLEM_HIDDEN))) %}
|
||||
{% if pdoc and (not pdoc['hidden'] or (pdoc['domain_id'] == handler.domain_id and handler.has_perm(perm.PERM_VIEW_PROBLEM_HIDDEN))) %}
|
||||
{{ problem.render_problem_title(pdoc, show_tags=false) }}
|
||||
{% else %}
|
||||
*
|
||||
|
||||
@@ -175,7 +175,7 @@
|
||||
</form>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if handler.own(tdoc, vj4.model.builtin.PERM_EDIT_TRAINING_SELF) or handler.has_perm(vj4.model.builtin.PERM_EDIT_TRAINING) %}
|
||||
{% if handler.own(tdoc, perm.PERM_EDIT_TRAINING_SELF) or handler.has_perm(perm.PERM_EDIT_TRAINING) %}
|
||||
<li class="menu__item"><a class="menu__link" href="{{ reverse_url('training_edit', tid=tdoc['doc_id']) }}">
|
||||
<span class="icon icon-edit"></span> {{ _('Edit') }}
|
||||
</a></li>
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if handler.has_perm(vj4.model.builtin.PERM_CREATE_TRAINING) %}
|
||||
{% if handler.has_perm(perm.PERM_CREATE_TRAINING) %}
|
||||
<div class="section side">
|
||||
<div class="section__header">
|
||||
<h1 class="section__title">{{ _('Create Training Plan') }}</h1>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
{{ vj4.constant.model.USER_GENDER_ICONS[handler.get_udoc_setting(udoc, 'gender')] }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if handler.dudoc_has_perm(udoc, dudoc, vj4.model.builtin.PERM_MOD_BADGE) %}
|
||||
{% if handler.dudoc_has_perm(udoc, dudoc, perm.PERM_MOD_BADGE) %}
|
||||
<span
|
||||
class="profile-header__contact-item user-profile-badge badge--mod"
|
||||
data-tooltip="{{ _('{} is a moderator of this domain.').format(_('She' if handler.get_udoc_setting(udoc, 'gender') == 1 else 'He')) }}"
|
||||
@@ -111,7 +111,7 @@
|
||||
</div>
|
||||
<div class="section__body">
|
||||
{% for pdoc in pdocs %}
|
||||
<p><a href="{{ reverse_url('problem_detail', pid=pdoc['_id']) }}">{{ pdoc['title'] }}</a></p>
|
||||
<p><a href="/p/{{ pdoc.pid }}">{{ pdoc['title'] }}</a></p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}{# if pdocs #}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</div></div>
|
||||
<div class="row"><div class="columns">
|
||||
<div class="text-center supplementary inverse">
|
||||
<a href="{{ reverse_url('user_lostpass') }}">{{ _('Forgot password or username?') }}</a>
|
||||
<a href="/lostpass">{{ _('Forgot password or username?') }}</a>
|
||||
</div>
|
||||
</div></div>
|
||||
</form>
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
<div class="section__body typo">
|
||||
{{ _('no_translation_warn')|safe }}
|
||||
<p>如果您无法登录,请仔细想想,是不是用户名记错了。比如,自己原本想要注册的用户名已经被注册,所以使用了一个带有前和/或后缀的用户名。</p>
|
||||
<p>如果您确信您的账号被盗或者忘记了账号和/或密码,请及时<a href="{{ reverse_url('user_lostpass') }}">{{ _('Reset Password or Find Username') }}</a>。</p>
|
||||
<p>如果您确信您的账号被盗或者忘记了账号和/或密码,请及时<a href="/lostpass">{{ _('Reset Password or Find Username') }}</a>。</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -153,6 +153,11 @@ binary-extensions@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
|
||||
integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==
|
||||
|
||||
blueimp-md5@^2.13.0:
|
||||
version "2.13.0"
|
||||
resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.13.0.tgz#07314b0c64dda0bf1733f96ce40d5af94eb28965"
|
||||
integrity sha512-lmp0m647R5e77ORduxLW5mISIDcvgJZa52vMBv5uVI3UmSWTQjkJsZVBfaFqQPw/QFogJwvY6e3Gl9nP+Loe+Q==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
@@ -401,6 +406,11 @@ encodeurl@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
|
||||
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
|
||||
|
||||
entities@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
|
||||
integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
|
||||
|
||||
error-inject@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37"
|
||||
@@ -651,6 +661,11 @@ has-flag@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
|
||||
hljs@^6.2.3:
|
||||
version "6.2.3"
|
||||
resolved "https://registry.yarnpkg.com/hljs/-/hljs-6.2.3.tgz#d4d6208fa2a84f294956bc50f2c812e9cbd49bcc"
|
||||
integrity sha1-1NYgj6KoTylJVrxQ8sgS6cvUm8w=
|
||||
|
||||
http-assert@^1.3.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878"
|
||||
@@ -839,6 +854,13 @@ json-stable-stringify-without-jsonify@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
|
||||
|
||||
katex@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/katex/-/katex-0.6.0.tgz#12418e09121c05c92041b6b3b9fb6bab213cb6f3"
|
||||
integrity sha1-EkGOCRIcBckgQbazuftrqyE8tvM=
|
||||
dependencies:
|
||||
match-at "^0.1.0"
|
||||
|
||||
keygrip@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226"
|
||||
@@ -950,6 +972,13 @@ levn@^0.3.0, levn@~0.3.0:
|
||||
prelude-ls "~1.1.2"
|
||||
type-check "~0.3.2"
|
||||
|
||||
linkify-it@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
|
||||
integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
|
||||
dependencies:
|
||||
uc.micro "^1.0.1"
|
||||
|
||||
lodash@^4.17.14, lodash@^4.17.15:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
@@ -960,6 +989,34 @@ long@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
|
||||
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
|
||||
|
||||
markdown-it-katex@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it-katex/-/markdown-it-katex-2.0.3.tgz#d7b86a1aea0b9d6496fab4e7919a18fdef589c39"
|
||||
integrity sha1-17hqGuoLnWSW+rTnkZoY/e9YnDk=
|
||||
dependencies:
|
||||
katex "^0.6.0"
|
||||
|
||||
markdown-it@^10.0.0:
|
||||
version "10.0.0"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc"
|
||||
integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==
|
||||
dependencies:
|
||||
argparse "^1.0.7"
|
||||
entities "~2.0.0"
|
||||
linkify-it "^2.0.0"
|
||||
mdurl "^1.0.1"
|
||||
uc.micro "^1.0.5"
|
||||
|
||||
match-at@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/match-at/-/match-at-0.1.1.tgz#25d040d291777704d5e6556bbb79230ec2de0540"
|
||||
integrity sha512-h4Yd392z9mST+dzc+yjuybOGFNOZjmXIPKWjxBd1Bb23r4SmDOsk2NYCU2BMUBGbSpZqwVsZYNq26QS3xfaT3Q==
|
||||
|
||||
mdurl@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
||||
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
@@ -1498,6 +1555,11 @@ type-is@^1.6.14, type-is@^1.6.16:
|
||||
media-typer "0.3.0"
|
||||
mime-types "~2.1.24"
|
||||
|
||||
uc.micro@^1.0.1, uc.micro@^1.0.5:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
|
||||
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
|
||||
|
||||
unpipe@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
|
||||
Reference in new issue
Block a user