添加站内消息,修复讨论节点丢失的问题

This commit is contained in:
undefined committed 2020-05-03 15:33:54 +08:00
1 parent 33e277f28f
commit 627e64a901
44 files changed
+582 -540

No files matched your search

+20
View File
@@ -1,8 +1,10 @@
/* eslint-disable import/no-extraneous-dependencies */
const fs = require('fs');
const webpack = require('webpack');
const yaml = require('js-yaml');
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
const root = require('./root');
const template = require('./template');
const exist = (name) => {
try {
@@ -50,6 +52,24 @@ const build = async (type) => {
resolve();
});
});
for (const i of modules) {
if (!i.startsWith('.')) {
if (exist(`module/${i}/locale`)) {
const locales = fs.readdirSync(root(`module/${i}/locale`));
const lang = {};
for (const j of locales) {
const content = fs.readFileSync(root(`module/${i}/locale/${j}`)).toString();
lang[i.split('.')[0]] = yaml.safeLoad(content);
}
const file = root(`.build/module/${i}/locale.json`);
fs.writeFileSync(file, JSON.stringify(lang));
}
if (exist(`module/${i}/template`)) {
const file = root(`.build/module/${i}/template.yaml`);
fs.writeFileSync(file, yaml.safeDump(template(`module/${i}/template`)));
}
}
}
};
module.exports = build;
+7 -37
View File
@@ -1,45 +1,15 @@
const fs = require('fs');
const yaml = require('js-yaml');
const root = require('./root');
function getFiles(folder) {
const files = [];
const f = fs.readdirSync(root(folder));
for (const i of f) {
if (!i.startsWith('.')) {
if (fs.statSync(root(`${folder}/${i}`)).isDirectory()) {
const g = getFiles(`${folder}/${i}`);
for (const j of g) files.push(`${i}/${j}`);
} else files.push(i);
}
}
return files;
}
const template = require('./template');
const build = async () => {
const files = getFiles('templates');
const exclude = ['partials/training_default.json', 'partials/problem_default.md'];
const templates = {};
for (const i of files) {
let template = fs.readFileSync(root(`templates/${i}`)).toString();
if (!exclude.includes(i)) {
template = template
.trim()
.replace(/ *\n */gmi, ' ')
.replace(/, /gmi, ',')
.replace(/%} {%/gmi, '%}{%')
.replace(/ %}/gmi, '%}')
.replace(/{% /gmi, '{%')
.replace(/> </gmi, '><')
.replace(/}} </gmi, '}}<')
.replace(/> {{/gmi, '>{{')
.replace(/{{ /gmi, '{{')
.replace(/ }}/gmi, '}}')
.trim();
}
templates[i] = template;
}
fs.writeFileSync(root('.build/template.yaml'), yaml.safeDump(templates));
const exclude = [
'partials/training_default.json',
'partials/problem_default.md',
'bsod.html',
];
fs.writeFileSync(root('.build/template.yaml'), yaml.safeDump(template('templates', exclude)));
};
module.exports = build;
+5
View File
@@ -0,0 +1,5 @@
module.exports = function ignoreFailure(func, ...params) {
try {
func(...params);
} catch (e) { } // eslint-disable-line no-empty
};
+7 -10
View File
@@ -1,18 +1,15 @@
const fs = require('fs');
const root = require('./root');
const ignoreFailure = require('./ignoreFailure');
async function build(type) {
if (!['development', 'production'].includes(type)) throw new Error(`Unknown type: ${type}`);
try {
fs.rmdirSync(root('.build'));
} catch (e) { }
fs.mkdirSync(root('.build'));
await Promise.all([
require('./locales')(type),
require('./buildModule')(type),
require('./buildTemplate')(type),
require('./webpack')(type),
]);
ignoreFailure(fs.mkdirSync, root('.cache'));
ignoreFailure(fs.mkdirSync, root('.build'));
await require('./locales')(type);
await require('./buildModule')(type);
await require('./buildTemplate')(type);
await require('./webpack')(type);
}
module.exports = build;
+43
View File
@@ -0,0 +1,43 @@
const fs = require('fs');
const root = require('./root');
function getFiles(folder) {
const files = [];
const f = fs.readdirSync(root(folder));
for (const i of f) {
if (!i.startsWith('.')) {
if (fs.statSync(root(`${folder}/${i}`)).isDirectory()) {
const g = getFiles(`${folder}/${i}`);
for (const j of g) files.push(`${i}/${j}`);
} else files.push(i);
}
}
return files;
}
const build = (dir, exclude = []) => {
const files = getFiles(dir);
const templates = {};
for (const i of files) {
let template = fs.readFileSync(root(`${dir}/${i}`)).toString();
if (!exclude.includes(i)) {
template = template
.trim()
.replace(/ *\n */gmi, ' ')
.replace(/, /gmi, ',')
.replace(/%} {%/gmi, '%}{%')
.replace(/ %}/gmi, '%}')
.replace(/{% /gmi, '{%')
.replace(/> </gmi, '><')
.replace(/}} </gmi, '}}<')
.replace(/> {{/gmi, '>{{')
.replace(/{{ /gmi, '{{')
.replace(/ }}/gmi, '}}')
.trim();
}
templates[i] = template;
}
return templates;
};
module.exports = build;
+1 -40
View File
@@ -9,46 +9,7 @@ process.stdin.on('data', async (input) => {
}
});
global.Hydro = {
handler: {},
template: {},
};
require('./lib/i18n');
require('./utils');
const bus = require('./service/bus');
const loader = require('./lib/loader');
async function run() {
await loader.prepare();
await new Promise((resolve) => {
const h = () => {
console.log('Database connected');
bus.unsubscribe(['system_database_connected'], h);
resolve();
};
bus.subscribe(['system_database_connected'], h);
require('./service/db');
});
require('./service/gridfs');
require('./service/queue');
const server = require('./service/server');
const builtinHandler = [
'home', 'problem', 'record', 'judge', 'user',
'contest', 'training', 'discussion', 'manage', 'import',
];
for (const i of builtinHandler) require(`./handler/${i}`);
await loader.model();
await loader.handler();
for (const i in global.Hydro.handler) {
await global.Hydro.handler[i].apply();
}
const notfound = require('./handler/notfound');
await notfound.apply();
server.start();
}
run().catch((e) => {
require('./loader')().catch((e) => {
console.error(e);
process.exit(1);
});
+37 -24
View File
@@ -4,9 +4,13 @@ const {
} = require('../error');
const options = require('../options');
const bus = require('../service/bus');
const { Route, Handler } = require('../service/server');
const {
Route, Connection, Handler, ConnectionHandler,
} = require('../service/server');
const misc = require('../lib/misc');
const md5 = require('../lib/md5');
const contest = require('../model/contest');
const message = require('../model/message');
const user = require('../model/user');
const setting = require('../model/setting');
const discussion = require('../model/discussion');
@@ -114,6 +118,7 @@ class HomeSecurityHandler extends Handler {
const sessions = await token.getSessionListByUid(this.user._id);
for (const session in sessions) {
if (tokenDigest === md5(session._id)) {
// eslint-disable-next-line no-await-in-loop
await token.delete(session._id, token.TYPE_SESSION);
return this.back();
}
@@ -175,7 +180,7 @@ class HomeMessagesHandler extends Handler {
udoc(udict, key) { // eslint-disable-line class-methods-use-this
const udoc = udict[key];
if (!udoc) return;
const gravatar_url = misc.gravatar_url(udoc.gravatar);
const gravatar_url = misc.gravatar(udoc.gravatar);
if (udoc.gravatar) udict[key] = { ...udoc, gravatar_url, gravatar: '' };
}
@@ -192,11 +197,11 @@ class HomeMessagesHandler extends Handler {
]);
// TODO(twd2): improve here:
for (const mdoc of mdocs) {
this.modify_udoc(udict, mdoc.from);
this.modify_udoc(udict, mdoc.to);
this.udoc(udict, mdoc.from);
this.udoc(udict, mdoc.to);
}
this.response.body = { messages: mdocs, udict };
this.response.template = 'home_message.html';
this.response.template = 'home_messages.html';
}
async postSendMessage({ uid, content }) {
@@ -204,10 +209,10 @@ class HomeMessagesHandler extends Handler {
const mdoc = await message.add(this.user._id, udoc._id, content);
// TODO(twd2): improve here:
// projection
mdoc.from = this.user;
this.modify_udoc(mdoc, 'from');
mdoc.to = udoc;
this.modify_udoc(mdoc, 'to');
mdoc.from_udoc = this.user;
this.udoc(mdoc, 'from');
mdoc.to_udoc = udoc;
this.udoc(mdoc, 'to');
if (this.user._id !== uid) {
await bus.publish(`user_message-${uid}`, { type: 'new', data: mdoc });
}
@@ -231,32 +236,40 @@ class HomeMessagesHandler extends Handler {
}
}
class HomeMessagesConnectionHandler extends ConnectionHandler {
async prepare() {
bus.subscribe([`message_received-${this.user._id}`], this.onMessageReceived);
}
async onMessageReceived(e) {
this.send(...e.value);
}
async clearup() {
bus.unsubscribe(this.onMessageReceived);
}
}
async function apply() {
Route('/', module.exports.HomeHandler);
Route('/home/security', module.exports.HomeSecurityHandler);
Route('/home/changeMail/:code', module.exports.UserChangemailWithCodeHandler);
Route('/home/settings/:category', module.exports.HomeSettingsHandler);
Route('/home/messages', module.exports.HomeMessagesHandler);
Connection('/home/messages-conn', module.exports.HomeMessagesConnectionHandler);
}
global.Hydro.handler.home = module.exports = {
HomeHandler, HomeSecurityHandler, HomeSettingsHandler, UserChangemailWithCodeHandler, apply,
HomeHandler,
HomeSecurityHandler,
HomeSettingsHandler,
UserChangemailWithCodeHandler,
HomeMessagesHandler,
HomeMessagesConnectionHandler,
apply,
};
/*
@app.connection_route('/home/messages-conn', 'home_messages-conn', global_route=True)
class HomeMessagesConnection(base.Connection):
@base.require_priv(builtin.PRIV_USER_PROFILE)
async def on_open(this):
await super(HomeMessagesConnection, this).on_open()
bus.subscribe(this.on_message_received, ['message_received-' + str(this.user['_id'])])
async def on_message_received(this, e):
this.send(**e['value'])
async def on_close(this):
bus.unsubscribe(this.on_message_received)
@app.route('/home/file', 'home_file', global_route=True)
class HomeFileHandler(base.OperationHandler):
def file_url(this, fdoc):
+2 -2
View File
@@ -2,8 +2,8 @@ const { Route, Handler } = require('../service/server');
const { NotFoundError } = require('../error');
class NotFoundHandler extends Handler {
async prepare() {
throw new NotFoundError(); // eslint-disable-line class-methods-use-this
async prepare() { // eslint-disable-line class-methods-use-this
throw new NotFoundError();
}
}
+1 -1
View File
@@ -169,7 +169,7 @@ class UserSearchHandler extends Handler {
}
for (const i in udocs) {
if (udocs[i].gravatar) {
udocs[i].gravatar_url = misc.gravatar_url(udocs[i].gravatar);
udocs[i].gravatar_url = misc.gravatar(udocs[i].gravatar);
}
}
this.response.body = udocs;
+4 -3
View File
@@ -10,7 +10,10 @@ async function run() {
let mongourl = 'mongodb://';
if (options.db.username) mongourl += `${options.db.username}:${options.db.password}@`;
mongourl += `${options.db.host}:${options.db.port}/${options.db.name}`;
const Database = await Mongo.MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopology: true });
const Database = await Mongo.MongoClient.connect(
mongourl,
{ useNewUrlParser: true, useUnifiedTopology: true },
);
const db = Database.db(options.db.name);
const collUser = db.collection('user');
const collRole = db.collection('role');
@@ -48,8 +51,6 @@ async function run() {
}, udoc),
]);
}
await collUser.createIndex('unameLower', { unique: true });
await collUser.createIndex('mailLower', { sparse: true });
await collRole.insertMany(builtin.BUILTIN_ROLES);
await collBlacklist.createIndex('expireAt', { expireAfterSeconds: 0 });
await collToken.createIndex([{ uid: 1 }, { tokenType: 1 }, { updateAt: -1 }], { sparse: true });
+11 -1
View File
@@ -21,13 +21,23 @@ String.prototype.format = function formatStr(...args) {
}
return result;
};
String.prototype.rawformat = function rawFormat(object) {
const res = this.split('{@}');
return [res[0], object, res[1]];
};
String.prototype.translate = function translate(language = 'zh_CN') {
if (locales[language]) return locales[language][this] || this;
return this;
};
module.exports = locales;
function load(data) {
for (const i in data) {
if (!locales[i]) locales[i] = data[i];
else locales[i] = Object.assign(locales[i], data[i]);
}
}
global.Hydro.locales = locales;
global.Hydro.lib.i18n = module.exports = load;
-49
View File
@@ -1,49 +0,0 @@
const fs = require('fs');
const path = require('path');
let installed;
function root(name) {
return path.resolve(process.cwd(), name);
}
function exist(name) {
try {
fs.statSync(root(name));
} catch (e) {
return false;
}
return true;
}
const superRequire = (name) => {
let m;
try {
m = require(root(name)); // eslint-disable-line import/no-dynamic-require
} catch (e) {
m = __non_webpack_require__(root(name)); // eslint-disable-line no-undef
}
return m;
};
async function prepare() {
installed = fs.readdirSync(root('.build/module'));
}
async function handler() {
for (const i of installed) {
if (exist(`.build/module/${i}/handler.js`)) {
superRequire(`.build/module/${i}/handler.js`);
console.log(`Handler init: ${i}`);
}
}
}
async function model() {
for (const i of installed) {
if (exist(`.build/module/${i}/model.js`)) {
superRequire(`.build/module/${i}/model.js`);
console.log(`Model init: ${i}`);
}
}
}
global.Hydro['lib.loader'] = module.exports = { prepare, handler, model };
+7 -3
View File
@@ -1,15 +1,19 @@
const hljs = require('highlight.js');
const MarkdownIt = require('markdown-it');
const katex = require('markdown-it-katex');
const Prism = require('prismjs');
const loadLanguages = require('prismjs/components/');
// FIXME doesnt work in webpack
loadLanguages(['js', 'javascript', 'go', 'c', 'pascal', 'hs', 'java', 'cs', 'cpp', 'py', 'ruby']);
class Markdown extends MarkdownIt {
constructor() {
super({
linkify: true,
highlight(str, lang) {
if (lang && hljs.getLanguage(lang)) {
if (lang && Prism.languages[lang]) {
try {
return hljs.highlight(lang, str).value;
return Prism.highlight(str, Prism.languages[lang], lang);
} catch (__) { } // eslint-disable-line no-empty
}
return '';
+1 -1
View File
@@ -1,6 +1,6 @@
const md5 = require('./md5');
exports.gravatar_url = function gravatarUrl(email, size = 32) {
exports.gravatar = function gravatar(email, size = 32) {
return `//gravatar.loli.net/avatar/${md5((email || '').toString().trim().toLowerCase())}?d=mm&s=${size}`;
};
+18
View File
@@ -0,0 +1,18 @@
const permission = require('../permission');
global.Hydro.ui.nav = [];
const Item = (path, name, prefix, perm) => {
global.Hydro.ui.nav.push({
path, name, prefix, perm,
});
};
Item('/', 'domain_main', 'domain_main');
Item('/p', 'problem_main', 'problem', permission.PERM_VIEW_PROBLEM);
Item('/t', 'training_main', 'training', permission.PERM_VIEW_TRAINING);
Item('/discuss', 'discussion_main', 'discussion', permission.PERM_VIEW_DISCUSSION);
Item('/c', 'contest_main', 'contest', permission.PERM_VIEW_CONTEST);
Item('/manage', 'domain_manage', 'domain_manage', permission.PERM_MANAGE);
global.Hydro.lib.nav = module.exports = Item;
+32 -18
View File
@@ -1,35 +1,49 @@
const path = require('path');
const nunjucks = require('nunjucks');
const markdown = require('./markdown');
const options = require('../options');
const perm = require('../permission');
const builtin = require('../model/builtin');
const model = require('../model');
const misc = require('./misc');
function Loader() { }
Loader.prototype.getSource = function getSource(name) {
if (!global.Hydro.template[name]) throw new Error();
return {
src: global.Hydro.template[name],
path: name,
};
};
class Nunjucks extends nunjucks.Environment {
constructor() {
super(
new nunjucks.FileSystemLoader(path.resolve(options.template.path)),
{ autoescape: true, trimBlocks: true },
);
super(new Loader(), { autoescape: true, trimBlocks: true });
this.addFilter('json', (self) => JSON.stringify(self), false);
this.addFilter('assign', (self, data) => Object.assign(self, data));
this.addFilter('markdown', (self) => markdown.render(self));
this.addFilter('base64_encode', (s) => Buffer.from(s).toString('base64'));
this.addFilter('gravatar_url', misc.gravatar_url);
this.addFilter('format_size', misc.format_size);
this.addGlobal('typeof', (o) => typeof o);
this.addGlobal('console', console);
this.addGlobal('static_url', (str) => `/${str}`);
this.addGlobal('reverse_url', (str) => str);
this.addGlobal('datetime_span', misc.datetime_span);
this.addGlobal('paginate', misc.paginate);
this.addGlobal('perm', perm);
this.addGlobal('status', builtin.STATUS);
this.addGlobal('model', model);
}
}
const env = new Nunjucks();
module.exports = env;
module.exports = {
render(name, state) {
Object.assign(state, {
typeof: (o) => typeof o,
static_url: (str) => `/${str}`,
datetime_span: misc.datetime_span,
paginate: misc.paginate,
perm,
status: builtin.status,
size: misc.size,
gravatar: misc.gravatar,
model,
Context: global.Hydro.ui,
});
return new Promise((resolve, reject) => {
env.render(name, state, (err, res) => {
if (err) reject(err);
else resolve(res);
});
});
},
};
+134
View File
@@ -0,0 +1,134 @@
/* eslint-disable import/no-dynamic-require */
const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');
function root(name) {
return path.resolve(process.cwd(), name);
}
const installed = fs.readdirSync(root('.build/module'));
function exist(name) {
try {
fs.statSync(root(name));
} catch (e) {
return false;
}
return true;
}
const superRequire = (name) => {
let m;
try {
m = require(root(name));
} catch (e) {
m = __non_webpack_require__(root(name)); // eslint-disable-line no-undef
}
return m;
};
async function handler() {
for (const i of installed) {
if (exist(`.build/module/${i}/handler.js`)) {
superRequire(`.build/module/${i}/handler.js`);
console.log(`Handler init: ${i}`);
}
}
}
async function locale() {
if (exist('.build/locale.js')) {
global.Hydro.lib.i18n(superRequire('.build/locale.js'));
console.log('Locale init: builtin');
}
for (const i of installed) {
if (exist(`.build/module/${i}/locale.js`)) {
global.Hydro.lib.i18n(superRequire(`.build/module/${i}/locale.js`));
console.log(`Locale init: ${i}`);
}
}
}
async function template() {
if (exist('.build/template.yaml')) {
const file = fs.readFileSync(root('.build/template.yaml')).toString();
Object.assign(global.Hydro.template, yaml.safeLoad(file));
console.log('Template init: builtin');
}
for (const i of installed) {
if (exist(`.build/module/${i}/locale.js`)) {
const file = fs.readFileSync(root(`.build/module/${i}/template.yaml`)).toString();
Object.assign(global.Hydro.template, yaml.safeLoad(file));
console.log(`Template init: ${i}`);
}
}
}
async function model() {
for (const i of installed) {
if (exist(`.build/module/${i}/model.js`)) {
const m = superRequire(`.build/module/${i}/model.js`);
if (m.index) await m.index(); // eslint-disable-line no-await-in-loop
console.log(`Model init: ${i}`);
}
}
}
async function load() {
global.Hydro = {
handler: {},
service: {},
model: {},
lib: {},
template: {},
ui: {},
};
await template();
require('./lib/i18n');
require('./utils');
require('./error');
require('./permission');
require('./options');
const bus = require('./service/bus');
await new Promise((resolve) => {
const h = () => {
console.log('Database connected');
bus.unsubscribe(['system_database_connected'], h);
resolve();
};
bus.subscribe(['system_database_connected'], h);
require('./service/db');
});
const builtinLib = [
'axios', 'download', 'i18n', 'mail', 'markdown',
'md5', 'misc', 'paginate', 'pwhash', 'rank',
'template', 'validator', 'nav',
];
for (const i of builtinLib) require(`./lib/${i}`);
await locale();
require('./service/gridfs');
require('./service/queue');
const server = require('./service/server');
const builtinModel = [
'blacklist', 'builtin', 'contest', 'discussion', 'message',
'opcount', 'problem', 'record', 'setting', 'solution',
'system', 'token', 'training', 'user',
];
for (const i of builtinModel) {
const m = require(`./model/${i}`);
if (m.index) await m.index(); // eslint-disable-line no-await-in-loop
}
const builtinHandler = [
'home', 'problem', 'record', 'judge', 'user',
'contest', 'training', 'discussion', 'manage', 'import',
];
for (const i of builtinHandler) require(`./handler/${i}`);
await model();
await handler();
for (const i in global.Hydro.handler) {
await global.Hydro.handler[i].apply(); // eslint-disable-line no-await-in-loop
}
const notfound = require('./handler/notfound');
await notfound.apply();
server.start();
}
module.exports = load;
+5 -2
View File
@@ -1,5 +1,7 @@
const { ObjectID } = require('bson');
const problem = require('./problem');
const contest = require('./contest');
const { PERM_VIEW_PROBLEM_HIDDEN } = require('../permission');
const { DocumentNotFoundError } = require('../error');
const db = require('../service/db.js');
@@ -8,7 +10,7 @@ const collReply = db.collection('discussion.reply');
const collStatus = db.collection('discussion.status');
async function add(parentType, parentId, owner, title, content, ip = null, highlight = false) {
let res = await coll.insertOne({
const res = await coll.insertOne({
owner,
title,
content,
@@ -145,7 +147,8 @@ async function getVnode(ddoc, handler) {
async function getListVnodes(ddocs, handler) {
const res = {};
for (const ddoc of ddocs) {
res[ddoc._id] = await getVnode(ddoc, handler);
// FIXME no-await-in-loop
res[ddoc._id] = await getVnode(ddoc, handler); // eslint-disable-line no-await-in-loop
}
return res;
}
+72
View File
@@ -0,0 +1,72 @@
const { MessageNotFoundError } = require('../error');
const db = require('../service/db.js');
const coll = db.collection('message');
async function add(from, to, content) {
const res = await coll.insertOne({
from,
to,
fromUnread: false,
toUnread: true,
reply: [
{
from, unread: true, content, at: new Date(),
},
],
});
return await coll.findOne({ _id: res.insertedId }); // eslint-disable-line no-return-await
}
async function get(_id) {
const doc = await coll.findOne({ _id });
if (!doc) throw new MessageNotFoundError();
return doc;
}
function getMany(query, sort, page, limit) {
return coll.find(query).sort(sort)
.skip((page - 1) * limit).limit(limit)
.toArray();
}
function del(_id) {
return coll.deleteOne({ _id });
}
function count(query) {
return coll.find(query).count();
}
function getMulti(uid) {
return coll.find({ $or: [{ from: uid }, { to: uid }] });
}
async function addReply(_id, from, content) {
const reply = {
from,
content,
unread: true,
at: new Date(),
};
await coll.updateOne({ _id }, { $push: { reply } });
return await coll.findOne({ _id }); // eslint-disable-line no-return-await
}
function index() {
return Promise.all([
coll.createIndex({ to: 1, _id: -1 }),
coll.createIndex({ from: 1, _id: -1 }),
]);
}
global.Hydro.model.message = module.exports = {
count,
add,
get,
del,
getMany,
getMulti,
addReply,
index,
};
+12 -8
View File
@@ -26,8 +26,8 @@ class USER {
this.nSubmit = user.nSubmit || 0;
}
hasPerm(perm) {
return this.perm.includes(perm);
hasPerm(p) {
return this.perm.includes(p);
}
checkPassword(password) {
@@ -144,7 +144,7 @@ async function getPrefixList(prefix, limit = 50) {
async function setRole(uid, role) {
const udoc = await getById(uid);
return await Promise.all([
return await Promise.all([ // eslint-disable-line no-return-await
coll.findOneAndUpdate({ _id: uid }, { $set: { role } }),
collRole.updateOne({ _id: udoc.role }, { $inc: { count: -1 } }),
collRole.updateOne({ _id: role }, { $inc: { count: 1 } }),
@@ -159,8 +159,8 @@ function getRole(name) {
return collRole.findOne({ _id: name });
}
function addRole(name, perm) {
return collRole.insertOne({ _id: name, perm, count: 0 });
function addRole(name, permission) {
return collRole.insertOne({ _id: name, perm: permission, count: 0 });
}
function deleteRoles(roles) {
@@ -170,8 +170,12 @@ function deleteRoles(roles) {
]);
}
function init() {
return collRole.update({ _id: 'root' }, { $set: { perm: perm.PERM_ALL } });
function index() {
return Promise.all([
collRole.updateOne({ _id: 'root' }, { $set: { perm: perm.PERM_ALL } }),
coll.createIndex('unameLower', { unique: true }),
coll.createIndex('mailLower', { sparse: true }),
]);
}
module.exports = {
@@ -192,5 +196,5 @@ module.exports = {
getRoles,
addRole,
deleteRoles,
init,
index,
};
+1 -1
View File
@@ -114,4 +114,4 @@ perm.PERM_DEFAULT = perm.PERM_BASIC
perm.PERM_ADMIN = perm.PERM_ALL;
module.exports = perm;
global.Hydro.permission = module.exports = perm;
+33
View File
@@ -0,0 +1,33 @@
class Cron {
constructor() {
this.tasks = [];
}
plan(time, task) {
const now = new Date();
if (!(time instanceof Date)) time = new Date(time);
this.tasks.push({
id: setTimeout(() => {
for (const i in this.tasks) {
if (this.tasks[i].func === task) {
this.tasks.splice(i, 1);
break;
}
}
task();
}, time - now),
func: task,
});
}
interval(time, task) {
const now = new Date();
if (!(time instanceof Date)) time = new Date(time);
this.tasks.push({
id: setTimeout(() => { task(); }, time - now),
func: task,
});
}
}
module.exports = Cron;
+1 -1
View File
@@ -16,6 +16,6 @@ Mongo.MongoClient.connect(mongourl, { useNewUrlParser: true, useUnifiedTopology:
bus.publish('system_database_connected', null);
});
module.exports = {
global.Hydro.service.db = module.exports = {
collection: (c) => db.collection(c),
};
+21 -29
View File
@@ -65,20 +65,16 @@ class Handler {
this.session = {};
}
renderHTML(name, context) {
async renderHTML(name, context) {
console.time(name);
this.hasPerm = (perm) => this.user.hasPerm(perm);
return new Promise((resolve, reject) => {
template.render(name, Object.assign(context, {
handler: this,
_: (str) => (str ? str.toString().translate(this.user.language) : ''),
user: this.user,
}), (error, res) => {
console.timeEnd(name);
if (error) reject(error);
else resolve(res);
});
});
const res = await template.render(name, Object.assign(context, {
handler: this,
_: (str) => (str ? str.toString().translate(this.user.language) : ''),
user: this.user,
}));
console.timeEnd(name);
return res;
}
async render(name, context) {
@@ -320,20 +316,16 @@ class ConnectionHandler {
for (const i in p) this.request.params[p[i][0]] = decodeURIComponent(p[i][1]);
}
renderHTML(name, context) {
async renderHTML(name, context) {
console.time(name);
this.hasPerm = (perm) => this.user.hasPerm(perm);
return new Promise((resolve, reject) => {
template.render(name, Object.assign(context, {
handler: this,
_: (str) => (str ? str.toString().translate(this.user.language) : ''),
user: this.user,
}), (error, res) => {
console.timeEnd(name);
if (error) reject(error);
else resolve(res);
});
});
const res = await template.render(name, Object.assign(context, {
handler: this,
_: (str) => (str ? str.toString().translate(this.user.language) : ''),
user: this.user,
}));
console.timeEnd(name);
return res;
}
send(data) {
@@ -401,14 +393,14 @@ function Connection(prefix, RouteConnHandler) {
sock.installHandlers(server);
}
exports.Handler = Handler;
exports.ConnectionHandler = ConnectionHandler;
exports.Route = Route;
exports.Connection = Connection;
exports.start = function start() {
function start() {
app.use(morgan(':method :url :status :res[content-length] - :response-time ms'));
app.use(router.routes()).use(router.allowedMethods());
Route('*', Handler);
server.listen(options.listen.port);
console.log('Server listening at: %s', options.listen.port);
}
global.Hydro.service.server = module.exports = {
Handler, ConnectionHandler, Route, Connection, start,
};
+4 -4
View File
@@ -8,19 +8,19 @@
"dependencies": {
"axios": "^0.19.0",
"bson": "^4.0.2",
"highlight.js": "^9.18.1",
"js-yaml": "^3.13.1",
"koa": "^2.11.0",
"koa-body": "^4.1.1",
"koa-morgan": "^1.0.1",
"koa-router": "^8.0.8",
"koa-static-cache": "^5.1.2",
"koa-static-cache": "^5.1.3",
"lodash": "^4.17.15",
"markdown-it": "^10.0.0",
"markdown-it-katex": "^2.0.3",
"mongodb": "^3.5.5",
"mongodb": "^3.5.7",
"nodemailer": "^6.3.1",
"nunjucks": "^3.2.1",
"prismjs": "^1.20.0",
"sockjs": "^0.3.20"
},
"devDependencies": {
@@ -47,4 +47,4 @@
"templates/*"
]
}
}
}
@@ -3,7 +3,7 @@
<li class="dczcomments__reply{% if mode_create %} commentbox-container{% endif %}">
<div class="media">
<div class="media__left top">
<img src="{{ udoc['gravatar']|gravatar_url }}" width="50" height="50" class="medium user-profile-avatar">
<img src="{{ gravatar(udoc['gravatar']) }}" width="50" height="50" class="medium user-profile-avatar">
</div>
<div class="media__body top no-heading">
{% if not mode_create %}
@@ -14,7 +14,7 @@
</div>
{{ reply_operations(doc, rdoc) }}
</div>
<div class="typo" data-emoji-enabled data-raw-url="{{ reverse_url('discussion_tail_reply_raw', did=doc['parent_doc_id'], drid=doc['doc_id'], drrid=rdoc['_id']) }}">
<div class="typo" data-emoji-enabled data-raw-url="/discuss/{{ doc.parentId }}/{{ doc._id }}/{{ rdoc._id }}/raw">
{{ rdoc['content']|markdown|safe }}
</div>
<div class="commentbox-edit-target"></div>
@@ -75,7 +75,7 @@
<li class="dczcomments__item">
<div class="media">
<div class="media__left top">
<img src="{{ udoc['gravatar']|gravatar_url }}" width="60" height="60" class="medium user-profile-avatar">
<img src="{{ gravatar(udoc.gravatar) }}" width="60" height="60" class="medium user-profile-avatar">
</div>
<div class="media__body top no-heading">
<div class="hasjs--hide">
@@ -107,7 +107,7 @@
<li class="dczcomments__item">
<div class="media">
<div class="media__left top">
<img src="{{ udoc['gravatar']|gravatar_url }}" width="60" height="60" class="medium user-profile-avatar">
<img src="{{ gravatar(udoc['gravatar']) }}" width="60" height="60" class="medium user-profile-avatar">
</div>
<div class="media__body top no-heading">
<div class="clearfix">
@@ -133,7 +133,7 @@
{% endif %}
</div>
</div>
<div class="typo" data-emoji-enabled data-raw-url="{{ reverse_url('discussion_reply_raw', did=doc['parent_doc_id'], drid=doc['doc_id']) }}">
<div class="typo" data-emoji-enabled data-raw-url="/discuss/{{ doc.parentId }}/{{ doc._id }}/raw">
{{ doc['content']|markdown|safe }}
</div>
<div class="commentbox-edit-target"></div>
+1 -1
View File
@@ -6,7 +6,7 @@
) %}
<span class="user-profile-link">
{% if avatar %}
<img class="small user-profile-avatar v-center" src="{{ udoc['gravatar']|default('')|gravatar_url }}" width="20" height="20">
<img class="small user-profile-avatar v-center" src="{{ gravatar(udoc['gravatar']|default('')) }}" width="20" height="20">
{% endif %}
<a class="user-profile-name" href="/u/{{ udoc['_id']|default(0) }}">
{{ udoc['uname'] }}
+1 -1
View File
@@ -85,7 +85,7 @@
<div class="section__body">
<div class="media sidebar-user-profile">
<div class="media__left">
<img src="{{ udoc['gravatar']|gravatar_url }}" width="80" height="80" class="medium user-profile-avatar">
<img src="{{ gravatar(udoc['gravatar']) }}" width="80" height="80" class="medium user-profile-avatar">
</div>
<div class="media__body">
<p>
+1 -1
View File
@@ -24,7 +24,7 @@
<div class="section__body">
{% if vnode %}
{% if handler.hasPerm(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>
<p><a href="/discuss/{{ vnode.parentType }}/{{ vnode.parentId }}" class="expanded primary button">{{ _('Create a Discussion') }}</a></p>
{% else %}
{% if not handler.hasPerm(perm.PERM_LOGGEDIN) %}
<p><a href="javascript:showSignInDialog();" class="expanded primary button">{{ _('Login to Create a Discussion') }}</a></p>
+1 -1
View File
@@ -15,7 +15,7 @@
</div>
<div class="section__body typo">
<dl class="large horizontal">
<dt>{{ _('Gravatar') }}</dt><dd><img src="{{ system.gravatar|gravatar_url }}" width="32" height="32"></dd>
<dt>{{ _('Gravatar') }}</dt><dd><img src="{{ gravatar(system.gravatar) }}" width="32" height="32"></dd>
<dt>{{ _('Name') }}</dt><dd>{{ system.uname }}</dd>
</dl>
</div>
+1
View File
@@ -1,3 +1,4 @@
{% set page_name = "home_messages" %}
{% extends "layout/home_base.html" %}
{% block home_content %}
<div style="display: none" class="dialog__body--user-select">
+1 -1
View File
@@ -26,7 +26,7 @@
{% else %}
<span class="v-center icon icon-flag"></span>
{% endif %}
{{ vndict[ddoc.parentId].title|default(_('(missing)')) }}
{{ vndict[ddoc._id].title|default(_('(missing)')) }}
</a>
</li>
<li>
+9 -16
View File
@@ -10,22 +10,15 @@
<div class="row"><div class="columns clearfix">
<ol class="nav__list nav__list--main clearfix">
<li class="nav__list-item"><a href="/" class="nav__logo">&nbsp;</a></li>
{{ nav_item('/', 'domain_main', 'domain_main') }}
{% if handler.hasPerm(perm.PERM_VIEW_PROBLEM) %}
{{ nav_item('/p', 'problem_main', 'problem') }}
{% endif %}
{% if handler.hasPerm(perm.PERM_VIEW_TRAINING) %}
{{ nav_item('/t', 'training_main', 'training') }}
{% endif %}
{% if handler.hasPerm(perm.PERM_VIEW_DISCUSSION) %}
{{ nav_item('/discuss', 'discussion_main', 'discussion') }}
{% endif %}
{% if handler.hasPerm(perm.PERM_VIEW_CONTEST) %}
{{ nav_item('/c', 'contest_main', 'contest') }}
{% endif %}
{% if handler.hasPerm(perm.PERM_MANAGE) %}
{{ nav_item('/manage', 'domain_manage', 'domain_manage') }}
{% endif %}
{% for item in Context.nav %}
{% if item.perm %}
{% if handler.hasPerm(item.perm) %}
{{ nav_item(item.path, item.name, item.prefix) }}
{% endif %}
{% else %}
{{ nav_item(item.path, item.name, item.prefix) }}
{% endif %}
{% endfor %}
</ol>
<ol class="nav__list nav__list--secondary clearfix">
{% if not handler.hasPerm(perm.PERM_LOGGEDIN) %}
+2 -2
View File
@@ -48,8 +48,8 @@
<span>{{ rcdoc['judgeText'] }}</span>
<a class="tool-button" href="/wiki/help#status"><span class="icon icon-help"></span></a>
</td>
<td class="col--time">{% if rcdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rcdoc['time_ms'] }}ms</td>
<td class="col--memory">{% if rcdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rcdoc['memory_kb']|format_size(1024) }}</td>
<td class="col--time">{% if rcdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rcdoc.time }}ms</td>
<td class="col--memory">{% if rcdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rcdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ size(rcdoc.memory_kb, 1024) }}</td>
</tr>
{% endfor %}
</tbody>
+1 -1
View File
@@ -6,5 +6,5 @@
<dt>{{ _('Total Time') }}</dt>
<dd>{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc.time }}ms</dd>
<dt>{{ _('Peak Memory') }}</dt>
<dd>{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc.memory|format_size(1024) }}</dd>
<dd>{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ size(rdoc.memory, 1024) }}</dd>
</dl>
+1 -1
View File
@@ -24,7 +24,7 @@
</a>
</td>
<td class="col--time">{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc.time }}ms</td>
<td class="col--memory">{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ rdoc.memory|format_size(1024) }}</td>
<td class="col--memory">{% if rdoc['status'] == status.STATUS_TIME_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_MEMORY_LIMIT_EXCEEDED or rdoc['status'] == status.STATUS_OUTPUT_LIMIT_EXCEEDED %}&ge;{% endif %}{{ size(rdoc.memory, 1024) }}</td>
<td class="col--lang">{{ model.builtin.LANG_TEXTS[rdoc['lang']] }}</td>
<td class="col--submit-at">{{ datetime_span(rdoc['_id'])|safe }}</td>
</tr>
+1 -1
View File
@@ -114,7 +114,7 @@
{% endif %}
<td class="col--name col--problem-name">
{% if handler.hasPerm(perm.PERM_LOGGEDIN) %}
<form class="form--inline" action="{{ reverse_url('problem_main') }}" method="post">
<form class="form--inline" action="/p" method="post">
<input type="hidden" name="pid" value="{{ pdoc['_id'] }}">
<input type="hidden" name="operation" value="{% if not psdoc['star'] %}star{% else %}unstar{% endif %}">
<input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}">
+1 -1
View File
@@ -9,7 +9,7 @@
<div class="profile-header__content">
<div class="media">
<div class="media__left">
<img src="{{ udoc.gravatar|gravatar_url }}" width="120" height="120" class="large user-profile-avatar">
<img src="{{ gravatar(udoc.gravatar) }}" width="120" height="120" class="large user-profile-avatar">
</div>
<div class="media__body profile-header__main">
<h1>
+1 -2
View File
@@ -78,10 +78,9 @@ export default function (env = {}) {
const config = {
bail: true,
mode: 'production',
mode: env.production ? 'production' : 'development',
profile: true,
context: root(),
devtool: env.production ? 'source-map' : false,
entry: {
vj4: './Entry.js',
},
@@ -56,11 +56,11 @@ export default class MessagePadDialogueContentContainer extends React.PureCompon
return _.map(this.props.item.reply, (reply, idx) => (
<Message
key={idx}
isSelf={reply.sender_uid === UserContext.uid}
isSelf={reply.from === UserContext.uid}
faceUrl={
reply.sender_uid === this.props.item.sender_uid
? this.props.item.sender_udoc.gravatar_url
: this.props.item.sendee_udoc.gravatar_url
reply.from === this.props.item.from
? this.props.item.from_udoc.gravatar_url
: this.props.item.to_udoc.gravatar_url
}
>
<div>{reply.content}</div>
@@ -39,9 +39,9 @@ export default class MessagePadDialogueListContainer extends React.PureComponent
<ListItem
key={dialogue._id}
userName={
dialogue.sender_uid === UserContext.uid
? dialogue.sendee_udoc.uname
: dialogue.sender_udoc.uname
dialogue.from === UserContext.uid
? dialogue.to_udoc.uname
: dialogue.from_udoc.uname
}
summary={
dialogue.isPlaceholder
@@ -49,9 +49,9 @@ export default class MessagePadDialogueListContainer extends React.PureComponent
: _.last(dialogue.reply).content
}
faceUrl={
dialogue.sender_uid === UserContext.uid
? dialogue.sendee_udoc.gravatar_url
: dialogue.sender_udoc.gravatar_url
dialogue.from === UserContext.uid
? dialogue.to_udoc.gravatar_url
: dialogue.from_udoc.gravatar_url
}
active={dialogue._id === this.props.activeId}
onClick={() => this.props.handleClick(dialogue._id)}
@@ -97,7 +97,7 @@ export default class MessagePadInputContainer extends React.PureComponent {
if (state.dialogues[this.props.activeId].isPlaceholder) {
this.props.postSend(
this.props.activeId,
state.dialogues[this.props.activeId].sendee_uid,
state.dialogues[this.props.activeId].to,
this.props.inputValue,
);
} else {
@@ -7,11 +7,11 @@ export default function reducer(state = {}, action) {
return _.keyBy(
_.filter(
_.map(messages, (m) => ({
sendee_udoc: udict[m.sendee_uid],
sender_udoc: udict[m.sender_uid],
to_udoc: udict[m.to],
from_udoc: udict[m.from],
...m,
})),
(m) => m.sendee_udoc && m.sender_udoc,
(m) => m.to_udoc && m.from_udoc,
),
'_id',
);
@@ -22,9 +22,9 @@ export default function reducer(state = {}, action) {
...state,
[id]: {
_id: id,
sender_uid: UserContext.uid,
sendee_uid: user._id,
sendee_udoc: { ...user },
from: UserContext.uid,
to: user._id,
to_udoc: { ...user },
reply: [],
isPlaceholder: true,
},
+59 -255
View File
@@ -206,11 +206,6 @@ a-sync-waterfall@^1.0.0:
resolved "https://registry.yarnpkg.com/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz#75b6b6aa72598b497a125e7a2770f14f4c8a1fa7"
integrity sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==
abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
accepts@^1.3.5:
version "1.3.7"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
@@ -332,19 +327,11 @@ anymatch@~3.1.1:
normalize-path "^3.0.0"
picomatch "^2.0.4"
aproba@^1.0.3, aproba@^1.1.1:
aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
are-we-there-yet@~1.1.2:
version "1.1.5"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==
dependencies:
delegates "^1.0.0"
readable-stream "^2.0.6"
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@@ -811,6 +798,15 @@ cli-width@^2.0.0:
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48"
integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==
clipboard@^2.0.0:
version "2.0.6"
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376"
integrity sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==
dependencies:
good-listener "^1.2.2"
select "^1.1.2"
tiny-emitter "^2.0.0"
co-body@^5.1.1:
version "5.2.0"
resolved "https://registry.yarnpkg.com/co-body/-/co-body-5.2.0.tgz#5a0a658c46029131e0e3a306f67647302f71c124"
@@ -826,11 +822,6 @@ co@^4.6.0:
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
collection-visit@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
@@ -915,11 +906,6 @@ console-browserify@^1.1.0:
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
constants-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
@@ -1050,7 +1036,7 @@ debug@=3.1.0, debug@~3.1.0:
dependencies:
ms "2.0.0"
debug@^3.1.0, debug@^3.2.6:
debug@^3.1.0:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
@@ -1074,11 +1060,6 @@ deep-equal@~1.0.1:
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
@@ -1113,6 +1094,11 @@ define-property@^2.0.2:
is-descriptor "^1.0.2"
isobject "^3.0.1"
delegate@^3.1.2:
version "3.2.0"
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
@@ -1146,11 +1132,6 @@ destroy@^1.0.4:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
@@ -1686,13 +1667,6 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
fs-minipass@^1.2.5:
version "1.2.7"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
dependencies:
minipass "^2.6.0"
fs-readdir-recursive@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27"
@@ -1736,20 +1710,6 @@ functional-red-black-tree@^1.0.1:
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
dependencies:
aproba "^1.0.3"
console-control-strings "^1.0.0"
has-unicode "^2.0.0"
object-assign "^4.1.0"
signal-exit "^3.0.0"
string-width "^1.0.1"
strip-ansi "^3.0.1"
wide-align "^1.1.0"
get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
@@ -1789,6 +1749,13 @@ globals@^12.1.0:
dependencies:
type-fest "^0.8.1"
good-listener@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=
dependencies:
delegate "^3.1.2"
graceful-fs@^4.1.11, graceful-fs@^4.1.15:
version "4.2.4"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
@@ -1821,11 +1788,6 @@ has-symbols@^1.0.0, has-symbols@^1.0.1:
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
has-value@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
@@ -1881,11 +1843,6 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3"
minimalistic-assert "^1.0.1"
highlight.js@^9.18.1:
version "9.18.1"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.1.tgz#ed21aa001fe6252bb10a3d76d47573c6539fe13c"
integrity sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==
hmac-drbg@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@@ -1929,7 +1886,7 @@ https-browserify@^1.0.0:
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -1946,13 +1903,6 @@ iferr@^0.1.5:
resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE=
ignore-walk@^3.0.1:
version "3.0.3"
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
dependencies:
minimatch "^3.0.4"
ignore@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
@@ -2004,11 +1954,6 @@ inherits@2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@~1.3.0:
version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
inquirer@^7.0.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29"
@@ -2125,13 +2070,6 @@ is-extglob@^2.1.0, is-extglob@^2.1.1:
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
is-fullwidth-code-point@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
dependencies:
number-is-nan "^1.0.0"
is-fullwidth-code-point@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
@@ -2362,10 +2300,10 @@ koa-router@^8.0.8:
path-to-regexp "1.x"
urijs "^1.19.2"
koa-static-cache@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/koa-static-cache/-/koa-static-cache-5.1.2.tgz#49b592007157b164f5e9df5b276e305c8be5016a"
integrity sha512-EhnVBF9mkbp7bijDz2+yg5KxXFsUYUQCOqGy78bAhJp2PRMCMYV7nG/f7k9/liw+43u2Uow0v6ZZ025qBCYsGw==
koa-static-cache@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/koa-static-cache/-/koa-static-cache-5.1.3.tgz#a86a0892bf185994a3f20b315558f4ce0426e19e"
integrity sha512-nq58/gZUSQ31OUWTEG0pLRqs6dlbRt7vSAdFc7G912urrYxj+qNOl/QfarK5y/CarmXk8R8LzZKwXusRRuSG/Q==
dependencies:
compressible "^2.0.6"
debug "^3.1.0"
@@ -2629,21 +2567,6 @@ minimist@^1.2.0, minimist@^1.2.5:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
dependencies:
safe-buffer "^5.1.2"
yallist "^3.0.0"
minizlib@^1.2.1:
version "1.3.3"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
dependencies:
minipass "^2.9.0"
mississippi@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
@@ -2668,17 +2591,17 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3:
mkdirp@^0.5.1, mkdirp@^0.5.3:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
dependencies:
minimist "^1.2.5"
mongodb@^3.5.5:
version "3.5.6"
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.5.6.tgz#a1be2d9796c8a8a5b0e6bcbc6baaaa406bd5c0d5"
integrity sha512-sh3q3GLDLT4QmoDLamxtAECwC3RGjq+oNuK1ENV8+tnipIavss6sMYt77hpygqlMOCt0Sla5cl7H4SKCVBCGEg==
mongodb@^3.5.7:
version "3.5.7"
resolved "https://registry.yarnpkg.com/mongodb/-/mongodb-3.5.7.tgz#6dcfff3bdbf67a53263dcca1647c265eea1d065d"
integrity sha512-lMtleRT+vIgY/JhhTn1nyGwnSMmJkJELp+4ZbrjctrnBxuLbj6rmLuJFz8W2xUzUqWmqoyVxJLYuC58ZKpcTYQ==
dependencies:
bl "^2.2.0"
bson "^1.1.4"
@@ -2762,15 +2685,6 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
needle@^2.2.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.1.tgz#14af48732463d7475696f937626b1b993247a56a"
integrity sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g==
dependencies:
debug "^3.2.6"
iconv-lite "^0.4.4"
sax "^1.2.4"
negotiator@0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
@@ -2815,35 +2729,11 @@ node-libs-browser@^2.2.1:
util "^0.11.0"
vm-browserify "^1.0.1"
node-pre-gyp@*:
version "0.14.0"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83"
integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==
dependencies:
detect-libc "^1.0.2"
mkdirp "^0.5.1"
needle "^2.2.1"
nopt "^4.0.1"
npm-packlist "^1.1.6"
npmlog "^4.0.2"
rc "^1.2.7"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^4.4.2"
nodemailer@^6.3.1:
version "6.4.6"
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.6.tgz#d37f504f6560b36616f646a606894fe18819107f"
integrity sha512-/kJ+FYVEm2HuUlw87hjSqTss+GU35D4giOpdSfGp7DO+5h6RlJj7R94YaYHOkoxu1CSaM0d3WRBtCzwXrY6MKA==
nopt@^4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==
dependencies:
abbrev "1"
osenv "^0.1.4"
normalize-package-data@^2.3.2:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@@ -2866,42 +2756,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
npm-bundled@^1.0.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b"
integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==
dependencies:
npm-normalize-package-bin "^1.0.1"
npm-normalize-package-bin@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2"
integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==
npm-packlist@^1.1.6:
version "1.4.8"
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
dependencies:
ignore-walk "^3.0.1"
npm-bundled "^1.0.1"
npm-normalize-package-bin "^1.0.1"
npmlog@^4.0.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
dependencies:
are-we-there-yet "~1.1.2"
console-control-strings "~1.1.0"
gauge "~2.7.3"
set-blocking "~2.0.0"
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
nunjucks@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/nunjucks/-/nunjucks-3.2.1.tgz#f229539281e92c6ad25d8c578c9bdb41655caf83"
@@ -2913,7 +2767,7 @@ nunjucks@^3.2.1:
optionalDependencies:
chokidar "^3.3.0"
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
object-assign@^4.0.1, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@@ -3029,24 +2883,11 @@ os-browserify@^0.3.0:
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
os-tmpdir@^1.0.0, os-tmpdir@~1.0.2:
os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
osenv@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
p-limit@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
@@ -3229,6 +3070,13 @@ prelude-ls@~1.1.2:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
prismjs@^1.20.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.20.0.tgz#9b685fc480a3514ee7198eac6a3bf5024319ff03"
integrity sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==
optionalDependencies:
clipboard "^2.0.0"
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -3346,16 +3194,6 @@ raw-body@^2.2.0:
iconv-lite "0.4.24"
unpipe "1.0.0"
rc@^1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
dependencies:
deep-extend "^0.6.0"
ini "~1.3.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
read-pkg-up@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be"
@@ -3373,7 +3211,7 @@ read-pkg@^2.0.0:
normalize-package-data "^2.3.2"
path-type "^2.0.0"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@@ -3489,7 +3327,7 @@ rimraf@2.6.3:
dependencies:
glob "^7.1.3"
rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.3:
rimraf@^2.5.4, rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
@@ -3554,11 +3392,6 @@ saslprep@^1.0.0:
dependencies:
sparse-bitfield "^3.0.3"
sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
schema-utils@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
@@ -3568,7 +3401,12 @@ schema-utils@^1.0.0:
ajv-errors "^1.0.0"
ajv-keywords "^3.1.0"
"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0, semver@^5.5.0, semver@^5.6.0:
select@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.5.0, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -3583,11 +3421,6 @@ serialize-javascript@^2.1.2:
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==
set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
set-value@^2.0.0, set-value@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
@@ -3628,7 +3461,7 @@ shebang-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
signal-exit@^3.0.0, signal-exit@^3.0.2:
signal-exit@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
@@ -3822,16 +3655,7 @@ stream-shift@^1.0.0:
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
dependencies:
code-point-at "^1.0.0"
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
"string-width@^1.0.2 || 2", string-width@^2.0.0:
string-width@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
@@ -3905,7 +3729,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
@@ -3943,11 +3767,6 @@ strip-json-comments@^3.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180"
integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
@@ -3982,19 +3801,6 @@ tapable@^1.0.0, tapable@^1.1.3:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
tar@^4.4.2:
version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
dependencies:
chownr "^1.1.1"
fs-minipass "^1.2.5"
minipass "^2.8.6"
minizlib "^1.2.1"
mkdirp "^0.5.0"
safe-buffer "^5.1.2"
yallist "^3.0.3"
terser-webpack-plugin@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c"
@@ -4058,6 +3864,11 @@ timers-browserify@^2.0.4:
dependencies:
setimmediate "^1.0.4"
tiny-emitter@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@@ -4350,13 +4161,6 @@ which@^1.2.9:
dependencies:
isexe "^2.0.0"
wide-align@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
dependencies:
string-width "^1.0.2 || 2"
word-wrap@~1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
@@ -4391,7 +4195,7 @@ y18n@^4.0.0:
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3:
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==