diff --git a/README.md b/README.md index 50dcec4..d3337c1 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,17 @@ # sardonyx-server サードニクス -Server for Sardonyx・サードニクスのサーバー +Server for Sardonyx -## About・概要 -Sardonyx is an online solution to transform how students and teachers use technology at the International Baccalaureate Diploma Program in Tokyo Metropolitan Kokusai High School. Sardonyx offers a cross-platfrom experience for all its users, through its mobile and web platforms. This repository contains code for Sardonyx's mobile application. +## About +Sardonyx is an online solution to transform how high school students and teachers use technology to manage workloads. Sardonyx offers a cross-platfrom experience for all its users, through its mobile and web platforms. This repository contains code for Sardonyx's web application, targeted for computers and tablets. -The mobile application offers a responsive mobile experience of Kokusai's online environment. It also provides a real time messaging service between students and teachers. This is a solution to enhance student-teacher communication while complying to the Tokyo Metropolitan Board of Education's policies. +The web application offers a group tasklist accessible by both teachers and students. Students and teachers benefit from the transparency of the workload, organized by due dates, subjects, and task categories. Each task on the list can be given a detailed description. -サードニクスは東京都立国際高校国際バカロレアコースの生徒と教員のテクノロジーの使い方を改新するためのオンラインソリューションです。 -スマートフォンとウェブアプリケーションを通じてサードニクスはクロスプラットフォームなサービスを提供する予定です。このリポジトリでは、サードニクスのスマートフォンアプリケーションのコードを載せております。 +## How to Use +Navigate to [sardonyx.app](https://sardonyx.app), then enter your credentials. Students can use their Managebac credentials to login, while teachers are assigned a login and a password. -本アプリケーションはスマートフォンでの国際高校のICT環境を改善するほか、生徒・教員間のリアルタイムメッセージングサービスを提供目標としています。これは東京都教育委員会のポリシーに従いながら、生徒と先生の間のコミュニケーションを改善するソリューションなのです。 - -## How to Use・使用方法 -Sardonyx is currently under development and is not available for use. - -サードニクスは現在開発途中で、まだ非公開です。 +Read the info page in the app to learn more about using the application. ## API Sardonyx's Managebac API can be accessed at the following endpoints. @@ -347,5 +342,153 @@ Required: `Reflection-Data` header with JSON: } ``` +### Web-based Authentication API +#### Student login +``` +POST /login/student +``` + +Required: multipart form in request body with `login` and `password` for `https://kokusaiib.managebac.com` + +#### Teacher login +``` +POST /login/teacher +``` + +Required: multipart form in request body with Sardonyx `login` and `password` + +#### Logout +``` +GET /logout +``` + +Required: valid signed JWT cookie + +#### Change Password (teachers) +``` +POST /password +``` + +Required: valid signed JWT cookie with email and JSON request body in request body with `new_password` + +### Tasklist API +#### Load user details + +``` +GET /app/user +GET /app/user?tasklist=:tasklist +``` + +Required: valid signed JWT cookie with `email` property and `tasklist` property or a `tasklist` URL parameter + +Tasklists can be specified for retrieving default labels (teachers only) + +#### Change default labels +Add default labels +``` +POST /app/user/subjects?id=:id +POST /app/user/categories?id=:id +``` + +Remove default labels +``` +DELETE /app/user/subjects?id=:id +DELETE /app/user/categories?id=:id +``` + +Required: valid signed JWT cookie with `id` property and `id` URL parameter (for label's id) + +#### Change default tasklist +``` +PATCH /app/user/tasklist?id=:id +``` + +Required: valid signed JWT cookie with `id` property and `id` URL parameter (for tasklist's id) + +#### Load tasklist +``` +GET /app/tasklist +GET /app/tasklist?tasklist=:tasklist +GET /app/tasklist?tasklist=all +``` + +Required for students: valid signed JWT cookie with `tasklist` property + +Required for teachers: valid signed JWT cookie with `tasklist` property or a `tasklist` URL parameter + +To select all tasklists, pass `all` as the tasklist URL parameter (teachers only) + +#### Load tasks +``` +GET /app/tasks +GET /app/tasks?tasklist=:tasklist +GET /app/tasks?full=true +``` + +Required for students: valid signed JWT cookie with `tasklist` property + +Required for teachers: valid signed JWT token with `tasklist` property or a `tasklist` URL parameter + +To select labels associated with tasks, pass true for `full`. + +#### Change tasks +Create tasks +``` +POST /app/task +``` + +Required: valid signed JWT cookie and JSON request body with task information + +Edit tasks +``` +PATCH /app/task?id=:id +``` + +Required: valid signed JWT cookie, `id` URL parameter, and JSON request body with task information. + +Delete tasks +``` +DELETE /app/task?id=:id +``` + +Required: valid signed JWT cookie and `id` URL parameter. + +#### Load subjects or categories labels +``` +GET /app/subjects +GET /app/subjects?tasklist=:tasklist +GET /app/categories +GET /app/categories?tasklist=:tasklist +``` + +Required for students: valid signed JWT cookie with `tasklist` property + +Required for teachers: valid signed JWT with `tasklist` property or a `tasklist` URL parameter + +#### Change subjects or categories labels +Add labels +``` +POST /app/subjects +POST /app/categories +``` + +Required: valid signed JWT cookie and JSON request body with label information. + +Edit labels +``` +PATCH /app/subjects?id=:id +PATCH /app/categories?id=:id +``` + +Required: valid signed JWT cookie, `id` URL paramter, JSON request body with label information + +Delete labels +``` +DELETE /app/subjects?id=:id +DELETE /app/categories?id=:id +``` + +Required: valid signed JWT cookie and `id` URL parameter + ## Contribution For contribution, see `CONTRIBUTING.md` in SardonyxApp/sardonyx repository. \ No newline at end of file diff --git a/__tests__/api.test.js b/__tests__/api.test.js index 6488270..d860146 100644 --- a/__tests__/api.test.js +++ b/__tests__/api.test.js @@ -1,19 +1,6 @@ const request = require('supertest'); const app = require('../app'); -describe('Random API', () => { - describe('GET /random', () => { - test('GET /random should return 401 or 200', (done) => { - request(app) - .get('/random') - .then(response => { - expect(response.statusCode === 200 || response.statusCode === 401).toBeTruthy(); - done(); - }); - }); - }); -}); - describe('CORS', () => { test('GET /api should have Access-Control-Allow-Origin set to *', (done) => { request(app) diff --git a/__tests__/authentication.test.js b/__tests__/authentication.test.js index 2510e1b..6bba725 100644 --- a/__tests__/authentication.test.js +++ b/__tests__/authentication.test.js @@ -1,5 +1,6 @@ const request = require('supertest'); const app = require('../app'); +const db = require('../db'); require('dotenv').config(); @@ -118,67 +119,75 @@ describe('Authentication API', () => { }); }); - describe('POST /api/login', () => { - test('POST /api/login should return 401 without credentials', (done) => { - request(app) - .post('/api/login') - .then(response => { - expect(response.statusCode).toBe(401); - done(); - }); - }); - - test('POST /api/login should return 200 with valid credentials', (done) => { - request(app) - .post('/api/login') - .set('Content-Type', 'multipart/form-data') - .field('login', process.env.LOGIN) - .field('password', process.env.PASSWORD) - .then(response => { - expect(response.statusCode).toBe(200); - done(); - }); - }); - - test('POST /api/login should return 401 with invalid login', (done) => { - request(app) - .post('/api/login') - .set('Content-Type', 'multipart/form-data') - .field('login', 'foo@bar.com') - .field('password', process.env.PASSWORD) - .then(response => { - expect(response.statusCode).toBe(401); - done(); - }); - }); - - test('POST /api/login should return 401 with invalid password', (done) => { - request(app) - .post('/api/login') - .set('Content-Type', 'multipart/form-data') - .field('login', process.env.LOGIN) - .field('password', 'foobar') - .then(response => { - expect(response.statusCode).toBe(401); - done(); - }); - }); - - test('POST /api/login should return Login-Token with valid credentials', (done) => { - request(app) - .post('/api/login') - .set('Content-Type', 'multipart/form-data') - .field('login', process.env.LOGIN) - .field('password', process.env.PASSWORD) - .then(response => { - const credentials = JSON.parse(response.headers['login-token'] || '{}'); - expect(credentials).toHaveProperty('login'); - expect(credentials).toHaveProperty('password'); - expect(credentials).toHaveProperty('managebacSession'); - expect(credentials).toHaveProperty('cfduid'); - expect(credentials).toHaveProperty('authenticityToken'); - done(); - }); + db.connect(err => { + if (err) { + console.error(err); + process.exit(1); + } + + describe('POST /api/login', () => { + test('POST /api/login should return 401 without credentials', (done) => { + request(app) + .post('/api/login') + .then(response => { + expect(response.statusCode).toBe(401); + done(); + }); + }); + + test('POST /api/login should return 200 with valid credentials', (done) => { + request(app) + .post('/api/login') + .set('Content-Type', 'multipart/form-data') + .field('login', process.env.LOGIN) + .field('password', process.env.PASSWORD) + .then(response => { + expect(response.statusCode).toBe(200); + done(); + }); + }); + + test('POST /api/login should return 401 with invalid login', (done) => { + request(app) + .post('/api/login') + .set('Content-Type', 'multipart/form-data') + .field('login', 'foo@bar.com') + .field('password', process.env.PASSWORD) + .then(response => { + expect(response.statusCode).toBe(401); + done(); + }); + }); + + test('POST /api/login should return 401 with invalid password', (done) => { + request(app) + .post('/api/login') + .set('Content-Type', 'multipart/form-data') + .field('login', process.env.LOGIN) + .field('password', 'foobar') + .then(response => { + expect(response.statusCode).toBe(401); + done(); + }); + }); + + test('POST /api/login should return Login-Token with valid credentials', (done) => { + request(app) + .post('/api/login') + .set('Content-Type', 'multipart/form-data') + .field('login', process.env.LOGIN) + .field('password', process.env.PASSWORD) + .then(response => { + const credentials = JSON.parse(response.headers['login-token'] || '{}'); + expect(credentials).toHaveProperty('login'); + expect(credentials).toHaveProperty('password'); + expect(credentials).toHaveProperty('managebacSession'); + expect(credentials).toHaveProperty('cfduid'); + expect(credentials).toHaveProperty('authenticityToken'); + expect(response.headers).toHaveProperty('sardonyx-token'); + done(); + }); + }); }); }); }); \ No newline at end of file diff --git a/__tests__/managebac.test.js b/__tests__/managebac.test.js index 72d1a86..236085d 100644 --- a/__tests__/managebac.test.js +++ b/__tests__/managebac.test.js @@ -1,9 +1,10 @@ const request = require('supertest'); const app = require('../app'); +const db = require('../db'); // Required, since db is usually started in server.js require('dotenv').config(); -jest.setTimeout(30000); +jest.setTimeout(60000); describe('Load default', () => { describe('GET /api/validate', () => { @@ -81,88 +82,96 @@ describe('Load default', () => { }); }); - describe('POST /api/login', () => { - test('POST /api/login should return valid tokens', done => { - request(app) - .post('/api/login') - .set('Content-Type', 'multipart/form-data') - .field('login', process.env.LOGIN) - .field('password', process.env.PASSWORD) - .then(response => { - expect(response.statusCode).toBe(200); - const credentials = JSON.parse(response.headers['login-token'] || '{}'); - expect(credentials).toHaveProperty('cfduid'); - expect(credentials).toHaveProperty('managebacSession'); - expect(credentials).toHaveProperty('authenticityToken'); - done(); - }); - }); - - test('POST /api/login should return a valid deadlines json', done => { - request(app) - .post('/api/login') - .set('Content-Type', 'multipart/form-data') - .field('login', process.env.LOGIN) - .field('password', process.env.PASSWORD) - .then(response => { - const deadlines = JSON.parse(response.headers['managebac-data']).deadlines; - deadlines.forEach(item => { - expect(typeof item.title).toBe('string'); - expect(typeof item.link).toBe('string'); - expect(Array.isArray(item.labels)).toBeTruthy(); - expect(typeof item.deadline).toBe('boolean'); - expect(typeof item.due).toBe('string'); - expect(typeof Date.parse(item.due)).toBe('number'); - expect(typeof item.author).toBe('string'); - expect(typeof item.avatar === 'string' || item.avatar === null).toBeTruthy(); + db.connect(err => { + if (err) { + console.error('There was an error connecting to MySQL. ' + err); + process.exit(1); + } + + describe('POST /api/login', () => { + test('POST /api/login should return valid tokens', done => { + request(app) + .post('/api/login') + .set('Content-Type', 'multipart/form-data') + .field('login', process.env.LOGIN) + .field('password', process.env.PASSWORD) + .then(response => { + expect(response.statusCode).toBe(200); + const credentials = JSON.parse(response.headers['login-token'] || '{}'); + expect(credentials).toHaveProperty('cfduid'); + expect(credentials).toHaveProperty('managebacSession'); + expect(credentials).toHaveProperty('authenticityToken'); + expect(response.headers).toHaveProperty('sardonyx-token'); + done(); }); - done(); - }); - }); - - test('POST /api/login should return a valid classes json', done => { - request(app) - .post('/api/login') - .set('Content-Type', 'multipart/form-data') - .field('login', process.env.LOGIN) - .field('password', process.env.PASSWORD) - .then(response => { - const classes = JSON.parse(response.headers['managebac-data']).classes; - classes.forEach(item => { - expect(typeof item.title).toBe('string'); - expect(typeof item.link).toBe('string'); + }); + + test('POST /api/login should return a valid deadlines json', done => { + request(app) + .post('/api/login') + .set('Content-Type', 'multipart/form-data') + .field('login', process.env.LOGIN) + .field('password', process.env.PASSWORD) + .then(response => { + const deadlines = JSON.parse(response.headers['managebac-data']).deadlines; + deadlines.forEach(item => { + expect(typeof item.title).toBe('string'); + expect(typeof item.link).toBe('string'); + expect(Array.isArray(item.labels)).toBeTruthy(); + expect(typeof item.deadline).toBe('boolean'); + expect(typeof item.due).toBe('string'); + expect(typeof Date.parse(item.due)).toBe('number'); + expect(typeof item.author).toBe('string'); + expect(typeof item.avatar === 'string' || item.avatar === null).toBeTruthy(); + }); + done(); }); - done(); - }); - }); - - test('POST /api/login should return a valid groups json', done => { - request(app) - .post('/api/login') - .set('Content-Type', 'multipart/form-data') - .field('login', process.env.LOGIN) - .field('password', process.env.PASSWORD) - .then(response => { - const groups = JSON.parse(response.headers['managebac-data']).groups; - groups.forEach(item => { - expect(typeof item.title).toBe('string'); - expect(typeof item.link).toBe('string'); + }); + + test('POST /api/login should return a valid classes json', done => { + request(app) + .post('/api/login') + .set('Content-Type', 'multipart/form-data') + .field('login', process.env.LOGIN) + .field('password', process.env.PASSWORD) + .then(response => { + const classes = JSON.parse(response.headers['managebac-data']).classes; + classes.forEach(item => { + expect(typeof item.title).toBe('string'); + expect(typeof item.link).toBe('string'); + }); + done(); }); - done(); - }); - }); - - test('POST /api/login should return a valid notification count', done => { - request(app) - .post('/api/login') - .set('Content-Type', 'multipart/form-data') - .field('login', process.env.LOGIN) - .field('password', process.env.PASSWORD) - .then(response => { - const notificationCount = JSON.parse(response.headers['managebac-data']).notificationCount; - expect(typeof notificationCount).toBe('number'); - done(); - }); + }); + + test('POST /api/login should return a valid groups json', done => { + request(app) + .post('/api/login') + .set('Content-Type', 'multipart/form-data') + .field('login', process.env.LOGIN) + .field('password', process.env.PASSWORD) + .then(response => { + const groups = JSON.parse(response.headers['managebac-data']).groups; + groups.forEach(item => { + expect(typeof item.title).toBe('string'); + expect(typeof item.link).toBe('string'); + }); + done(); + }); + }); + + test('POST /api/login should return a valid notification count', done => { + request(app) + .post('/api/login') + .set('Content-Type', 'multipart/form-data') + .field('login', process.env.LOGIN) + .field('password', process.env.PASSWORD) + .then(response => { + const notificationCount = JSON.parse(response.headers['managebac-data']).notificationCount; + expect(typeof notificationCount).toBe('number'); + done(); + }); + }); }); }); diff --git a/app.js b/app.js index 9981fea..6cf2b07 100644 --- a/app.js +++ b/app.js @@ -1,32 +1,36 @@ +/** + * @fileoverview Manage routes for the Managebac parser, tasklist, and web pages. + * @author SardonyxApp + * @license MIT + */ + const express = require('express'); const app = express(); const multer = require('multer'); const upload = multer(); // Used to parse multipart/form-data +const cookieParser = require('cookie-parser'); +app.use(cookieParser()); require('dotenv').config(); // Used to parse .env // Custom helper utilities const auth = require('./helpers/authentication'); const mb = require('./helpers/managebac'); +const task = require('./helpers/tasklists'); const send = require('./helpers/sender'); const { end200 } = require('./helpers/helpers'); -app.use(express.static('public')); - -// Route to return a random response code of either 401 or 200 -app.all('/random', (req, res) => { - const random = Math.floor(Math.random() * 2); // Generate either 0 or 1 - res.sendStatus(random === 0 ? 401 : 200); -}); - -// Set general settings on all of the API routes -app.use('/api', (req, res, next) => { - // Allow from all for now, for testing purposes - res.set('Access-Control-Allow-Origin', '*'); +// Determine request type +app.use((req, res, next) => { + req.type = /^\/api/.test(req.path) ? 'api' : 'browser'; next(); }); +/** + * Managebac API + */ + // Initial validation app.get('/api/validate', auth.createBody, auth.loginToManagebac, mb.loadDefaults); @@ -35,80 +39,146 @@ app.get('/api/login', auth.createBody, auth.loginToManagebac, end200); // Initial login // use upload.none() when it's only text fields -app.post('/api/login', upload.none(), auth.loginToManagebac, auth.createSardonyxToken, mb.loadDefaults); +app.post('/api/login', upload.none(), auth.loginToManagebac, auth.initiateStudent, mb.loadDefaults); + +// Create tokens for all Managebac API requests +app.use('/api', auth.createTokens); // Load dashboard -app.get('/api/dashboard', auth.createTokens, mb.createUrl(), send, mb.loadDefaults); +app.get('/api/dashboard', mb.createUrl(), send, mb.loadDefaults); // Load class -app.get('/api/class/:resourceId/overview', auth.createTokens, mb.createUrl('classes'), send, mb.loadOverview); -app.get('/api/class/:resourceId/assignments', auth.createTokens, mb.createUrl('classes', 'assignments'), send, mb.loadAssignments); -app.get('/api/class/:resourceId/messages', auth.createTokens, mb.createUrl('classes', 'discussions'), send, mb.loadMessages); +app.get('/api/class/:resourceId/overview', mb.createUrl('classes'), send, mb.loadOverview); +app.get('/api/class/:resourceId/assignments', mb.createUrl('classes', 'assignments'), send, mb.loadAssignments); +app.get('/api/class/:resourceId/messages', mb.createUrl('classes', 'discussions'), send, mb.loadMessages); // Load group -app.get('/api/group/:resourceId/overview', auth.createTokens, mb.createUrl('groups'), send, mb.loadOverview); -app.get('/api/group/:resourceId/messages', auth.createTokens, mb.createUrl('groups', 'discussions'), send, mb.loadMessages); +app.get('/api/group/:resourceId/overview', mb.createUrl('groups'), send, mb.loadOverview); +app.get('/api/group/:resourceId/messages', mb.createUrl('groups', 'discussions'), send, mb.loadMessages); // Load assignment or event -app.get('/api/class/:resourceId/assignments/:subresourceId', auth.createTokens, mb.createUrl('classes', 'assignments'), send, mb.loadAssignment); -app.get('/api/event/:resourceId', auth.createTokens, mb.createUrl('ib/events'), send, mb.loadAssignment); -app.get('/api/class/:resourceId/events/:subresourceId', auth.createTokens, mb.createUrl('classes', 'events'), send, mb.loadAssignment); -app.get('/api/group/:resourceId/events/:subresourceId', auth.createTokens, mb.createUrl('groups', 'events'), send, mb.loadAssignment); +app.get('/api/class/:resourceId/assignments/:subresourceId', mb.createUrl('classes', 'assignments'), send, mb.loadAssignment); +app.get('/api/event/:resourceId', mb.createUrl('ib/events'), send, mb.loadAssignment); +app.get('/api/class/:resourceId/events/:subresourceId', mb.createUrl('classes', 'events'), send, mb.loadAssignment); +app.get('/api/group/:resourceId/events/:subresourceId', mb.createUrl('groups', 'events'), send, mb.loadAssignment); // Load message and replies -app.get('/api/class/:resourceId/messages/:subresourceId', auth.createTokens, mb.createUrl('classes', 'discussions'), send, mb.loadMessage); -app.get('/api/group/:resourceId/messages/:subresourceId', auth.createTokens, mb.createUrl('groups', 'discussions'), send, mb.loadMessage); +app.get('/api/class/:resourceId/messages/:subresourceId', mb.createUrl('classes', 'discussions'), send, mb.loadMessage); +app.get('/api/group/:resourceId/messages/:subresourceId', mb.createUrl('groups', 'discussions'), send, mb.loadMessage); // Load repies of reply -app.get('/api/class/:resourceId/messages/:subresourceId/reply/:subitemId', auth.createTokens, mb.createUrl('classes', 'discussions', 'replies'), mb.craftRequestForReplyOfReply, send, mb.loadReplyOfReply); -app.get('/api/group/:resourceId/messages/:subresourceId/reply/:subitemId', auth.createTokens, mb.createUrl('groups', 'discussions', 'replies'), mb.craftRequestForReplyOfReply, send, mb.loadReplyOfReply); +app.get('/api/class/:resourceId/messages/:subresourceId/reply/:subitemId', mb.createUrl('classes', 'discussions', 'replies'), mb.craftRequestForReplyOfReply, send, mb.loadReplyOfReply); +app.get('/api/group/:resourceId/messages/:subresourceId/reply/:subitemId', mb.createUrl('groups', 'discussions', 'replies'), mb.craftRequestForReplyOfReply, send, mb.loadReplyOfReply); // Send message -app.post('/api/class/:resourceId/messages', auth.createTokens, mb.createUrl('classes', 'discussions'), mb.craftNewMessage, send, mb.loadMessages); -app.post('/api/group/:resourceId/messages', auth.createTokens, mb.createUrl('groups', 'discussions'), mb.craftNewMessage, send, mb.loadMessages); +app.post('/api/class/:resourceId/messages', mb.createUrl('classes', 'discussions'), mb.craftNewMessage, send, mb.loadMessages); +app.post('/api/group/:resourceId/messages', mb.createUrl('groups', 'discussions'), mb.craftNewMessage, send, mb.loadMessages); // Edit message -app.patch('/api/class/:resourceId/messages/:subresourceId', auth.createTokens, mb.createUrl('classes', 'discussions'), mb.craftMessage, send, mb.loadMessages); -app.patch('/api/group/:resourceId/messages/:subresourceId', auth.createTokens, mb.createUrl('groups', 'discussions'), mb.craftMessage, send, mb.loadMessages); +app.patch('/api/class/:resourceId/messages/:subresourceId', mb.createUrl('classes', 'discussions'), mb.craftMessage, send, mb.loadMessages); +app.patch('/api/group/:resourceId/messages/:subresourceId', mb.createUrl('groups', 'discussions'), mb.craftMessage, send, mb.loadMessages); // Delete message -app.delete('/api/class/:resourceId/messages/:subresourceId', auth.createTokens, mb.createUrl('classes', 'discussions'), send, mb.loadMessages); -app.delete('/api/group/:resourceId/messages/:subresourceId', auth.createTokens, mb.createUrl('groups', 'discussions'), send, mb.loadMessages); +app.delete('/api/class/:resourceId/messages/:subresourceId', mb.createUrl('classes', 'discussions'), send, mb.loadMessages); +app.delete('/api/group/:resourceId/messages/:subresourceId', mb.createUrl('groups', 'discussions'), send, mb.loadMessages); // Send reply -app.post('/api/class/:resourceId/messages/:subresourceId/reply', auth.createTokens, mb.createUrl('classes', 'discussions', 'replies'), mb.craftNewReply, send, end200); -app.post('/api/group/:resourceId/messages/:subresourceId/reply', auth.createTokens, mb.createUrl('groups', 'discussions', 'replies'), mb.craftNewReply, send, end200); +app.post('/api/class/:resourceId/messages/:subresourceId/reply', mb.createUrl('classes', 'discussions', 'replies'), mb.craftNewReply, send, end200); +app.post('/api/group/:resourceId/messages/:subresourceId/reply', mb.createUrl('groups', 'discussions', 'replies'), mb.craftNewReply, send, end200); // Send reply to reply -app.post('/api/class/:resourceId/messages/:subresourceId/reply/:subitemId', auth.createTokens, mb.createUrl('classes', 'discussions', 'replies'), mb.craftNewReply, send, end200); -app.post('/api/group/:resourceId/messages/:subresourceId/reply/:subitemId', auth.createTokens, mb.createUrl('groups', 'discussions', 'replies'), mb.craftNewReply, send, end200); +app.post('/api/class/:resourceId/messages/:subresourceId/reply/:subitemId', mb.createUrl('classes', 'discussions', 'replies'), mb.craftNewReply, send, end200); +app.post('/api/group/:resourceId/messages/:subresourceId/reply/:subitemId', mb.createUrl('groups', 'discussions', 'replies'), mb.craftNewReply, send, end200); // Edit reply -app.patch('/api/class/:resourceId/messages/:subresourceId/reply/:subitemId', auth.createTokens, mb.createUrl('classes', 'discussions', 'replies'), mb.craftReply, send, end200); -app.patch('/api/group/:resourceId/messages/:subresourceId/reply/:subitemId', auth.createTokens, mb.createUrl('groups', 'discussions', 'replies'), mb.craftReply, send, end200); +app.patch('/api/class/:resourceId/messages/:subresourceId/reply/:subitemId', mb.createUrl('classes', 'discussions', 'replies'), mb.craftReply, send, end200); +app.patch('/api/group/:resourceId/messages/:subresourceId/reply/:subitemId', mb.createUrl('groups', 'discussions', 'replies'), mb.craftReply, send, end200); // Delete reply -app.delete('/api/class/:resourceId/messages/:subresourceId/reply/:subitemId', auth.createTokens, mb.createUrl('classes', 'discussions', 'replies'), send, end200); -app.delete('/api/group/:resourceId/messages/:subresourceId/reply/:subitemId', auth.createTokens, mb.createUrl('groups', 'discussions', 'replies'), send, end200); +app.delete('/api/class/:resourceId/messages/:subresourceId/reply/:subitemId', mb.createUrl('classes', 'discussions', 'replies'), send, end200); +app.delete('/api/group/:resourceId/messages/:subresourceId/reply/:subitemId', mb.createUrl('groups', 'discussions', 'replies'), send, end200); // Load notifications -app.get('/api/notification', auth.createTokens, mb.createUrl('notifications'), send, mb.loadNotifications); -app.get('/api/notification/:resourceId', auth.createTokens, mb.createUrl('notifications'), send, mb.loadNotification); +app.get('/api/notification', mb.createUrl('notifications'), send, mb.loadNotifications); +app.get('/api/notification/:resourceId', mb.createUrl('notifications'), send, mb.loadNotification); // CAS -app.get('/api/cas', auth.createTokens, mb.createUrl('ib/activity/cas'), send, mb.loadCas); -app.get('/api/cas/:resourceId/overview', auth.createTokens, mb.createUrl('ib/activity/cas'), send, mb.loadExperience); +app.get('/api/cas', mb.createUrl('ib/activity/cas'), send, mb.loadCas); +app.get('/api/cas/:resourceId/overview', mb.createUrl('ib/activity/cas'), send, mb.loadExperience); // CAS Answers -app.get('/api/cas/:resourceId/answers', auth.createTokens, mb.createUrl('ib/activity/cas', 'answers'), send, mb.loadAnswers); -app.post('/api/cas/:resourceId/answers', auth.createTokens, mb.createUrl('ib/activity/cas', 'answers'), mb.craftAnswers, send, mb.loadAnswers); +app.get('/api/cas/:resourceId/answers', mb.createUrl('ib/activity/cas', 'answers'), send, mb.loadAnswers); +app.post('/api/cas/:resourceId/answers', mb.createUrl('ib/activity/cas', 'answers'), mb.craftAnswers, send, mb.loadAnswers); // CAS Reflections -app.get('/api/cas/:resourceId/reflections', auth.createTokens, mb.createUrl('ib/activity/cas', 'reflections'), send, mb.loadReflections); -app.post('/api/cas/:resourceId/reflections', auth.createTokens, mb.createUrl('ib/activity/cas', 'reflections'), mb.craftNewReflection, send, mb.loadReflections); -app.patch('/api/cas/:resourceId/reflections/:subresourceId', auth.createTokens, mb.createUrl('ib/activity/cas', 'reflections'), mb.craftReflection, send, mb.loadReflections); -app.delete('/api/cas/:resourceId/reflections/:subresourceId', auth.createTokens, mb.createUrl('ib/activity/cas', 'reflections'), send, mb.loadReflections); -app.get('/api/cas/:resourceId/learning_outcomes', auth.createTokens, mb.createUrl('ib/activity/cas', 'reflections/new'), send, mb.loadLearningOutcomes); +app.get('/api/cas/:resourceId/reflections', mb.createUrl('ib/activity/cas', 'reflections'), send, mb.loadReflections); +app.post('/api/cas/:resourceId/reflections', mb.createUrl('ib/activity/cas', 'reflections'), mb.craftNewReflection, send, mb.loadReflections); +app.patch('/api/cas/:resourceId/reflections/:subresourceId', mb.createUrl('ib/activity/cas', 'reflections'), mb.craftReflection, send, mb.loadReflections); +app.delete('/api/cas/:resourceId/reflections/:subresourceId', mb.createUrl('ib/activity/cas', 'reflections'), send, mb.loadReflections); +app.get('/api/cas/:resourceId/learning_outcomes', mb.createUrl('ib/activity/cas', 'reflections/new'), send, mb.loadLearningOutcomes); + +/** + * Sardonyx Web App + */ + +app.use('/login', upload.none()); + +// Student login through web client +app.post('/login/student', auth.loginToManagebac, auth.initiateStudent, (req, res) => { + req.firstTime ? res.redirect('/app?info=true') : res.redirect('/app'); +}); + +// Teacher login through web client +app.post('/login/teacher', auth.initiateTeacher, (req, res) => { + req.firstTime ? res.redirect('/app?info=true') : res.redirect('/app'); +}); + +app.get('/logout', auth.authenticateToken, auth.logout); + +// Change password +app.use('/password', auth.authenticateToken, upload.none(), (req, res, next) => { + if (!req.token.teacher) res.status(401).send('Students must change passwords through Managebac.'); + else next(); +}); +app.post('/password', auth.changePassword); + +// Authenticate +app.use('/app', auth.authenticateToken, auth.authenticateTasklist); + +app.get('/app/user', task.loadUser); // Tasklist can be specified for user too because of preferred labels +app.get('/app/tasklist', task.loadTasklist); +app.get('/app/tasks', task.loadTasks); +app.get('/app/subjects', task.loadLabel('subjects')); +app.get('/app/categories', task.loadLabel('categories')); + +app.delete('/app/task', task.deleteTask); +app.delete('/app/subjects', task.deleteLabel('subjects')); +app.delete('/app/categories', task.deleteLabel('categories')); + +app.post('/app/user/subjects', task.changeUserLabel('subjects', 'add')); +app.delete('/app/user/subjects', task.changeUserLabel('subjects', 'delete')); +app.post('/app/user/subjects', task.changeUserLabel('categories', 'add')); +app.delete('/app/user/subjects', task.changeUserLabel('categories', 'delete')); +app.patch('/app/user/tasklist', task.changeTeacherTasklist); + +// Data with JSON body +app.use('/app', express.json()); + +app.post('/app/task', task.craftTask, task.createTask); +app.patch('/app/task', task.craftTask, task.editTask); +app.post('/app/subjects', task.createLabel('subjects')); +app.post('/app/categories', task.createLabel('categories')); +app.patch('/app/subjects', task.updateLabel('subjects')); +app.patch('/app/categories', task.updateLabel('categories')); + +/** + * Public + */ + +// Serve html files +app.use(express.static('public')); + +app.use('/favicon.ico', express.static(__dirname + '/public/Icon.png')); module.exports = app; // app.js and server.js are split for testing reasons \ No newline at end of file diff --git a/app.yaml b/app.yaml index f0ccc6d..92c2a60 100644 --- a/app.yaml +++ b/app.yaml @@ -1 +1,7 @@ runtime: nodejs8 + +handlers: +- url: /.* + secure: always + redirect_http_response_code: 301 + script: auto \ No newline at end of file diff --git a/db.js b/db.js new file mode 100644 index 0000000..b536e55 --- /dev/null +++ b/db.js @@ -0,0 +1,42 @@ +/** + * @fileoverview Facilitate database connections. + * @author SardonyxApp + * @license MIT + */ + +const mysql = require('mysql'); +require('dotenv').config(); + +const state = { + pool: null +}; + +/** + * @description Start a database pool + * @param {Function} callback + */ +exports.connect = callback => { + state.pool = process.env.MODE === 'production' + ? mysql.createPool({ + socketPath: `/cloudsql/${process.env.DB_INSTANCE}`, + user: process.env.DB_LOGIN, + password: process.env.DB_PASSWORD, + database: process.env.DB_DATABASE + }) + : mysql.createPool({ + host: process.env.DB_HOST, + user: process.env.DB_LOGIN, + password: process.env.DB_PASSWORD, + database: process.env.DB_DATABASE + }); + + console.log(`Created pool. User: ${process.env.DB_LOGIN}@${process.env.DB_HOST || '%'} and Database: ${process.env.DB_DATABASE}`); + + callback(); +}; + +/** + * @description Use a pre-existing database pool + * @returns Pool + */ +exports.get = () => state.pool; diff --git a/helpers/authentication.js b/helpers/authentication.js index 2ac0808..fb941c7 100644 --- a/helpers/authentication.js +++ b/helpers/authentication.js @@ -5,7 +5,13 @@ */ const request = require('request'); +const jwt = require('jsonwebtoken'); + +require('dotenv').config(); + const parser = require('./parsers'); +const { students, teachers } = require('../models/users'); +const { hashPassword } = require('./helpers'); /** * @description Convert Login-Token header to req.body FormData @@ -27,7 +33,7 @@ exports.createBody = (req, res, next) => { next(); } else { // The request did not contain a login-token, unauthorize them before sending useless requests - res.status(401).end(); + res.status(401).send('The request did not contain the necessary credentials.'); } }; @@ -60,15 +66,13 @@ exports.createTokens = (req, res, next) => { next(); } else { // The request did not contain token information, redirect them to reissue - res.status(401).end(); + res.status(401).send('The request did not contain the necessary credentials.'); } }; /** * @description Validate login in req.body using Managebac - * @param {Object} req Request with body containing keys 'login' and 'password' - * @param {Object} res - * @param {Function} next + * @param {String} redir URL to redirect to upon failure, or the middleware will return 401 */ exports.loginToManagebac = (req, res, next) => { const additionalFormData = { @@ -85,48 +89,200 @@ exports.loginToManagebac = (req, res, next) => { }, (err, response) => { if (err) { console.error(err); - res.status(502).end(); + res.status(502).send('There was an error connecting to Managebac. ' + err); return; } // Successfully returns student page if (response.request.uri.href === 'https://kokusaiib.managebac.com/student') { - const __cfduid = cookieJar.getCookieString('https://kokusaiib.managebac.com').split(';')[0]; - const _managebac_session = cookieJar.getCookieString('https://kokusaiib.managebac.com').split(';')[3]; - const login = req.body.login; - const password = req.body.password; // Encrypt this in the future + // Store returned tokens + req.token = { + cfduid: cookieJar.getCookieString('https://kokusaiib.managebac.com').split(';')[0], + managebacSession: cookieJar.getCookieString('https://kokusaiib.managebac.com').split(';')[3] + }; + const payload = JSON.stringify({ - cfduid: __cfduid, - managebacSession: _managebac_session, + cfduid: req.token.cfduid, + managebacSession: req.token.managebacSession, authenticityToken: parser.parseAuthenticityToken(response.body), - login: login, - password: password + login: req.body.login, + password: req.body.password }); + res.append('Login-Token', payload); req.document = response.body; return next(); } // Nonexistent or incorrect redirection, unauthorized - res.status(401).end(); + if (req.type === 'api') res.status(401).send('The login was rejected by Managebac.'); + else res.redirect('/login?invalid=true'); }); }; /** - * This middleware is only called if loginToManagebac was 200. - * @description Creates a unique token and puts that in a DB. + * @description Handles initial sardonyx database operations for students * @param {Object} req * @param {Object} res * @param {Function} next */ -exports.createSardonyxToken = (req, res, next) => { - // Create token - const token = 'temporary0123abcd' +exports.initiateStudent = (req, res, next) => { + // Check database to see if student already exists + students.selectByEmail(req.body.login).then(results => { + return new Promise((resolve, reject) => { + // If student does not exist, create student + if (!results.length) { + req.firstTime = true; + + // Set cookies + const j = request.jar(); + j.setCookie(request.cookie(req.token.cfduid), 'https://kokusaiib.managebac.com'); + j.setCookie(request.cookie(req.token.managebacSession), 'https://kokusaiib.managebac.com'); + + // Retrieve information about student and their cohort + request.get({ + url: 'https://kokusaiib.managebac.com/student/ib/members', + jar: j + }, (err, response) => { + if (err) reject(err); + + // Store student information + const obj = Object.assign(parser.parseStudent(response.body), { + email: req.body.login + }); - // Put token in DB - // createDBEntry(req.body.login, token) + // Register the student + students.create([obj.name, obj.email, obj.year, obj.tasklist_id]) + .then(r => resolve({ ...obj, id: r.insertId })) + .catch(e => reject(e)); + }); + } else resolve(results[0]); + }); + }).then(student => { + const token = jwt.sign({ + teacher: false, + id: student.id, + email: req.body.login, + tasklist: student.tasklist_id + }, process.env.PRIVATE_KEY, { + expiresIn: '1d', + }); + + if (req.type === 'api') { + res.append('Sardonyx-Token', token); + } else { + res.cookie('Sardonyx-Token', token, { + maxAge: 86400000, // expires in 24 hours + secure: process.env.MODE === 'production', + httpOnly: true + }); + } + + next(); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error accessing the database. ' + err); + }); +}; - // Return that token - res.append('Sardonyx-Token', token); - next(); -}; \ No newline at end of file +/** + * @description Authenticates teachers + * @param {Object} req + * @param {Object} res + * @param {Function} next + */ +exports.initiateTeacher = (req, res, next) => { + // First time users do not have cookies + if (!req.cookies['Sardonyx-Token']) { + req.firstTime = true; + } + + teachers.selectByEmail(req.body.login).then(results => { + if (results.length && hashPassword(req.body.password, results[0].salt).password_digest === results[0].password_digest) { + // Valid account and correct password + + const token = jwt.sign({ + teacher: true, + id: results[0].id, + email: req.body.login, + tasklist: results[0].tasklist_id + }, process.env.PRIVATE_KEY, { + expiresIn: '1d', + }); + + res.cookie('Sardonyx-Token', token, { + maxAge: 86400000, // expires in 24 hours + secure: process.env.MODE === 'production', + httpOnly: true + }); + + next(); + } else { + // Invalid account or incorrect password + + res.redirect('/login?teacher=true&invalid=true'); + } + }).catch(err => { + console.error(err); + res.status(500).end('There was an error accessing the database. ' + err); + }); +}; + +/** + * @description Authenticates Sardonyx Tokens + * @param {Object} req + * @param {Object} res + * @param {Function} next + */ +exports.authenticateToken = (req, res, next) => { + req.token = Object.assign(req.token || {}, jwt.decode(req.cookies['Sardonyx-Token'])); + jwt.verify(req.cookies['Sardonyx-Token'], process.env.PRIVATE_KEY, (err, decoded) => { + if (err) { // Invalid or expired Sardonyx Token + if (req.type === 'browser' && req.token.teacher) res.redirect('/login?teacher=true'); + else if (req.type === 'browser') res.redirect('/login'); + else res.status(401).send('Sardonyx-Token is invalid or expired. ' + err); + } else next(); + }); +} + +/** + * @description Authenticates access to the requested tasklist + * @param {Object} req + * @param {Object} res + * @param {Function} next + */ +exports.authenticateTasklist = (req, res, next) => { + if (req.query.tasklist && req.token.teacher) { + req.token.tasklist = req.query.tasklist; + next(); + } else if (req.query.tasklist && req.token.tasklist != req.query.tasklist) { + res.status(403).send('Requested without permission.'); + } else { + next(); + } +} + +/** + * @description Clears cookies to log the user out + * @param {Object} req + * @param {Object} res + */ +exports.logout = (req, res) => { + res.clearCookie('Sardonyx-Token'); + req.token.teacher ? res.redirect('/login?teacher=true&logout=true') : res.redirect('/login?logout=true'); +} + +/** + * @description Changes password for teachers + * @param {Object} req + * @param {Object} res + */ +exports.changePassword = (req, res) => { + teachers.updatePassword(req.token.email, req.body.new_password).then(results => { + res.clearCookie('Sardonyx-Token'); + req.type === 'browser' ? res.redirect('/login?teacher=true&password=true') : res.status(200).send('Password changed successfuly'); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); +} \ No newline at end of file diff --git a/helpers/helpers.js b/helpers/helpers.js index 2535714..8c0c2b7 100644 --- a/helpers/helpers.js +++ b/helpers/helpers.js @@ -104,4 +104,24 @@ exports.toSardonyxUrl = url => { */ exports.end200 = (req, res) => { res.status(200).end(); +}; + +/** + * @description Hash a password with sha512 + * @param {String} password + * @param {String} salt (optional) + * @returns {Object} containing hashed password and salt + */ +exports.hashPassword = (password, salt) => { + const crypto = require('crypto'); + + // Generate a random bit sequence to use as salt if salt is not provided + if (!salt) salt = crypto.randomBytes(64).toString('hex'); + + // Create a hash based on salt + const hmac = crypto.createHmac('sha512', salt); + hmac.update(password); + const password_digest = hmac.digest('hex'); + + return { password_digest, salt }; }; \ No newline at end of file diff --git a/helpers/parsers.js b/helpers/parsers.js index 5932bb1..8e20d51 100644 --- a/helpers/parsers.js +++ b/helpers/parsers.js @@ -474,3 +474,19 @@ exports.parseNumberOfPages = document => { const len = $('.pagination').find('li').length - 2; // Subtract back and next buttons return len === -2 ? 1 : len; // If there are no buttons, len = -2. In that case there is 1 page }; + +/** + * @description Parse information about the student and their cohort + * @param {String} document + * @returns {Object} + */ +exports.parseStudent = document => { + const $ = cheerio.load(document); + + const obj = { + name: $('.profile-link > a ').text().delNewlines(), + year: Number($('td.col-sm-4').first().text().match(/\d{4}/)) + 3, + }; + obj.tasklist_id = obj.year - 2017; // 3rd cohort is year of 2020 + return obj; +} \ No newline at end of file diff --git a/helpers/sender.js b/helpers/sender.js index 414b4ee..4ca37ea 100644 --- a/helpers/sender.js +++ b/helpers/sender.js @@ -91,7 +91,7 @@ module.exports = (req, res, next) => { } // Nonexistent or invalid request - if (option === 1) res.status(401).end(); - else res.status(400).end(); + if (option === 1) res.status(401).send('Access was rejected by Managebac.'); + else res.status(400).send('There was an error accessing Managebac.'); }); } \ No newline at end of file diff --git a/helpers/tasklists.js b/helpers/tasklists.js new file mode 100644 index 0000000..65d2fff --- /dev/null +++ b/helpers/tasklists.js @@ -0,0 +1,268 @@ +/** + * @fileoverview Helper functions used to manage tasklists. + * @author SardonyxApp + * @license MIT + */ + +const { students, teachers } = require('../models/users'); +const tasklists = require('../models/tasklists'); +const tasks = require('../models/tasks'); +const { subjects, categories } = require('../models/labels'); +const jwt = require('jsonwebtoken'); + +/** + * @description Load user information + * @param {Object} req + * @param {Object} res + */ +exports.loadUser = (req, res) => { + const target = req.token.teacher ? teachers : students; + Promise.all([ + target.selectByEmail(req.token.email), + target.selectLabels(req.token.id, req.token.tasklist) + ]).then(results => { + const user = results[0][0]; + if (!results[0].length) res.status(400).send('Invalid user requested.'); + + // For teachers + delete user.password_digest; + delete user.salt; + + user.teacher = req.token.teacher; + user.subjects = []; + user.categories = []; + + results[1].forEach(obj => { + if (obj.subject_id) user.subjects.push(obj.subject_id); + if (obj.category_id) user.categories.push(obj.category_id); + }); + + user.tasklist_id = req.token.tasklist; // Tasklist id not synced across cookies, db entry only used for new cookies + + res.json(user); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); +}; + +/** + * @description Add or delete user's default labels + * @param {String} type subjects or categories + * @param {String} action add or delete + */ +exports.changeUserLabel = (type, action) => { + return (req, res) => { + const target = req.token.teacher ? teachers : students; + const operation = action === 'add' ? target.addLabel : target.deleteLabel; + operation.call(target, req.token.id, req.query.id, type).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); + }; +}; + +/** + * @description Update a teacher's default tasklist + * @param {Object} req + * @param {Object} res + */ +exports.changeTeacherTasklist = (req, res) => { + teachers.updateTasklist(req.token.id, req.query.id).then(results => { + const token = jwt.sign({ + teacher: req.token.teacher, + id: req.token.id, + email: req.token.email, + tasklist: req.query.id + }, process.env.PRIVATE_KEY, { + expiresIn: '1d', + }); + + res.cookie('Sardonyx-Token', token, { + maxAge: 86400000, // expires in 24 hours + secure: process.env.MODE === 'production', + httpOnly: true + }); + + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); +}; + +/** + * @description Load tasklist + * @param {Object} req + * @param {Object} res + */ +exports.loadTasklist = (req, res) => { + // Select all + if (req.token.tasklist === 'all') { + tasklists.selectAll().then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); + } else { + // Select by tasklist_id + tasklists.select(req.token.tasklist).then(results => { + if (!results.length) res.status(400).send('Invalid tasklist requested.'); + res.json(results[0]); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); + } +}; + +/** + * @description Load tasks + * @param {Object} req + * @param {Object} res + */ +exports.loadTasks = (req, res) => { + if (req.query.full = 'true') { + tasks.selectJoinedByTasklistId(req.token.tasklist).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); + } else { + tasks.selectByTasklistId(req.token.tasklist).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); + } +}; + +/** + * @description Process task + * @param {Object} req + * @param {Object} res + * @param {FUnction} next + */ +exports.craftTask = (req, res, next) => { + if (req.body.due) { // Skips when req.body.due === null or undefined + // Shift the time by timezone offset since the ISO string is in UTC + req.body.due = new Date(req.body.due); + } + + next(); +} + +/** + * @description Create task + * @param {Object} req + * @param {Object} res + */ +exports.createTask = (req, res) => { + tasks.create(req.body).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); +} + +/** + * @description Edit a task by its id + * @param {Object} req + * @param {Object} res + */ +exports.editTask = (req, res) => { + tasks.update(Number(req.query.id), req.body).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); +} + +/** + * @description Delete a task by its id + * @param {Object} req + * @param {Object} res + */ +exports.deleteTask = (req, res) => { + tasks.delete(Number(req.query.id)).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); +} + +/** + * @description Load labels + * @param {String} type subjects or categories + * @returns {Function} express middleware + */ +exports.loadLabel = type => { + const target = type === 'subjects' ? subjects : categories; + return (req, res) => { + target.selectByTasklistId(req.token.tasklist).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); + }; +}; + +/** + * @description Create a label + * @param {String} type subjects or categories + * @returns {Function} express middleware + */ +exports.createLabel = type => { + return (req, res) => { + const target = type === 'subjects' ? subjects : categories; + target.create(req.body).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); + }; +}; + +/** + * @description Update a label + * @param {String} type subjects or categories + * @returns {Function} express middleware + */ +exports.updateLabel = type => { + return (req, res) => { + const target = type === 'subjects' ? subjects : categories; + target.update(req.query.id, req.body).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); + }; +}; + +/** + * @description Delete a label + * @param {String} type subjects or categories + * @returns {Function} express middleware + */ +exports.deleteLabel = type => { + return (req, res) => { + const target = type === 'subjects' ? subjects : categories; + target.delete(req.query.id).then(results => { + res.json(results); + }).catch(err => { + console.error(err); + res.status(500).send('There was an error while accessing the database. ' + err); + }); + }; +}; \ No newline at end of file diff --git a/models/labels.js b/models/labels.js new file mode 100644 index 0000000..855a9ad --- /dev/null +++ b/models/labels.js @@ -0,0 +1,78 @@ +/** + * @fileoverview Interact with the subjects and the categories table in the database. + * @author SardonyxApp + * @license MIT + */ + +const db = require('../db'); + +class Labels { + /** + * @param {String} target Name of the table + */ + constructor(target) { + this.target = target; + } + + /** + * @description Select all labels by tasklist id + * @param {Number} tasklistId + * @returns {Promise} + */ + selectByTasklistId(tasklistId) { + return new Promise((resolve, reject) => { + db.get().query("SELECT * FROM ?? WHERE tasklist_id = ?", [this.target, tasklistId], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); + } + + /** + * @decription Create a new task + * @param {Object} task + * @returns {Promise} + */ + create(task) { + return new Promise((resolve, reject) => { + db.get().query("INSERT INTO ?? SET ?", [this.target, task], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); + } + + /** + * @description Update a task + * @param {Number} id + * @param {Object} task + * @returns {Promise} + */ + update(id, task) { + return new Promise((resolve, reject) => { + db.get().query("UPDATE ?? SET ? WHERE id = ?", [this.target, task, id], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); + } + + /** + * @description Delete a task + * @param {Number} id + * @returns {Promise} + */ + delete(id) { + return new Promise((resolve, reject) => { + db.get().query("DELETE FROM ?? WHERE id = ?", [this.target, id], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); + } +} + +const subjects = new Labels('subjects'); +const categories = new Labels('categories'); + +module.exports = { subjects, categories }; \ No newline at end of file diff --git a/models/tasklists.js b/models/tasklists.js new file mode 100644 index 0000000..5d7f14d --- /dev/null +++ b/models/tasklists.js @@ -0,0 +1,34 @@ +/** + * @fileoverview Interacts with the tasklists table of the database. + * @author SardonyxApp + * @license MIT + */ + +const db = require('../db'); + +/** + * @description Select tasklist by id + * @param {Number} id + * @returns {Promise} + */ +exports.select = id => { + return new Promise((resolve, reject) => { + db.get().query("SELECT * FROM tasklists WHERE id = ?", id, (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +}; + +/** + * @description Select all tasklists + * @returns {Promise} + */ +exports.selectAll = () => { + return new Promise((resolve, reject) => { + db.get().query("SELECT * FROM tasklists", (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +} \ No newline at end of file diff --git a/models/tasks.js b/models/tasks.js new file mode 100644 index 0000000..fe5f0f9 --- /dev/null +++ b/models/tasks.js @@ -0,0 +1,78 @@ +/** + * @fileoverview Interact with the tasks table in the database. + * @author SardonyxApp + * @license MIT + */ + +const db = require('../db'); + +/** + * @description Select all tasks by tasklist id + * @param {Number} tasklistId + * @returns {Promise} + */ +exports.selectByTasklistId = tasklistId => { + return new Promise((resolve, reject) => { + db.get().query("SELECT * FROM tasks WHERE tasklist_id = ?", tasklistId, (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +}; + +/** + * @description Select all tasks joined by relevant foreign tables by tasklist id + * @param {Number} tasklistId + * @returns {Promise} + */ +exports.selectJoinedByTasklistId = tasklistId => { + return new Promise((resolve, reject) => { + db.get().query("SELECT tasks.id, tasks.name, tasks.description, tasks.due, tasks.tasklist_id, tasks.subject_id, subjects.name AS subject_name, subjects.color AS subject_color, tasks.category_id, categories.name AS category_name, categories.color AS category_color, tasks.student_id, students.name AS student_name, tasks.teacher_id, teachers.name AS teacher_name FROM tasks LEFT JOIN subjects ON subject_id LEFT JOIN categories ON category_id LEFT JOIN students ON student_id LEFT JOIN teachers ON teacher_id WHERE (tasks.subject_id = subjects.id OR tasks.subject_id IS NULL) AND (tasks.category_id = categories.id OR tasks.category_id IS NULL) AND (tasks.student_id = students.id OR tasks.student_id IS NULL) AND (tasks.teacher_id = teachers.id OR tasks.teacher_id IS NULL) AND tasks.tasklist_id = ? ORDER BY due ASC;", tasklistId, (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +}; + +/** + * @description Create a new task + * @param {Object} task + * @returns {Promise} + */ +exports.create = task => { + return new Promise((resolve, reject) => { + db.get().query("INSERT INTO tasks SET ?", task, (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +} + +/** + * @description Edit a task by id + * @param {Number} id + * @param {Object} task + * @returns {Promise} + */ +exports.update = (id, task) => { + return new Promise((resolve, reject) => { + db.get().query("UPDATE tasks SET ? WHERE id = ?", [task, id], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +} + +/** + * @description Delete a task by id + * @param {Number} id + * @returns {Promise} + */ +exports.delete = id => { + return new Promise((resolve, reject) => { + db.get().query("DELETE FROM tasks WHERE id = ?", id, (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +} \ No newline at end of file diff --git a/models/users.js b/models/users.js new file mode 100644 index 0000000..e4f2b23 --- /dev/null +++ b/models/users.js @@ -0,0 +1,136 @@ +/** + * @fileoverview Interact with the students and teachers table of the database. + * @author SardonyxApp + * @license MIT + */ + + const db = require('../db'); + const { hashPassword } = require('../helpers/helpers'); + +class User { + /** + * @param {String} type students or teachers + */ + constructor(type) { + this.target = type; + this.idName = type === 'students' ? 'student_id' : 'teacher_id'; + } + + /** + * @description Select a user by email + * @param {String} email + * @returns {Promise} results + */ + selectByEmail(email) { + return new Promise((resolve, reject) => { + db.get().query("SELECT * FROM ?? WHERE email = ?", [this.target, email], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); + } + + /** + * @description Retrieve default labels for user + * @param {Number} id + * @param {Number} tasklist_id + * @returns {Promise} results + */ + selectLabels(id, tasklist_id) { + return new Promise((resolve, reject) => { + db.get().query("SELECT subject_id, category_id FROM user_labels LEFT JOIN subjects ON user_labels.subject_id = subjects.id LEFT JOIN categories ON user_labels.category_id = categories.id WHERE ?? = ? AND (subjects.tasklist_id = ? OR categories.tasklist_id = ?)", [this.idName, id, tasklist_id, tasklist_id], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); + } + + /** + * @description Add a default label for user + * @param {Number} id user + * @param {Number} label_id + * @param {Number} type subjects or categories + * @returns {Promise} results + */ + addLabel(id, label_id, type) { + return new Promise((resolve, reject) => { + const obj = {}; + obj[this.idName] = id; + const labelName = type === 'subjects' ? 'subject_id' : 'category_id'; + obj[labelName] = label_id; + + db.get().query("INSERT INTO user_labels SET ?", obj, (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); + } + + /** + * @description Delete a default label for user + * @param {Number} id user + * @param {Number} label_id + * @param {Number} type subjects or categories + * @returns {Promise} results + */ + deleteLabel(id, label_id, type) { + return new Promise((resolve, reject) => { + const labelName = type === 'subjects' ? 'subject_id' : 'category_id'; + db.get().query("DELETE FROM user_labels WHERE ?? = ? AND ?? = ?", [this.idName, id, labelName, label_id], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); + } +} + +const students = new User('students'); +const teachers = new User('teachers'); + +/** + * @description Create a student + * @param {Array} params + * name, email, year, tasklist_id are required + * @returns {Promise} results + */ +students.create = params => { + return new Promise((resolve, reject) => { + db.get().query("INSERT INTO students (name, email, year, tasklist_id) VALUES (?, ?, ?, ?)", params, (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +}; + +/** + * @description Update a teacher's password + * @param {String} email + * @param {String} password + * @returns {Promise} results + */ +teachers.updatePassword = (email, password) => { + return new Promise((resolve, reject) => { + const obj = hashPassword(password); + db.get().query("UPDATE teachers SET ? WHERE email = ?", [obj, email], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +}; + +/** + * @description Update a teacher's default tasklist + * @param {Number} id + * @param {Number} tasklist_id + * @returns {Promise} results + */ +teachers.updateTasklist = (id, tasklistId) => { + return new Promise((resolve, reject) => { + db.get().query("UPDATE teachers SET tasklist_id = ? WHERE id = ?", [tasklistId, id], (err, results) => { + if (err) reject(err); + resolve(results); + }); + }); +}; + +module.exports = { students, teachers }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a4c9347..101e0e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -779,6 +779,21 @@ "@babel/plugin-transform-react-jsx-source": "^7.0.0" } }, + "@babel/runtime": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.2.tgz", + "integrity": "sha512-7Bl2rALb7HpvXFL7TETNzKSAeBVCPHELzc0C//9FCxN8nsiueWSJBqaF+2oIJScyILStASR/Cx5WMkXGYTiJFA==", + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + } + } + }, "@babel/template": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.1.2.tgz", @@ -853,6 +868,11 @@ } } }, + "@icons/material": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", + "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==" + }, "@jest/console": { "version": "24.3.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.3.0.tgz", @@ -1419,24 +1439,12 @@ "string-width": "^2.0.0" } }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true - }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -1552,7 +1560,7 @@ }, "array-equal": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, @@ -1567,21 +1575,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -1594,6 +1587,11 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -1656,12 +1654,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async": { - "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, "async-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", @@ -1933,12 +1925,6 @@ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", "dev": true }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -1953,6 +1939,11 @@ "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", "dev": true }, + "bignumber.js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz", + "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==" + }, "binary-extensions": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", @@ -1997,28 +1988,6 @@ "type-is": "~1.6.16" } }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - }, - "dependencies": { - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - } - } - }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -2225,17 +2194,16 @@ } } }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -2517,6 +2485,11 @@ } } }, + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + }, "clean-css": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", @@ -2645,30 +2618,6 @@ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", "dev": true }, - "compressible": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", - "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", - "dev": true, - "requires": { - "mime-db": ">= 1.36.0 < 2" - } - }, - "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.14", - "debug": "2.6.9", - "on-headers": "~1.0.1", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - } - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2763,12 +2712,6 @@ "xdg-basedir": "^3.0.0" } }, - "connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", - "dev": true - }, "console-browserify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", @@ -2814,6 +2757,15 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, + "cookie-parser": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.4.tgz", + "integrity": "sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw==", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6" + } + }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -2901,6 +2853,15 @@ "sha.js": "^2.4.8" } }, + "create-react-context": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz", + "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==", + "requires": { + "fbjs": "^0.8.0", + "gud": "^1.0.0" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -3119,12 +3080,6 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -3137,16 +3092,6 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "default-gateway": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-2.7.2.tgz", - "integrity": "sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ==", - "dev": true, - "requires": { - "execa": "^0.10.0", - "ip-regex": "^2.1.0" - } - }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", @@ -3214,20 +3159,6 @@ } } }, - "del": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", - "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", - "dev": true, - "requires": { - "globby": "^6.1.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "p-map": "^1.1.1", - "pify": "^3.0.0", - "rimraf": "^2.2.8" - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3265,12 +3196,6 @@ "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", "dev": true }, - "detect-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", - "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", - "dev": true - }, "dicer": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", @@ -3297,31 +3222,6 @@ "randombytes": "^2.0.0" } }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", - "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, "dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -3458,6 +3358,14 @@ "safer-buffer": "^2.1.0" } }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -3495,6 +3403,14 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -3643,27 +3559,12 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, - "eventemitter3": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", - "dev": true - }, "events": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", "dev": true }, - "eventsource": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", - "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", - "dev": true, - "requires": { - "original": "^1.0.0" - } - }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -3905,15 +3806,6 @@ "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", "dev": true }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, "fb-watchman": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", @@ -3923,6 +3815,27 @@ "bser": "^2.0.0" } }, + "fbjs": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", + "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", + "requires": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + } + } + }, "file-loader": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-2.0.0.tgz", @@ -4041,26 +3954,6 @@ } } }, - "follow-redirects": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", - "integrity": "sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -4217,14 +4110,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4244,8 +4135,7 @@ "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", @@ -4393,7 +4283,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4860,27 +4749,6 @@ "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==", "dev": true }, - "globby": { - "version": "6.1.0", - "resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, "globule": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz", @@ -4923,11 +4791,10 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "dev": true }, - "handle-thing": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", - "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==", - "dev": true + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" }, "handlebars": { "version": "4.1.0", @@ -5083,50 +4950,6 @@ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", "dev": true }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -5136,12 +4959,6 @@ "whatwg-encoding": "^1.0.1" } }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true - }, "html-minifier": { "version": "3.5.21", "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", @@ -5227,12 +5044,6 @@ } } }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, "http-errors": { "version": "1.6.3", "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -5244,35 +5055,6 @@ "statuses": ">= 1.4.0 < 2" } }, - "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", - "dev": true - }, - "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", - "dev": true, - "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "0.18.0", - "resolved": "http://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", - "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", - "dev": true, - "requires": { - "http-proxy": "^1.16.2", - "is-glob": "^4.0.0", - "lodash": "^4.17.5", - "micromatch": "^3.1.9" - } - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -5448,16 +5230,6 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, - "internal-ip": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-3.0.1.tgz", - "integrity": "sha512-NXXgESC2nNVtU+pqmC9e6R8B1GpKxzsAQhffvh5AL79qKnodd+L7tnEQmTiUAVngqLalPbSqRA7XGIEL5nCd0Q==", - "dev": true, - "requires": { - "default-gateway": "^2.6.0", - "ipaddr.js": "^1.5.2" - } - }, "interpret": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", @@ -5479,18 +5251,6 @@ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, "ipaddr.js": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", @@ -5689,21 +5449,6 @@ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, "is-path-inside": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", @@ -5796,6 +5541,15 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + } + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -6451,9 +6205,9 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.12.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", - "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz", + "integrity": "sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -6534,12 +6288,6 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, "json5": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", @@ -6557,8 +6305,32 @@ } } }, - "jsprim": { - "version": "1.4.1", + "jsonwebtoken": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz", + "integrity": "sha512-IqEycp0znWHNA11TpYi77bVgyBO/pGESDh7Ajhas+u0ttkGkKYIIAjniL4Bw5+oVejVF+SYkaI7XKfwCCyeTuA==", + "requires": { + "jws": "^3.2.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "jsprim": { + "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "requires": { @@ -6568,11 +6340,24 @@ "verror": "1.10.0" } }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true + "jwa": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.0.tgz", + "integrity": "sha512-mt6IHaq0ZZWDBspg0Pheu3r9sVNMEZn+GJe1zcdYyhFcDSclp3J8xEdO4PjZolZ2i8xlaVU1LetHM0nJejYsEw==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.1.tgz", + "integrity": "sha512-bGA2omSrFUkd72dhh05bIAN832znP4wOU3lfuXtRBuGTbsmNmDXMQg28f0Vsxaxgk4myF5YkKQpz6qeRpMgX9g==", + "requires": { + "jwa": "^1.2.0", + "safe-buffer": "^5.0.1" + } }, "kind-of": { "version": "6.0.2", @@ -6713,12 +6498,47 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, "lodash.mergewith": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", "dev": true }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -6731,12 +6551,6 @@ "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", "dev": true }, - "loglevel": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", - "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", - "dev": true - }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6824,6 +6638,11 @@ "object-visit": "^1.0.0" } }, + "material-colors": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", + "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==" + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -6941,7 +6760,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -7149,22 +6968,46 @@ "xtend": "^4.0.0" } }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, + "mysql": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.16.0.tgz", + "integrity": "sha512-dPbN2LHonQp7D5ja5DJXNbCLe/HRdu+f3v61aguzNRQIrmZLOeRoymBYyeThrR6ug+FqzDL95Gc9maqZUJS+Gw==", "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" + "bignumber.js": "4.1.0", + "readable-stream": "2.3.6", + "safe-buffer": "5.1.2", + "sqlstring": "2.3.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, "nan": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", @@ -7222,11 +7065,14 @@ "lower-case": "^1.1.1" } }, - "node-forge": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", - "dev": true + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } }, "node-gyp": { "version": "3.8.0", @@ -7611,12 +7457,6 @@ "isobject": "^3.0.1" } }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -7625,12 +7465,6 @@ "ee-first": "1.1.1" } }, - "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", - "dev": true - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -7640,15 +7474,6 @@ "wrappy": "1" } }, - "opn": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", - "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -7681,15 +7506,6 @@ } } }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", @@ -7771,12 +7587,6 @@ "p-limit": "^1.1.0" } }, - "p-map": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", - "dev": true - }, "p-reduce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", @@ -8027,16 +7837,10 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, - "portfinder": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", - "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", - "dev": true, - "requires": { - "async": "^1.5.2", - "debug": "^2.2.0", - "mkdirp": "0.5.x" - } + "popper.js": { + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.7.tgz", + "integrity": "sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ==" }, "posix-character-classes": { "version": "0.1.1", @@ -8167,6 +7971,14 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -8280,12 +8092,6 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, - "querystringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz", - "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==", - "dev": true - }, "randombytes": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", @@ -8352,6 +8158,38 @@ "scheduler": "^0.11.2" } }, + "react-color": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.0.tgz", + "integrity": "sha512-kJfE5tSaFe6GzalXOHksVjqwCPAsTl+nzS9/BWfP7j3EXbQ4IiLAF9sZGNzk3uq7HfofGYgjmcUgh0JP7xAQ0w==", + "requires": { + "@icons/material": "^0.2.4", + "lodash": ">4.17.4", + "material-colors": "^1.2.1", + "prop-types": "^15.5.10", + "reactcss": "^1.2.0", + "tinycolor2": "^1.4.1" + } + }, + "react-datepicker": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-2.2.0.tgz", + "integrity": "sha512-JXXyytODTQojN2i2rbS/1MWnQkSlXiSDzOiGbQCC/vVuyo/1yPgj+2UP+wHXYjKobPirWMG3zfxZdZa4y2wTKg==", + "requires": { + "classnames": "^2.2.5", + "date-fns": "^2.0.0-alpha.23", + "prop-types": "^15.6.0", + "react-onclickoutside": "^6.7.1", + "react-popper": "^1.0.2" + }, + "dependencies": { + "date-fns": { + "version": "2.0.0-alpha.27", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.0.0-alpha.27.tgz", + "integrity": "sha512-cqfVLS+346P/Mpj2RpDrBv0P4p2zZhWWvfY5fuWrXNR/K38HaAGEkeOwb47hIpQP9Jr/TIxjZ2/sNMQwdXuGMg==" + } + } + }, "react-dom": { "version": "16.6.3", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.6.3.tgz", @@ -8369,6 +8207,32 @@ "integrity": "sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==", "dev": true }, + "react-onclickoutside": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.8.0.tgz", + "integrity": "sha512-5Q4Rn7QLEoh7WIe66KFvYIpWJ49GeHoygP1/EtJyZjXKgrWH19Tf0Ty3lWyQzrEEDyLOwUvvmBFSE3dcDdvagA==" + }, + "react-popper": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.3.tgz", + "integrity": "sha512-ynMZBPkXONPc5K4P5yFWgZx5JGAUIP3pGGLNs58cfAPgK67olx7fmLp+AdpZ0+GoQ+ieFDa/z4cdV6u7sioH6w==", + "requires": { + "@babel/runtime": "^7.1.2", + "create-react-context": "<=0.2.2", + "popper.js": "^1.14.4", + "prop-types": "^15.6.1", + "typed-styles": "^0.0.7", + "warning": "^4.0.2" + } + }, + "reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", + "requires": { + "lodash": "^4.0.1" + } + }, "read-pkg": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", @@ -8694,12 +8558,6 @@ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -8841,7 +8699,7 @@ }, "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, @@ -9035,26 +8893,10 @@ } } }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", - "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", - "dev": true, - "requires": { - "node-forge": "0.7.5" - } - }, "semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, "semver-diff": { "version": "2.1.0", @@ -9091,21 +8933,6 @@ "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==", "dev": true }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - } - }, "serve-static": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", @@ -9148,8 +8975,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { "version": "1.1.0", @@ -9430,56 +9256,6 @@ } } }, - "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.0.1" - } - }, - "sockjs-client": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", - "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", - "dev": true, - "requires": { - "debug": "^3.2.5", - "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "faye-websocket": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", - "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, "source-list-map": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", @@ -9567,87 +9343,6 @@ "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==", "dev": true }, - "spdy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", - "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "readable-stream": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", - "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -9663,6 +9358,11 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "sqlstring": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", + "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" + }, "sshpk": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", @@ -10275,12 +9975,6 @@ } } }, - "thunky": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", - "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", - "dev": true - }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -10296,6 +9990,11 @@ "setimmediate": "^1.0.4" } }, + "tinycolor2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", + "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -10466,11 +10165,21 @@ "mime-types": "~2.1.18" } }, + "typed-styles": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", + "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, + "ua-parser-js": { + "version": "0.7.19", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", + "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==" + }, "uglify-js": { "version": "3.4.9", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", @@ -10757,16 +10466,6 @@ } } }, - "url-parse": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", - "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", - "dev": true, - "requires": { - "querystringify": "^2.0.0", - "requires-port": "^1.0.0" - } - }, "url-parse-lax": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", @@ -10880,6 +10579,14 @@ "makeerror": "1.0.x" } }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", @@ -10891,15 +10598,6 @@ "neo-async": "^2.5.0" } }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", @@ -10968,178 +10666,6 @@ "yargs": "^12.0.2" } }, - "webpack-dev-middleware": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz", - "integrity": "sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==", - "dev": true, - "requires": { - "memory-fs": "~0.4.1", - "mime": "^2.3.1", - "range-parser": "^1.0.3", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", - "dev": true - } - } - }, - "webpack-dev-server": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.14.tgz", - "integrity": "sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.0.0", - "compression": "^1.5.2", - "connect-history-api-fallback": "^1.3.0", - "debug": "^3.1.0", - "del": "^3.0.0", - "express": "^4.16.2", - "html-entities": "^1.2.0", - "http-proxy-middleware": "~0.18.0", - "import-local": "^2.0.0", - "internal-ip": "^3.0.1", - "ip": "^1.1.5", - "killable": "^1.0.0", - "loglevel": "^1.4.1", - "opn": "^5.1.0", - "portfinder": "^1.0.9", - "schema-utils": "^1.0.0", - "selfsigned": "^1.9.1", - "semver": "^5.6.0", - "serve-index": "^1.7.2", - "sockjs": "0.3.19", - "sockjs-client": "1.3.0", - "spdy": "^4.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^5.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "3.4.0", - "webpack-log": "^2.0.0", - "yargs": "12.0.2" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", - "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", - "dev": true, - "requires": { - "xregexp": "4.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, - "yargs": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", - "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^2.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^10.1.0" - } - }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - } - }, "webpack-sources": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", @@ -11158,22 +10684,6 @@ } } }, - "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", - "dev": true, - "requires": { - "http-parser-js": ">=0.4.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", - "dev": true - }, "whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -11194,6 +10704,11 @@ } } }, + "whatwg-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", + "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + }, "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", @@ -11324,12 +10839,6 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, - "xregexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", - "dev": true - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index be61cfe..3fb61bc 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Backend server for Sardonyx.", "main": "server.js", "scripts": { - "client-dev": "webpack-dev-server --mode development", + "client-dev": "webpack --watch", "client": "webpack --mode production", "server-dev": "nodemon server", "start": "node server", @@ -21,13 +21,19 @@ "dependencies": { "@babel/polyfill": "^7.0.0", "cheerio": "^1.0.0-rc.2", + "cookie-parser": "^1.4.4", "dotenv": "^6.1.0", "express": "^4.16.3", + "jsonwebtoken": "^8.5.0", "multer": "^1.4.1", + "mysql": "^2.16.0", "react": "^16.6.3", + "react-color": "^2.17.0", + "react-datepicker": "^2.2.0", "react-dom": "^16.6.3", "request": "^2.88.0", - "showdown": "^1.9.0" + "showdown": "^1.9.0", + "whatwg-fetch": "^3.0.0" }, "devDependencies": { "@babel/core": "^7.1.6", @@ -47,7 +53,6 @@ "style-loader": "^0.23.1", "supertest": "^3.3.0", "webpack": "^4.25.1", - "webpack-cli": "^3.1.2", - "webpack-dev-server": "^3.1.14" + "webpack-cli": "^3.1.2" } } diff --git a/public/Icon.svg b/public/Icon.svg deleted file mode 100644 index 9bf594d..0000000 --- a/public/Icon.svg +++ /dev/null @@ -1 +0,0 @@ -Icon \ No newline at end of file diff --git a/public/about/index.html b/public/about/index.html new file mode 100644 index 0000000..564770d --- /dev/null +++ b/public/about/index.html @@ -0,0 +1,71 @@ + + + + + + + + + Sardonyx - About + + +
+ +
+

Sardonyx

+

ABOUT

+
+
+ +
+
+

About Sardonyx

+

Sardonyx is an online solution to transform how high school students and teachers use technology to manage workloads. Sardonyx offers a cross-platfrom experience for all its users, through its mobile and web platforms.

+

The web application offers a group tasklist accessible by both teachers and students. Students and teachers benefit from the transparency of the workload, organized by due dates, subjects, and task categories. Each task on the list can be given a detailed description.

+

The mobile application is planned to offer students and teachers a native experience in managing their online learning environment. This includes an intuitive interface for using Managebac on mobile phones and accessing the Sardonyx group tasklist.

+
+
+

CAS

+

Sardonyx is a CAS project, which is part of the International Baccalaureate Diploma Programme. This project is planned, designed, developed, tested, and operated by two high school students. Adhering to the principles of CAS, Sardonyx is provided completely free of charge. For more information about CAS projects, visit the International Baccalaureate Organization's website.

+
+
+

Browser compatibility

+

Recently, there has been rapid development of new web technologies that facilitate the development of sophisticated web applications like Sardonyx. However, modernization comes at a cost of dropping support for legacy web browsers, like Internet Explorer. Although Sardonyx would like to support browsers used by all users, this difficult task would require an unrealistic amount of time and effort. Like many web apps have done, Sardonyx has decided to support various browsers realistically. This means that there will be varied levels of support for different browsers.

+

The below list shows the current level of support for popular browsers. Sardonyx recommends users to use the newest version of Google Chrome or Mozilla Firefox for the most stable experience.

+ + +

Above information is as of April 2019.

+
+
+ + + + \ No newline at end of file diff --git a/public/app/ie.html b/public/app/ie.html new file mode 100644 index 0000000..5ab5629 --- /dev/null +++ b/public/app/ie.html @@ -0,0 +1,18 @@ + + + + + + + Sardonyx + + +
+ + + + \ No newline at end of file diff --git a/public/app/index.html b/public/app/index.html new file mode 100644 index 0000000..fd31f64 --- /dev/null +++ b/public/app/index.html @@ -0,0 +1,18 @@ + + + + + + + Sardonyx + + +
+ + + + \ No newline at end of file diff --git a/public/article.css b/public/article.css new file mode 100644 index 0000000..a57f958 --- /dev/null +++ b/public/article.css @@ -0,0 +1,51 @@ +html, body { + font-family: Jost; + margin: 0; +} + +#title, #content { + padding: 20px 40px; +} + +#content > div { + padding: 10px 0 10px 0; +} + +h1, h2, h3, h4, p, ul, li { + font-weight: 300; +} + +h1 { + color: #d17b46; +} + +a, a:visited { + text-decoration: none; + color: #d17b46; +} + +a:hover { + filter: brightness(1.25); +} + +#title > div { + display: inline-block; + vertical-align: middle; +} + +img.logo { + height: 150px; + width: 150px; + margin-right: 30px; + vertical-align: middle; +} + +@media only screen and (max-width: 600px) { + img.logo { + display: none; + } +} + +.version { + color: #d17b46; +} \ No newline at end of file diff --git a/public/assets/Icon.png b/public/assets/Icon.png new file mode 100644 index 0000000..9d7b927 Binary files /dev/null and b/public/assets/Icon.png differ diff --git a/public/assets/Icon.svg b/public/assets/Icon.svg new file mode 100644 index 0000000..dc7faef --- /dev/null +++ b/public/assets/Icon.svg @@ -0,0 +1 @@ +Icon \ No newline at end of file diff --git a/public/assets/Icon_bgwhite.svg b/public/assets/Icon_bgwhite.svg new file mode 100644 index 0000000..60d0803 --- /dev/null +++ b/public/assets/Icon_bgwhite.svg @@ -0,0 +1 @@ +Icon_bgwhite \ No newline at end of file diff --git a/public/assets/Icon_inverted.svg b/public/assets/Icon_inverted.svg new file mode 100644 index 0000000..df55c74 --- /dev/null +++ b/public/assets/Icon_inverted.svg @@ -0,0 +1 @@ +Icon \ No newline at end of file diff --git a/public/assets/screenshot-app.png b/public/assets/screenshot-app.png new file mode 100644 index 0000000..b91d83a Binary files /dev/null and b/public/assets/screenshot-app.png differ diff --git a/public/assets/screenshot-date.png b/public/assets/screenshot-date.png new file mode 100644 index 0000000..3b18e87 Binary files /dev/null and b/public/assets/screenshot-date.png differ diff --git a/public/assets/screenshot-detailed.png b/public/assets/screenshot-detailed.png new file mode 100644 index 0000000..5748bdd Binary files /dev/null and b/public/assets/screenshot-detailed.png differ diff --git a/public/assets/screenshot-lang.png b/public/assets/screenshot-lang.png new file mode 100644 index 0000000..00762e4 Binary files /dev/null and b/public/assets/screenshot-lang.png differ diff --git a/public/assets/screenshot-preferences.png b/public/assets/screenshot-preferences.png new file mode 100644 index 0000000..dca8c44 Binary files /dev/null and b/public/assets/screenshot-preferences.png differ diff --git a/public/changelog/index.html b/public/changelog/index.html new file mode 100644 index 0000000..3235b80 --- /dev/null +++ b/public/changelog/index.html @@ -0,0 +1,51 @@ + + + + + + + + + Sardonyx - Changelog + + +
+ +
+

Sardonyx Changelog

+

Last updated: March 29 2019

+
+
+ +
+
+

Latest version

+

v1.0.0-alpha.2

+

Released April 6 2019

+

Experimental features

+ +

Bugs

+ +

Security

+ +

Miscellaneous

+ + +

Legacy versions

+

v1.0.0-alpha.1

+

Released March 29 2019

+ +
+
+ \ No newline at end of file diff --git a/public/download/index.html b/public/download/index.html new file mode 100644 index 0000000..e0f8aeb --- /dev/null +++ b/public/download/index.html @@ -0,0 +1,58 @@ + + + + + + + + + Sardonyx - Download + + +
+ +
+

Sardonyx

+

DOWNLOAD

+
+
+ +
+
+

Mobile App

+

The Sardonyx mobile application is currently under development. This will be released soon.

+
+
+

Source Code

+

The source code for Sardonyx is available on GitHub. Although Sardonyx cannot guarantee stability and functionality, the applications can be built from the source code as well.

+ +
+
+ + + + \ No newline at end of file diff --git a/public/e088ad501518ad3fc355cfddc1c18cc6.svg b/public/e088ad501518ad3fc355cfddc1c18cc6.svg deleted file mode 100644 index 9bf594d..0000000 --- a/public/e088ad501518ad3fc355cfddc1c18cc6.svg +++ /dev/null @@ -1 +0,0 @@ -Icon \ No newline at end of file diff --git a/public/index.css b/public/index.css new file mode 100644 index 0000000..980479b --- /dev/null +++ b/public/index.css @@ -0,0 +1,169 @@ +/* general */ +body { + font-family: Jost, sans-serif; + margin: 0; + font-weight: 300; + background: #f8f8fa; +} + +h1, h2, h3, p, li { + font-weight: 300; + margin: 0; + color: #332927; +} + +h1, h2 { + color: #d17b46; +} + +a, a:visited { + text-decoration: none; + color: #d17b46; +} + +a:hover { + filter: brightness(1.25); +} + +button, button:active, button:focus { + outline: 0; + cursor: pointer; +} + +.action { + border: 2px solid white; + background: transparent; + border-radius: 4px; + color: white; + padding: 8px; +} + +.arrow { + display: none; +} + +.action:hover { + border: 2px solid #ddd; + color: #ddd; +} + +.action:hover span.arrow { + display: inline; +} + +.orange { + background: #d17b46; +} + +.orange h1, .orange h2, .orange p, .orange a, .orange a:visited { + color: white; +} + +.center { + text-align: center; +} + +.component { + padding: 32px 0; +} + +#title, #content { + padding: 20px 40px; +} + +#title > div { + display: inline-block; + vertical-align: middle; +} + +#title h1 { + font-size: 40px; +} + +img.logo { + height: 150px; + width: 150px; + margin-right: 30px; + vertical-align: middle; +} + +.nav > ul { + margin: 0; + padding: 0; +} + +.nav li { + padding: 0 8px; + display: inline-block; +} + +.columns { + display: flex; + align-items: center; +} + +@media only screen and (min-width: 600px) { + .block { + padding: 64px 0; + } + + .explanation, .graphic { + flex: auto; + } + + .explanation { + width: 38%; + } + + .graphic { + width: 60%; + } + + .graphic img { + width: 95%; + } +} + +@media only screen and (max-width: 600px) { + .block { + padding: 32px 0; + } + + .columns { + flex-wrap: wrap; + } + + .explanation, .graphic { + width: 100%; + } + + .explanation { + order: 0; + } + + .graphic { + order: 1; + padding: 12px 0; + } + + .graphic img { + width: 100%; + } +} + +.graphic { + text-align: center; +} + +#ready p { + padding: 8px 0; + margin: 0 24px; +} + +.nav { + padding: 24px; +} + +#copyright { + padding: 0 8px; +} \ No newline at end of file diff --git a/public/index.html b/public/index.html index b45b2cf..0e14bb1 100644 --- a/public/index.html +++ b/public/index.html @@ -4,9 +4,109 @@ + + Sardonyx - + + -
- +
+ +
+

Sardonyx

+ + +
+
+ +
+
+
+

Group tasklist specialized for students and teachers

+

Sardonyx is specifically target towards students and teachers, in order to assist workload management in school.

+

Sorted by dates, the workload is transparent for all users.

+
+
+ +
+
+
+
+ +
+
+

Seamlessly view information for each task

+

The detailed view allows students and teachers to share information about each task collaboratively.

+
+
+
+
+

The tasklist under your control

+

Settings can be adjusted to filter tasks by subjects and task categories by default, personalizing the experience.

+
+
+ +
+
+
+
+ +
+
+

Collaborate effectively

+

Sardonyx allows students and teachers to build a collaborative environment by allowing everyone to create, edit, and delete tasks as needed.

+

An intuitive user interface (UI) has been integrated to facilitate collaboration.

+
+
+
+
+

Non-English language support

+

Sardonyx tasks support input in almost any language, in order to meet the needs of an international community.

+
+
+ +
+
+
+

Sardonyx is free and open source

+

The source code is licensed under the MIT license, accessible for anyone wishing to review and contribute to our project.

+

Since Sardonyx is built as a CAS project, no charges will be incurred on the user.

+
+
+ +
+

Ready to start?

+

If you are using a computer or a tablet, our web application is accessible through a web browser.

+ +

If you are using a mobile phone, Sardonyx is currently developing a mobile application for both iOS and Android.

+ +
+ + + \ No newline at end of file diff --git a/public/index.js b/public/index.js deleted file mode 100644 index 7ebe765..0000000 --- a/public/index.js +++ /dev/null @@ -1,30 +0,0 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=113)}([function(e,t,n){var r=n(2),i=n(8),o=n(13),u=n(10),a=n(21),l=function(e,t,n){var c,f,s,p,d=e&l.F,h=e&l.G,v=e&l.S,y=e&l.P,m=e&l.B,g=h?r:v?r[t]||(r[t]={}):(r[t]||{}).prototype,b=h?i:i[t]||(i[t]={}),w=b.prototype||(b.prototype={});for(c in h&&(n=t),n)s=((f=!d&&g&&void 0!==g[c])?g:n)[c],p=m&&f?a(s,r):y&&"function"==typeof s?a(Function.call,s):s,g&&u(g,c,s,e&l.U),b[c]!=s&&o(b,c,p),y&&w[c]!=s&&(w[c]=s)};r.core=i,l.F=1,l.G=2,l.S=4,l.P=8,l.B=16,l.W=32,l.U=64,l.R=128,e.exports=l},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){var r=n(3);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){var r=n(58)("wks"),i=n(30),o=n(2).Symbol,u="function"==typeof o;(e.exports=function(e){return r[e]||(r[e]=u&&o[e]||(u?o:i)("Symbol."+e))}).store=r},function(e,t,n){var r=n(4),i=n(82),o=n(27),u=Object.defineProperty;t.f=n(7)?Object.defineProperty:function(e,t,n){if(r(e),t=o(t,!0),r(n),i)try{return u(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},function(e,t,n){e.exports=!n(1)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t){var n=e.exports={version:"2.5.7"};"number"==typeof __e&&(__e=n)},function(e,t,n){var r=n(25),i=Math.min;e.exports=function(e){return e>0?i(r(e),9007199254740991):0}},function(e,t,n){var r=n(2),i=n(13),o=n(12),u=n(30)("src"),a=Function.toString,l=(""+a).split("toString");n(8).inspectSource=function(e){return a.call(e)},(e.exports=function(e,t,n,a){var c="function"==typeof n;c&&(o(n,"name")||i(n,"name",t)),e[t]!==n&&(c&&(o(n,u)||i(n,u,e[t]?""+e[t]:l.join(String(t)))),e===r?e[t]=n:a?e[t]?e[t]=n:i(e,t,n):(delete e[t],i(e,t,n)))})(Function.prototype,"toString",function(){return"function"==typeof this&&this[u]||a.call(this)})},function(e,t,n){var r=n(0),i=n(1),o=n(24),u=/"/g,a=function(e,t,n,r){var i=String(o(e)),a="<"+t;return""!==n&&(a+=" "+n+'="'+String(r).replace(u,""")+'"'),a+">"+i+""};e.exports=function(e,t){var n={};n[e]=t(a),r(r.P+r.F*i(function(){var t=""[e]('"');return t!==t.toLowerCase()||t.split('"').length>3}),"String",n)}},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){var r=n(6),i=n(29);e.exports=n(7)?function(e,t,n){return r.f(e,t,i(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){var r=n(44),i=n(24);e.exports=function(e){return r(i(e))}},function(e,t,n){var r=n(24);e.exports=function(e){return Object(r(e))}},function(e,t,n){"use strict";var r=n(1);e.exports=function(e,t){return!!e&&r(function(){t?e.call(null,function(){},1):e.call(null)})}},function(e,t,n){var r=n(45),i=n(29),o=n(14),u=n(27),a=n(12),l=n(82),c=Object.getOwnPropertyDescriptor;t.f=n(7)?c:function(e,t){if(e=o(e),t=u(t,!0),l)try{return c(e,t)}catch(e){}if(a(e,t))return i(!r.f.call(e,t),e[t])}},function(e,t,n){var r=n(0),i=n(8),o=n(1);e.exports=function(e,t){var n=(i.Object||{})[e]||Object[e],u={};u[e]=t(n),r(r.S+r.F*o(function(){n(1)}),"Object",u)}},function(e,t,n){var r=n(21),i=n(44),o=n(15),u=n(9),a=n(208);e.exports=function(e,t){var n=1==e,l=2==e,c=3==e,f=4==e,s=6==e,p=5==e||s,d=t||a;return function(t,a,h){for(var v,y,m=o(t),g=i(m),b=r(a,h,3),w=u(g.length),x=0,S=n?d(t,w):l?d(t,0):void 0;w>x;x++)if((p||x in g)&&(y=b(v=g[x],x,m),e))if(n)S[x]=y;else if(y)switch(e){case 3:return!0;case 5:return v;case 6:return x;case 2:S.push(v)}else if(f)return!1;return s?-1:c||f?f:S}}},function(e,t,n){"use strict";e.exports=n(282)},function(e,t,n){var r=n(22);e.exports=function(e,t,n){if(r(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,r){return e.call(t,n,r)};case 3:return function(n,r,i){return e.call(t,n,r,i)}}return function(){return e.apply(t,arguments)}}},function(e,t){e.exports=function(e){if("function"!=typeof e)throw TypeError(e+" is not a function!");return e}},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t){var n=Math.ceil,r=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?r:n)(e)}},function(e,t,n){"use strict";if(n(7)){var r=n(31),i=n(2),o=n(1),u=n(0),a=n(56),l=n(81),c=n(21),f=n(41),s=n(29),p=n(13),d=n(42),h=n(25),v=n(9),y=n(107),m=n(33),g=n(27),b=n(12),w=n(48),x=n(3),S=n(15),_=n(74),k=n(34),E=n(36),T=n(35).f,C=n(76),P=n(30),O=n(5),N=n(19),F=n(46),M=n(53),I=n(78),A=n(38),j=n(50),L=n(40),R=n(77),U=n(99),D=n(6),z=n(17),W=D.f,V=z.f,B=i.RangeError,$=i.TypeError,H=i.Uint8Array,G=Array.prototype,K=l.ArrayBuffer,q=l.DataView,Y=N(0),Q=N(2),X=N(3),J=N(4),Z=N(5),ee=N(6),te=F(!0),ne=F(!1),re=I.values,ie=I.keys,oe=I.entries,ue=G.lastIndexOf,ae=G.reduce,le=G.reduceRight,ce=G.join,fe=G.sort,se=G.slice,pe=G.toString,de=G.toLocaleString,he=O("iterator"),ve=O("toStringTag"),ye=P("typed_constructor"),me=P("def_constructor"),ge=a.CONSTR,be=a.TYPED,we=a.VIEW,xe=N(1,function(e,t){return Te(M(e,e[me]),t)}),Se=o(function(){return 1===new H(new Uint16Array([1]).buffer)[0]}),_e=!!H&&!!H.prototype.set&&o(function(){new H(1).set({})}),ke=function(e,t){var n=h(e);if(n<0||n%t)throw B("Wrong offset!");return n},Ee=function(e){if(x(e)&&be in e)return e;throw $(e+" is not a typed array!")},Te=function(e,t){if(!(x(e)&&ye in e))throw $("It is not a typed array constructor!");return new e(t)},Ce=function(e,t){return Pe(M(e,e[me]),t)},Pe=function(e,t){for(var n=0,r=t.length,i=Te(e,r);r>n;)i[n]=t[n++];return i},Oe=function(e,t,n){W(e,t,{get:function(){return this._d[n]}})},Ne=function(e){var t,n,r,i,o,u,a=S(e),l=arguments.length,f=l>1?arguments[1]:void 0,s=void 0!==f,p=C(a);if(void 0!=p&&!_(p)){for(u=p.call(a),r=[],t=0;!(o=u.next()).done;t++)r.push(o.value);a=r}for(s&&l>2&&(f=c(f,arguments[2],2)),t=0,n=v(a.length),i=Te(this,n);n>t;t++)i[t]=s?f(a[t],t):a[t];return i},Fe=function(){for(var e=0,t=arguments.length,n=Te(this,t);t>e;)n[e]=arguments[e++];return n},Me=!!H&&o(function(){de.call(new H(1))}),Ie=function(){return de.apply(Me?se.call(Ee(this)):Ee(this),arguments)},Ae={copyWithin:function(e,t){return U.call(Ee(this),e,t,arguments.length>2?arguments[2]:void 0)},every:function(e){return J(Ee(this),e,arguments.length>1?arguments[1]:void 0)},fill:function(e){return R.apply(Ee(this),arguments)},filter:function(e){return Ce(this,Q(Ee(this),e,arguments.length>1?arguments[1]:void 0))},find:function(e){return Z(Ee(this),e,arguments.length>1?arguments[1]:void 0)},findIndex:function(e){return ee(Ee(this),e,arguments.length>1?arguments[1]:void 0)},forEach:function(e){Y(Ee(this),e,arguments.length>1?arguments[1]:void 0)},indexOf:function(e){return ne(Ee(this),e,arguments.length>1?arguments[1]:void 0)},includes:function(e){return te(Ee(this),e,arguments.length>1?arguments[1]:void 0)},join:function(e){return ce.apply(Ee(this),arguments)},lastIndexOf:function(e){return ue.apply(Ee(this),arguments)},map:function(e){return xe(Ee(this),e,arguments.length>1?arguments[1]:void 0)},reduce:function(e){return ae.apply(Ee(this),arguments)},reduceRight:function(e){return le.apply(Ee(this),arguments)},reverse:function(){for(var e,t=Ee(this).length,n=Math.floor(t/2),r=0;r1?arguments[1]:void 0)},sort:function(e){return fe.call(Ee(this),e)},subarray:function(e,t){var n=Ee(this),r=n.length,i=m(e,r);return new(M(n,n[me]))(n.buffer,n.byteOffset+i*n.BYTES_PER_ELEMENT,v((void 0===t?r:m(t,r))-i))}},je=function(e,t){return Ce(this,se.call(Ee(this),e,t))},Le=function(e){Ee(this);var t=ke(arguments[1],1),n=this.length,r=S(e),i=v(r.length),o=0;if(i+t>n)throw B("Wrong length!");for(;o255?255:255&r),i.v[d](n*t+i.o,r,Se)}(this,n,e)},enumerable:!0})};b?(h=n(function(e,n,r,i){f(e,h,c,"_d");var o,u,a,l,s=0,d=0;if(x(n)){if(!(n instanceof K||"ArrayBuffer"==(l=w(n))||"SharedArrayBuffer"==l))return be in n?Pe(h,n):Ne.call(h,n);o=n,d=ke(r,t);var m=n.byteLength;if(void 0===i){if(m%t)throw B("Wrong length!");if((u=m-d)<0)throw B("Wrong length!")}else if((u=v(i)*t)+d>m)throw B("Wrong length!");a=u/t}else a=y(n),o=new K(u=a*t);for(p(e,"_d",{b:o,o:d,l:u,e:a,v:new q(o)});sdocument.F=Object<\/script>"),e.close(),l=e.F;r--;)delete l.prototype[o[r]];return l()};e.exports=Object.create||function(e,t){var n;return null!==e?(a.prototype=r(e),n=new a,a.prototype=null,n[u]=e):n=l(),void 0===t?n:i(n,t)}},function(e,t,n){var r=n(84),i=n(61).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return r(e,i)}},function(e,t,n){var r=n(12),i=n(15),o=n(60)("IE_PROTO"),u=Object.prototype;e.exports=Object.getPrototypeOf||function(e){return e=i(e),r(e,o)?e[o]:"function"==typeof e.constructor&&e instanceof e.constructor?e.constructor.prototype:e instanceof Object?u:null}},function(e,t,n){var r=n(6).f,i=n(12),o=n(5)("toStringTag");e.exports=function(e,t,n){e&&!i(e=n?e:e.prototype,o)&&r(e,o,{configurable:!0,value:t})}},function(e,t){e.exports={}},function(e,t,n){var r=n(5)("unscopables"),i=Array.prototype;void 0==i[r]&&n(13)(i,r,{}),e.exports=function(e){i[r][e]=!0}},function(e,t,n){"use strict";var r=n(2),i=n(6),o=n(7),u=n(5)("species");e.exports=function(e){var t=r[e];o&&t&&!t[u]&&i.f(t,u,{configurable:!0,get:function(){return this}})}},function(e,t){e.exports=function(e,t,n,r){if(!(e instanceof t)||void 0!==r&&r in e)throw TypeError(n+": incorrect invocation!");return e}},function(e,t,n){var r=n(10);e.exports=function(e,t,n){for(var i in t)r(e,i,t[i],n);return e}},function(e,t,n){var r=n(3);e.exports=function(e,t){if(!r(e)||e._t!==t)throw TypeError("Incompatible receiver, "+t+" required!");return e}},function(e,t,n){var r=n(23);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==r(e)?e.split(""):Object(e)}},function(e,t){t.f={}.propertyIsEnumerable},function(e,t,n){var r=n(14),i=n(9),o=n(33);e.exports=function(e){return function(t,n,u){var a,l=r(t),c=i(l.length),f=o(u,c);if(e&&n!=n){for(;c>f;)if((a=l[f++])!=a)return!0}else for(;c>f;f++)if((e||f in l)&&l[f]===n)return e||f||0;return!e&&-1}}},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t,n){var r=n(23),i=n(5)("toStringTag"),o="Arguments"==r(function(){return arguments}());e.exports=function(e){var t,n,u;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(e){}}(t=Object(e),i))?n:o?r(t):"Object"==(u=r(t))&&"function"==typeof t.callee?"Arguments":u}},function(e,t,n){var r=n(0),i=n(24),o=n(1),u=n(65),a="["+u+"]",l=RegExp("^"+a+a+"*"),c=RegExp(a+a+"*$"),f=function(e,t,n){var i={},a=o(function(){return!!u[e]()||"​…"!="​…"[e]()}),l=i[e]=a?t(s):u[e];n&&(i[n]=l),r(r.P+r.F*a,"String",i)},s=f.trim=function(e,t){return e=String(i(e)),1&t&&(e=e.replace(l,"")),2&t&&(e=e.replace(c,"")),e};e.exports=f},function(e,t,n){var r=n(5)("iterator"),i=!1;try{var o=[7][r]();o.return=function(){i=!0},Array.from(o,function(){throw 2})}catch(e){}e.exports=function(e,t){if(!t&&!i)return!1;var n=!1;try{var o=[7],u=o[r]();u.next=function(){return{done:n=!0}},o[r]=function(){return u},e(o)}catch(e){}return n}},function(e,t,n){"use strict";var r=n(13),i=n(10),o=n(1),u=n(24),a=n(5);e.exports=function(e,t,n){var l=a(e),c=n(u,l,""[e]),f=c[0],s=c[1];o(function(){var t={};return t[l]=function(){return 7},7!=""[e](t)})&&(i(String.prototype,e,f),r(RegExp.prototype,l,2==t?function(e,t){return s.call(e,this,t)}:function(e){return s.call(e,this)}))}},function(e,t,n){var r=n(21),i=n(97),o=n(74),u=n(4),a=n(9),l=n(76),c={},f={};(t=e.exports=function(e,t,n,s,p){var d,h,v,y,m=p?function(){return e}:l(e),g=r(n,s,t?2:1),b=0;if("function"!=typeof m)throw TypeError(e+" is not iterable!");if(o(m)){for(d=a(e.length);d>b;b++)if((y=t?g(u(h=e[b])[0],h[1]):g(e[b]))===c||y===f)return y}else for(v=m.call(e);!(h=v.next()).done;)if((y=i(v,g,h.value,t))===c||y===f)return y}).BREAK=c,t.RETURN=f},function(e,t,n){var r=n(4),i=n(22),o=n(5)("species");e.exports=function(e,t){var n,u=r(e).constructor;return void 0===u||void 0==(n=r(u)[o])?t:i(n)}},function(e,t,n){var r=n(2).navigator;e.exports=r&&r.userAgent||""},function(e,t,n){"use strict";var r=n(2),i=n(0),o=n(10),u=n(42),a=n(28),l=n(52),c=n(41),f=n(3),s=n(1),p=n(50),d=n(37),h=n(66);e.exports=function(e,t,n,v,y,m){var g=r[e],b=g,w=y?"set":"add",x=b&&b.prototype,S={},_=function(e){var t=x[e];o(x,e,"delete"==e?function(e){return!(m&&!f(e))&&t.call(this,0===e?0:e)}:"has"==e?function(e){return!(m&&!f(e))&&t.call(this,0===e?0:e)}:"get"==e?function(e){return m&&!f(e)?void 0:t.call(this,0===e?0:e)}:"add"==e?function(e){return t.call(this,0===e?0:e),this}:function(e,n){return t.call(this,0===e?0:e,n),this})};if("function"==typeof b&&(m||x.forEach&&!s(function(){(new b).entries().next()}))){var k=new b,E=k[w](m?{}:-0,1)!=k,T=s(function(){k.has(1)}),C=p(function(e){new b(e)}),P=!m&&s(function(){for(var e=new b,t=5;t--;)e[w](t,t);return!e.has(-0)});C||((b=t(function(t,n){c(t,b,e);var r=h(new g,t,b);return void 0!=n&&l(n,y,r[w],r),r})).prototype=x,x.constructor=b),(T||P)&&(_("delete"),_("has"),y&&_("get")),(P||E)&&_(w),m&&x.clear&&delete x.clear}else b=v.getConstructor(t,e,y,w),u(b.prototype,n),a.NEED=!0;return d(b,e),S[e]=b,i(i.G+i.W+i.F*(b!=g),S),m||v.setStrong(b,e,y),b}},function(e,t,n){for(var r,i=n(2),o=n(13),u=n(30),a=u("typed_array"),l=u("view"),c=!(!i.ArrayBuffer||!i.DataView),f=c,s=0,p="Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array".split(",");s<9;)(r=i[p[s++]])?(o(r.prototype,a,!0),o(r.prototype,l,!0)):f=!1;e.exports={ABV:c,CONSTR:f,TYPED:a,VIEW:l}},function(e,t,n){var r=n(3),i=n(2).document,o=r(i)&&r(i.createElement);e.exports=function(e){return o?i.createElement(e):{}}},function(e,t,n){var r=n(8),i=n(2),o=i["__core-js_shared__"]||(i["__core-js_shared__"]={});(e.exports=function(e,t){return o[e]||(o[e]=void 0!==t?t:{})})("versions",[]).push({version:r.version,mode:n(31)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(e,t,n){t.f=n(5)},function(e,t,n){var r=n(58)("keys"),i=n(30);e.exports=function(e){return r[e]||(r[e]=i(e))}},function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t,n){var r=n(23);e.exports=Array.isArray||function(e){return"Array"==r(e)}},function(e,t,n){var r=n(2).document;e.exports=r&&r.documentElement},function(e,t,n){var r=n(3),i=n(4),o=function(e,t){if(i(e),!r(t)&&null!==t)throw TypeError(t+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,t,r){try{(r=n(21)(Function.call,n(17).f(Object.prototype,"__proto__").set,2))(e,[]),t=!(e instanceof Array)}catch(e){t=!0}return function(e,n){return o(e,n),t?e.__proto__=n:r(e,n),e}}({},!1):void 0),check:o}},function(e,t){e.exports="\t\n\v\f\r   ᠎              \u2028\u2029\ufeff"},function(e,t,n){var r=n(3),i=n(64).set;e.exports=function(e,t,n){var o,u=t.constructor;return u!==n&&"function"==typeof u&&(o=u.prototype)!==n.prototype&&r(o)&&i&&i(e,o),e}},function(e,t,n){"use strict";var r=n(25),i=n(24);e.exports=function(e){var t=String(i(this)),n="",o=r(e);if(o<0||o==1/0)throw RangeError("Count can't be negative");for(;o>0;(o>>>=1)&&(t+=t))1&o&&(n+=t);return n}},function(e,t){e.exports=Math.sign||function(e){return 0==(e=+e)||e!=e?e:e<0?-1:1}},function(e,t){var n=Math.expm1;e.exports=!n||n(10)>22025.465794806718||n(10)<22025.465794806718||-2e-17!=n(-2e-17)?function(e){return 0==(e=+e)?e:e>-1e-6&&e<1e-6?e+e*e/2:Math.exp(e)-1}:n},function(e,t,n){"use strict";var r=n(31),i=n(0),o=n(10),u=n(13),a=n(38),l=n(96),c=n(37),f=n(36),s=n(5)("iterator"),p=!([].keys&&"next"in[].keys()),d=function(){return this};e.exports=function(e,t,n,h,v,y,m){l(n,t,h);var g,b,w,x=function(e){if(!p&&e in E)return E[e];switch(e){case"keys":case"values":return function(){return new n(this,e)}}return function(){return new n(this,e)}},S=t+" Iterator",_="values"==v,k=!1,E=e.prototype,T=E[s]||E["@@iterator"]||v&&E[v],C=T||x(v),P=v?_?x("entries"):C:void 0,O="Array"==t&&E.entries||T;if(O&&(w=f(O.call(new e)))!==Object.prototype&&w.next&&(c(w,S,!0),r||"function"==typeof w[s]||u(w,s,d)),_&&T&&"values"!==T.name&&(k=!0,C=function(){return T.call(this)}),r&&!m||!p&&!k&&E[s]||u(E,s,C),a[t]=C,a[S]=d,v)if(g={values:_?C:x("values"),keys:y?C:x("keys"),entries:P},m)for(b in g)b in E||o(E,b,g[b]);else i(i.P+i.F*(p||k),t,g);return g}},function(e,t,n){var r=n(72),i=n(24);e.exports=function(e,t,n){if(r(t))throw TypeError("String#"+n+" doesn't accept regex!");return String(i(e))}},function(e,t,n){var r=n(3),i=n(23),o=n(5)("match");e.exports=function(e){var t;return r(e)&&(void 0!==(t=e[o])?!!t:"RegExp"==i(e))}},function(e,t,n){var r=n(5)("match");e.exports=function(e){var t=/./;try{"/./"[e](t)}catch(n){try{return t[r]=!1,!"/./"[e](t)}catch(e){}}return!0}},function(e,t,n){var r=n(38),i=n(5)("iterator"),o=Array.prototype;e.exports=function(e){return void 0!==e&&(r.Array===e||o[i]===e)}},function(e,t,n){"use strict";var r=n(6),i=n(29);e.exports=function(e,t,n){t in e?r.f(e,t,i(0,n)):e[t]=n}},function(e,t,n){var r=n(48),i=n(5)("iterator"),o=n(38);e.exports=n(8).getIteratorMethod=function(e){if(void 0!=e)return e[i]||e["@@iterator"]||o[r(e)]}},function(e,t,n){"use strict";var r=n(15),i=n(33),o=n(9);e.exports=function(e){for(var t=r(this),n=o(t.length),u=arguments.length,a=i(u>1?arguments[1]:void 0,n),l=u>2?arguments[2]:void 0,c=void 0===l?n:i(l,n);c>a;)t[a++]=e;return t}},function(e,t,n){"use strict";var r=n(39),i=n(100),o=n(38),u=n(14);e.exports=n(70)(Array,"Array",function(e,t){this._t=u(e),this._i=0,this._k=t},function(){var e=this._t,t=this._k,n=this._i++;return!e||n>=e.length?(this._t=void 0,i(1)):i(0,"keys"==t?n:"values"==t?e[n]:[n,e[n]])},"values"),o.Arguments=o.Array,r("keys"),r("values"),r("entries")},function(e,t,n){"use strict";var r=n(4);e.exports=function(){var e=r(this),t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),e.unicode&&(t+="u"),e.sticky&&(t+="y"),t}},function(e,t,n){var r,i,o,u=n(21),a=n(89),l=n(63),c=n(57),f=n(2),s=f.process,p=f.setImmediate,d=f.clearImmediate,h=f.MessageChannel,v=f.Dispatch,y=0,m={},g=function(){var e=+this;if(m.hasOwnProperty(e)){var t=m[e];delete m[e],t()}},b=function(e){g.call(e.data)};p&&d||(p=function(e){for(var t=[],n=1;arguments.length>n;)t.push(arguments[n++]);return m[++y]=function(){a("function"==typeof e?e:Function(e),t)},r(y),y},d=function(e){delete m[e]},"process"==n(23)(s)?r=function(e){s.nextTick(u(g,e,1))}:v&&v.now?r=function(e){v.now(u(g,e,1))}:h?(o=(i=new h).port2,i.port1.onmessage=b,r=u(o.postMessage,o,1)):f.addEventListener&&"function"==typeof postMessage&&!f.importScripts?(r=function(e){f.postMessage(e+"","*")},f.addEventListener("message",b,!1)):r="onreadystatechange"in c("script")?function(e){l.appendChild(c("script")).onreadystatechange=function(){l.removeChild(this),g.call(e)}}:function(e){setTimeout(u(g,e,1),0)}),e.exports={set:p,clear:d}},function(e,t,n){"use strict";var r=n(2),i=n(7),o=n(31),u=n(56),a=n(13),l=n(42),c=n(1),f=n(41),s=n(25),p=n(9),d=n(107),h=n(35).f,v=n(6).f,y=n(77),m=n(37),g="prototype",b="Wrong index!",w=r.ArrayBuffer,x=r.DataView,S=r.Math,_=r.RangeError,k=r.Infinity,E=w,T=S.abs,C=S.pow,P=S.floor,O=S.log,N=S.LN2,F=i?"_b":"buffer",M=i?"_l":"byteLength",I=i?"_o":"byteOffset";function A(e,t,n){var r,i,o,u=new Array(n),a=8*n-t-1,l=(1<>1,f=23===t?C(2,-24)-C(2,-77):0,s=0,p=e<0||0===e&&1/e<0?1:0;for((e=T(e))!=e||e===k?(i=e!=e?1:0,r=l):(r=P(O(e)/N),e*(o=C(2,-r))<1&&(r--,o*=2),(e+=r+c>=1?f/o:f*C(2,1-c))*o>=2&&(r++,o/=2),r+c>=l?(i=0,r=l):r+c>=1?(i=(e*o-1)*C(2,t),r+=c):(i=e*C(2,c-1)*C(2,t),r=0));t>=8;u[s++]=255&i,i/=256,t-=8);for(r=r<0;u[s++]=255&r,r/=256,a-=8);return u[--s]|=128*p,u}function j(e,t,n){var r,i=8*n-t-1,o=(1<>1,a=i-7,l=n-1,c=e[l--],f=127&c;for(c>>=7;a>0;f=256*f+e[l],l--,a-=8);for(r=f&(1<<-a)-1,f>>=-a,a+=t;a>0;r=256*r+e[l],l--,a-=8);if(0===f)f=1-u;else{if(f===o)return r?NaN:c?-k:k;r+=C(2,t),f-=u}return(c?-1:1)*r*C(2,f-t)}function L(e){return e[3]<<24|e[2]<<16|e[1]<<8|e[0]}function R(e){return[255&e]}function U(e){return[255&e,e>>8&255]}function D(e){return[255&e,e>>8&255,e>>16&255,e>>24&255]}function z(e){return A(e,52,8)}function W(e){return A(e,23,4)}function V(e,t,n){v(e[g],t,{get:function(){return this[n]}})}function B(e,t,n,r){var i=d(+n);if(i+t>e[M])throw _(b);var o=e[F]._b,u=i+e[I],a=o.slice(u,u+t);return r?a:a.reverse()}function $(e,t,n,r,i,o){var u=d(+n);if(u+t>e[M])throw _(b);for(var a=e[F]._b,l=u+e[I],c=r(+i),f=0;fq;)(H=K[q++])in w||a(w,H,E[H]);o||(G.constructor=w)}var Y=new x(new w(2)),Q=x[g].setInt8;Y.setInt8(0,2147483648),Y.setInt8(1,2147483649),!Y.getInt8(0)&&Y.getInt8(1)||l(x[g],{setInt8:function(e,t){Q.call(this,e,t<<24>>24)},setUint8:function(e,t){Q.call(this,e,t<<24>>24)}},!0)}else w=function(e){f(this,w,"ArrayBuffer");var t=d(e);this._b=y.call(new Array(t),0),this[M]=t},x=function(e,t,n){f(this,x,"DataView"),f(e,w,"DataView");var r=e[M],i=s(t);if(i<0||i>r)throw _("Wrong offset!");if(i+(n=void 0===n?r-i:p(n))>r)throw _("Wrong length!");this[F]=e,this[I]=i,this[M]=n},i&&(V(w,"byteLength","_l"),V(x,"buffer","_b"),V(x,"byteLength","_l"),V(x,"byteOffset","_o")),l(x[g],{getInt8:function(e){return B(this,1,e)[0]<<24>>24},getUint8:function(e){return B(this,1,e)[0]},getInt16:function(e){var t=B(this,2,e,arguments[1]);return(t[1]<<8|t[0])<<16>>16},getUint16:function(e){var t=B(this,2,e,arguments[1]);return t[1]<<8|t[0]},getInt32:function(e){return L(B(this,4,e,arguments[1]))},getUint32:function(e){return L(B(this,4,e,arguments[1]))>>>0},getFloat32:function(e){return j(B(this,4,e,arguments[1]),23,4)},getFloat64:function(e){return j(B(this,8,e,arguments[1]),52,8)},setInt8:function(e,t){$(this,1,e,R,t)},setUint8:function(e,t){$(this,1,e,R,t)},setInt16:function(e,t){$(this,2,e,U,t,arguments[2])},setUint16:function(e,t){$(this,2,e,U,t,arguments[2])},setInt32:function(e,t){$(this,4,e,D,t,arguments[2])},setUint32:function(e,t){$(this,4,e,D,t,arguments[2])},setFloat32:function(e,t){$(this,4,e,W,t,arguments[2])},setFloat64:function(e,t){$(this,8,e,z,t,arguments[2])}});m(w,"ArrayBuffer"),m(x,"DataView"),a(x[g],u.VIEW,!0),t.ArrayBuffer=w,t.DataView=x},function(e,t,n){e.exports=!n(7)&&!n(1)(function(){return 7!=Object.defineProperty(n(57)("div"),"a",{get:function(){return 7}}).a})},function(e,t,n){var r=n(2),i=n(8),o=n(31),u=n(59),a=n(6).f;e.exports=function(e){var t=i.Symbol||(i.Symbol=o?{}:r.Symbol||{});"_"==e.charAt(0)||e in t||a(t,e,{value:u.f(e)})}},function(e,t,n){var r=n(12),i=n(14),o=n(46)(!1),u=n(60)("IE_PROTO");e.exports=function(e,t){var n,a=i(e),l=0,c=[];for(n in a)n!=u&&r(a,n)&&c.push(n);for(;t.length>l;)r(a,n=t[l++])&&(~o(c,n)||c.push(n));return c}},function(e,t,n){var r=n(6),i=n(4),o=n(32);e.exports=n(7)?Object.defineProperties:function(e,t){i(e);for(var n,u=o(t),a=u.length,l=0;a>l;)r.f(e,n=u[l++],t[n]);return e}},function(e,t,n){var r=n(14),i=n(35).f,o={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];e.exports.f=function(e){return u&&"[object Window]"==o.call(e)?function(e){try{return i(e)}catch(e){return u.slice()}}(e):i(r(e))}},function(e,t,n){"use strict";var r=n(32),i=n(47),o=n(45),u=n(15),a=n(44),l=Object.assign;e.exports=!l||n(1)(function(){var e={},t={},n=Symbol(),r="abcdefghijklmnopqrst";return e[n]=7,r.split("").forEach(function(e){t[e]=e}),7!=l({},e)[n]||Object.keys(l({},t)).join("")!=r})?function(e,t){for(var n=u(e),l=arguments.length,c=1,f=i.f,s=o.f;l>c;)for(var p,d=a(arguments[c++]),h=f?r(d).concat(f(d)):r(d),v=h.length,y=0;v>y;)s.call(d,p=h[y++])&&(n[p]=d[p]);return n}:l},function(e,t,n){"use strict";var r=n(22),i=n(3),o=n(89),u=[].slice,a={};e.exports=Function.bind||function(e){var t=r(this),n=u.call(arguments,1),l=function(){var r=n.concat(u.call(arguments));return this instanceof l?function(e,t,n){if(!(t in a)){for(var r=[],i=0;i>>0||(u.test(n)?16:10))}:r},function(e,t,n){var r=n(2).parseFloat,i=n(49).trim;e.exports=1/r(n(65)+"-0")!=-1/0?function(e){var t=i(String(e),3),n=r(t);return 0===n&&"-"==t.charAt(0)?-0:n}:r},function(e,t,n){var r=n(23);e.exports=function(e,t){if("number"!=typeof e&&"Number"!=r(e))throw TypeError(t);return+e}},function(e,t,n){var r=n(3),i=Math.floor;e.exports=function(e){return!r(e)&&isFinite(e)&&i(e)===e}},function(e,t){e.exports=Math.log1p||function(e){return(e=+e)>-1e-8&&e<1e-8?e-e*e/2:Math.log(1+e)}},function(e,t,n){var r=n(25),i=n(24);e.exports=function(e){return function(t,n){var o,u,a=String(i(t)),l=r(n),c=a.length;return l<0||l>=c?e?"":void 0:(o=a.charCodeAt(l))<55296||o>56319||l+1===c||(u=a.charCodeAt(l+1))<56320||u>57343?e?a.charAt(l):o:e?a.slice(l,l+2):u-56320+(o-55296<<10)+65536}}},function(e,t,n){"use strict";var r=n(34),i=n(29),o=n(37),u={};n(13)(u,n(5)("iterator"),function(){return this}),e.exports=function(e,t,n){e.prototype=r(u,{next:i(1,n)}),o(e,t+" Iterator")}},function(e,t,n){var r=n(4);e.exports=function(e,t,n,i){try{return i?t(r(n)[0],n[1]):t(n)}catch(t){var o=e.return;throw void 0!==o&&r(o.call(e)),t}}},function(e,t,n){var r=n(22),i=n(15),o=n(44),u=n(9);e.exports=function(e,t,n,a,l){r(t);var c=i(e),f=o(c),s=u(c.length),p=l?s-1:0,d=l?-1:1;if(n<2)for(;;){if(p in f){a=f[p],p+=d;break}if(p+=d,l?p<0:s<=p)throw TypeError("Reduce of empty array with no initial value")}for(;l?p>=0:s>p;p+=d)p in f&&(a=t(a,f[p],p,c));return a}},function(e,t,n){"use strict";var r=n(15),i=n(33),o=n(9);e.exports=[].copyWithin||function(e,t){var n=r(this),u=o(n.length),a=i(e,u),l=i(t,u),c=arguments.length>2?arguments[2]:void 0,f=Math.min((void 0===c?u:i(c,u))-l,u-a),s=1;for(l0;)l in n?n[a]=n[l]:delete n[a],a+=s,l+=s;return n}},function(e,t){e.exports=function(e,t){return{value:t,done:!!e}}},function(e,t,n){n(7)&&"g"!=/./g.flags&&n(6).f(RegExp.prototype,"flags",{configurable:!0,get:n(79)})},function(e,t,n){"use strict";var r,i,o,u,a=n(31),l=n(2),c=n(21),f=n(48),s=n(0),p=n(3),d=n(22),h=n(41),v=n(52),y=n(53),m=n(80).set,g=n(229)(),b=n(103),w=n(230),x=n(54),S=n(104),_=l.TypeError,k=l.process,E=k&&k.versions,T=E&&E.v8||"",C=l.Promise,P="process"==f(k),O=function(){},N=i=b.f,F=!!function(){try{var e=C.resolve(1),t=(e.constructor={})[n(5)("species")]=function(e){e(O,O)};return(P||"function"==typeof PromiseRejectionEvent)&&e.then(O)instanceof t&&0!==T.indexOf("6.6")&&-1===x.indexOf("Chrome/66")}catch(e){}}(),M=function(e){var t;return!(!p(e)||"function"!=typeof(t=e.then))&&t},I=function(e,t){if(!e._n){e._n=!0;var n=e._c;g(function(){for(var r=e._v,i=1==e._s,o=0,u=function(t){var n,o,u,a=i?t.ok:t.fail,l=t.resolve,c=t.reject,f=t.domain;try{a?(i||(2==e._h&&L(e),e._h=1),!0===a?n=r:(f&&f.enter(),n=a(r),f&&(f.exit(),u=!0)),n===t.promise?c(_("Promise-chain cycle")):(o=M(n))?o.call(n,l,c):l(n)):c(r)}catch(e){f&&!u&&f.exit(),c(e)}};n.length>o;)u(n[o++]);e._c=[],e._n=!1,t&&!e._h&&A(e)})}},A=function(e){m.call(l,function(){var t,n,r,i=e._v,o=j(e);if(o&&(t=w(function(){P?k.emit("unhandledRejection",i,e):(n=l.onunhandledrejection)?n({promise:e,reason:i}):(r=l.console)&&r.error&&r.error("Unhandled promise rejection",i)}),e._h=P||j(e)?2:1),e._a=void 0,o&&t.e)throw t.v})},j=function(e){return 1!==e._h&&0===(e._a||e._c).length},L=function(e){m.call(l,function(){var t;P?k.emit("rejectionHandled",e):(t=l.onrejectionhandled)&&t({promise:e,reason:e._v})})},R=function(e){var t=this;t._d||(t._d=!0,(t=t._w||t)._v=e,t._s=2,t._a||(t._a=t._c.slice()),I(t,!0))},U=function(e){var t,n=this;if(!n._d){n._d=!0,n=n._w||n;try{if(n===e)throw _("Promise can't be resolved itself");(t=M(e))?g(function(){var r={_w:n,_d:!1};try{t.call(e,c(U,r,1),c(R,r,1))}catch(e){R.call(r,e)}}):(n._v=e,n._s=1,I(n,!1))}catch(e){R.call({_w:n,_d:!1},e)}}};F||(C=function(e){h(this,C,"Promise","_h"),d(e),r.call(this);try{e(c(U,this,1),c(R,this,1))}catch(e){R.call(this,e)}},(r=function(e){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1}).prototype=n(42)(C.prototype,{then:function(e,t){var n=N(y(this,C));return n.ok="function"!=typeof e||e,n.fail="function"==typeof t&&t,n.domain=P?k.domain:void 0,this._c.push(n),this._a&&this._a.push(n),this._s&&I(this,!1),n.promise},catch:function(e){return this.then(void 0,e)}}),o=function(){var e=new r;this.promise=e,this.resolve=c(U,e,1),this.reject=c(R,e,1)},b.f=N=function(e){return e===C||e===u?new o(e):i(e)}),s(s.G+s.W+s.F*!F,{Promise:C}),n(37)(C,"Promise"),n(40)("Promise"),u=n(8).Promise,s(s.S+s.F*!F,"Promise",{reject:function(e){var t=N(this);return(0,t.reject)(e),t.promise}}),s(s.S+s.F*(a||!F),"Promise",{resolve:function(e){return S(a&&this===u?C:this,e)}}),s(s.S+s.F*!(F&&n(50)(function(e){C.all(e).catch(O)})),"Promise",{all:function(e){var t=this,n=N(t),r=n.resolve,i=n.reject,o=w(function(){var n=[],o=0,u=1;v(e,!1,function(e){var a=o++,l=!1;n.push(void 0),u++,t.resolve(e).then(function(e){l||(l=!0,n[a]=e,--u||r(n))},i)}),--u||r(n)});return o.e&&i(o.v),n.promise},race:function(e){var t=this,n=N(t),r=n.reject,i=w(function(){v(e,!1,function(e){t.resolve(e).then(n.resolve,r)})});return i.e&&r(i.v),n.promise}})},function(e,t,n){"use strict";var r=n(22);e.exports.f=function(e){return new function(e){var t,n;this.promise=new e(function(e,r){if(void 0!==t||void 0!==n)throw TypeError("Bad Promise constructor");t=e,n=r}),this.resolve=r(t),this.reject=r(n)}(e)}},function(e,t,n){var r=n(4),i=n(3),o=n(103);e.exports=function(e,t){if(r(e),i(t)&&t.constructor===e)return t;var n=o.f(e);return(0,n.resolve)(t),n.promise}},function(e,t,n){"use strict";var r=n(6).f,i=n(34),o=n(42),u=n(21),a=n(41),l=n(52),c=n(70),f=n(100),s=n(40),p=n(7),d=n(28).fastKey,h=n(43),v=p?"_s":"size",y=function(e,t){var n,r=d(t);if("F"!==r)return e._i[r];for(n=e._f;n;n=n.n)if(n.k==t)return n};e.exports={getConstructor:function(e,t,n,c){var f=e(function(e,r){a(e,f,t,"_i"),e._t=t,e._i=i(null),e._f=void 0,e._l=void 0,e[v]=0,void 0!=r&&l(r,n,e[c],e)});return o(f.prototype,{clear:function(){for(var e=h(this,t),n=e._i,r=e._f;r;r=r.n)r.r=!0,r.p&&(r.p=r.p.n=void 0),delete n[r.i];e._f=e._l=void 0,e[v]=0},delete:function(e){var n=h(this,t),r=y(n,e);if(r){var i=r.n,o=r.p;delete n._i[r.i],r.r=!0,o&&(o.n=i),i&&(i.p=o),n._f==r&&(n._f=i),n._l==r&&(n._l=o),n[v]--}return!!r},forEach:function(e){h(this,t);for(var n,r=u(e,arguments.length>1?arguments[1]:void 0,3);n=n?n.n:this._f;)for(r(n.v,n.k,this);n&&n.r;)n=n.p},has:function(e){return!!y(h(this,t),e)}}),p&&r(f.prototype,"size",{get:function(){return h(this,t)[v]}}),f},def:function(e,t,n){var r,i,o=y(e,t);return o?o.v=n:(e._l=o={i:i=d(t,!0),k:t,v:n,p:r=e._l,n:void 0,r:!1},e._f||(e._f=o),r&&(r.n=o),e[v]++,"F"!==i&&(e._i[i]=o)),e},getEntry:y,setStrong:function(e,t,n){c(e,t,function(e,n){this._t=h(e,t),this._k=n,this._l=void 0},function(){for(var e=this._k,t=this._l;t&&t.r;)t=t.p;return this._t&&(this._l=t=t?t.n:this._t._f)?f(0,"keys"==e?t.k:"values"==e?t.v:[t.k,t.v]):(this._t=void 0,f(1))},n?"entries":"values",!n,!0),s(t)}}},function(e,t,n){"use strict";var r=n(42),i=n(28).getWeak,o=n(4),u=n(3),a=n(41),l=n(52),c=n(19),f=n(12),s=n(43),p=c(5),d=c(6),h=0,v=function(e){return e._l||(e._l=new y)},y=function(){this.a=[]},m=function(e,t){return p(e.a,function(e){return e[0]===t})};y.prototype={get:function(e){var t=m(this,e);if(t)return t[1]},has:function(e){return!!m(this,e)},set:function(e,t){var n=m(this,e);n?n[1]=t:this.a.push([e,t])},delete:function(e){var t=d(this.a,function(t){return t[0]===e});return~t&&this.a.splice(t,1),!!~t}},e.exports={getConstructor:function(e,t,n,o){var c=e(function(e,r){a(e,c,t,"_i"),e._t=t,e._i=h++,e._l=void 0,void 0!=r&&l(r,n,e[o],e)});return r(c.prototype,{delete:function(e){if(!u(e))return!1;var n=i(e);return!0===n?v(s(this,t)).delete(e):n&&f(n,this._i)&&delete n[this._i]},has:function(e){if(!u(e))return!1;var n=i(e);return!0===n?v(s(this,t)).has(e):n&&f(n,this._i)}}),c},def:function(e,t,n){var r=i(o(t),!0);return!0===r?v(e).set(t,n):r[e._i]=n,e},ufstore:v}},function(e,t,n){var r=n(25),i=n(9);e.exports=function(e){if(void 0===e)return 0;var t=r(e),n=i(t);if(t!==n)throw RangeError("Wrong length!");return n}},function(e,t,n){var r=n(35),i=n(47),o=n(4),u=n(2).Reflect;e.exports=u&&u.ownKeys||function(e){var t=r.f(o(e)),n=i.f;return n?t.concat(n(e)):t}},function(e,t,n){var r=n(9),i=n(67),o=n(24);e.exports=function(e,t,n,u){var a=String(o(e)),l=a.length,c=void 0===n?" ":String(n),f=r(t);if(f<=l||""==c)return a;var s=f-l,p=i.call(c,Math.ceil(s/c.length));return p.length>s&&(p=p.slice(0,s)),u?p+a:a+p}},function(e,t,n){var r=n(32),i=n(14),o=n(45).f;e.exports=function(e){return function(t){for(var n,u=i(t),a=r(u),l=a.length,c=0,f=[];l>c;)o.call(u,n=a[c++])&&f.push(e?[n,u[n]]:u[n]);return f}}},function(e,t,n){"use strict"; -/* -object-assign -(c) Sindre Sorhus -@license MIT -*/var r=Object.getOwnPropertySymbols,i=Object.prototype.hasOwnProperty,o=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,u,a=function(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;li;)K(e,n=r[i++],t[n]);return e},Y=function(e){var t=L.call(this,e=x(e,!0));return!(this===z&&i(U,e)&&!i(D,e))&&(!(t||!i(this,e)||!i(U,e)||i(this,A)&&this[A][e])||t)},Q=function(e,t){if(e=w(e),t=x(t,!0),e!==z||!i(U,t)||i(D,t)){var n=P(e,t);return!n||!i(U,t)||i(e,A)&&e[A][t]||(n.enumerable=!0),n}},X=function(e){for(var t,n=N(w(e)),r=[],o=0;n.length>o;)i(U,t=n[o++])||t==A||t==l||r.push(t);return r},J=function(e){for(var t,n=e===z,r=N(n?D:w(e)),o=[],u=0;r.length>u;)!i(U,t=r[u++])||n&&!i(z,t)||o.push(U[t]);return o};W||(a((F=function(){if(this instanceof F)throw TypeError("Symbol is not a constructor!");var e=p(arguments.length>0?arguments[0]:void 0),t=function(n){this===z&&t.call(D,n),i(this,A)&&i(this[A],e)&&(this[A][e]=!1),$(this,e,S(1,n))};return o&&B&&$(z,e,{configurable:!0,set:t}),H(e)}).prototype,"toString",function(){return this._k}),E.f=Q,T.f=K,n(35).f=k.f=X,n(45).f=Y,n(47).f=J,o&&!n(31)&&a(z,"propertyIsEnumerable",Y,!0),h.f=function(e){return H(d(e))}),u(u.G+u.W+u.F*!W,{Symbol:F});for(var Z="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),ee=0;Z.length>ee;)d(Z[ee++]);for(var te=C(d.store),ne=0;te.length>ne;)v(te[ne++]);u(u.S+u.F*!W,"Symbol",{for:function(e){return i(R,e+="")?R[e]:R[e]=F(e)},keyFor:function(e){if(!G(e))throw TypeError(e+" is not a symbol!");for(var t in R)if(R[t]===e)return t},useSetter:function(){B=!0},useSimple:function(){B=!1}}),u(u.S+u.F*!W,"Object",{create:function(e,t){return void 0===t?_(e):q(_(e),t)},defineProperty:K,defineProperties:q,getOwnPropertyDescriptor:Q,getOwnPropertyNames:X,getOwnPropertySymbols:J}),M&&u(u.S+u.F*(!W||c(function(){var e=F();return"[null]"!=I([e])||"{}"!=I({a:e})||"{}"!=I(Object(e))})),"JSON",{stringify:function(e){for(var t,n,r=[e],i=1;arguments.length>i;)r.push(arguments[i++]);if(n=t=r[1],(b(t)||void 0!==e)&&!G(e))return m(t)||(t=function(e,t){if("function"==typeof n&&(t=n.call(this,e,t)),!G(t))return t}),r[1]=t,I.apply(M,r)}}),F.prototype[j]||n(13)(F.prototype,j,F.prototype.valueOf),s(F,"Symbol"),s(Math,"Math",!0),s(r.JSON,"JSON",!0)},function(e,t,n){var r=n(32),i=n(47),o=n(45);e.exports=function(e){var t=r(e),n=i.f;if(n)for(var u,a=n(e),l=o.f,c=0;a.length>c;)l.call(e,u=a[c++])&&t.push(u);return t}},function(e,t,n){var r=n(0);r(r.S,"Object",{create:n(34)})},function(e,t,n){var r=n(0);r(r.S+r.F*!n(7),"Object",{defineProperty:n(6).f})},function(e,t,n){var r=n(0);r(r.S+r.F*!n(7),"Object",{defineProperties:n(85)})},function(e,t,n){var r=n(14),i=n(17).f;n(18)("getOwnPropertyDescriptor",function(){return function(e,t){return i(r(e),t)}})},function(e,t,n){var r=n(15),i=n(36);n(18)("getPrototypeOf",function(){return function(e){return i(r(e))}})},function(e,t,n){var r=n(15),i=n(32);n(18)("keys",function(){return function(e){return i(r(e))}})},function(e,t,n){n(18)("getOwnPropertyNames",function(){return n(86).f})},function(e,t,n){var r=n(3),i=n(28).onFreeze;n(18)("freeze",function(e){return function(t){return e&&r(t)?e(i(t)):t}})},function(e,t,n){var r=n(3),i=n(28).onFreeze;n(18)("seal",function(e){return function(t){return e&&r(t)?e(i(t)):t}})},function(e,t,n){var r=n(3),i=n(28).onFreeze;n(18)("preventExtensions",function(e){return function(t){return e&&r(t)?e(i(t)):t}})},function(e,t,n){var r=n(3);n(18)("isFrozen",function(e){return function(t){return!r(t)||!!e&&e(t)}})},function(e,t,n){var r=n(3);n(18)("isSealed",function(e){return function(t){return!r(t)||!!e&&e(t)}})},function(e,t,n){var r=n(3);n(18)("isExtensible",function(e){return function(t){return!!r(t)&&(!e||e(t))}})},function(e,t,n){var r=n(0);r(r.S+r.F,"Object",{assign:n(87)})},function(e,t,n){var r=n(0);r(r.S,"Object",{is:n(134)})},function(e,t){e.exports=Object.is||function(e,t){return e===t?0!==e||1/e==1/t:e!=e&&t!=t}},function(e,t,n){var r=n(0);r(r.S,"Object",{setPrototypeOf:n(64).set})},function(e,t,n){"use strict";var r=n(48),i={};i[n(5)("toStringTag")]="z",i+""!="[object z]"&&n(10)(Object.prototype,"toString",function(){return"[object "+r(this)+"]"},!0)},function(e,t,n){var r=n(0);r(r.P,"Function",{bind:n(88)})},function(e,t,n){var r=n(6).f,i=Function.prototype,o=/^\s*function ([^ (]*)/;"name"in i||n(7)&&r(i,"name",{configurable:!0,get:function(){try{return(""+this).match(o)[1]}catch(e){return""}}})},function(e,t,n){"use strict";var r=n(3),i=n(36),o=n(5)("hasInstance"),u=Function.prototype;o in u||n(6).f(u,o,{value:function(e){if("function"!=typeof this||!r(e))return!1;if(!r(this.prototype))return e instanceof this;for(;e=i(e);)if(this.prototype===e)return!0;return!1}})},function(e,t,n){var r=n(0),i=n(90);r(r.G+r.F*(parseInt!=i),{parseInt:i})},function(e,t,n){var r=n(0),i=n(91);r(r.G+r.F*(parseFloat!=i),{parseFloat:i})},function(e,t,n){"use strict";var r=n(2),i=n(12),o=n(23),u=n(66),a=n(27),l=n(1),c=n(35).f,f=n(17).f,s=n(6).f,p=n(49).trim,d=r.Number,h=d,v=d.prototype,y="Number"==o(n(34)(v)),m="trim"in String.prototype,g=function(e){var t=a(e,!1);if("string"==typeof t&&t.length>2){var n,r,i,o=(t=m?t.trim():p(t,3)).charCodeAt(0);if(43===o||45===o){if(88===(n=t.charCodeAt(2))||120===n)return NaN}else if(48===o){switch(t.charCodeAt(1)){case 66:case 98:r=2,i=49;break;case 79:case 111:r=8,i=55;break;default:return+t}for(var u,l=t.slice(2),c=0,f=l.length;ci)return NaN;return parseInt(l,r)}}return+t};if(!d(" 0o1")||!d("0b1")||d("+0x1")){d=function(e){var t=arguments.length<1?0:e,n=this;return n instanceof d&&(y?l(function(){v.valueOf.call(n)}):"Number"!=o(n))?u(new h(g(t)),n,d):g(t)};for(var b,w=n(7)?c(h):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),x=0;w.length>x;x++)i(h,b=w[x])&&!i(d,b)&&s(d,b,f(h,b));d.prototype=v,v.constructor=d,n(10)(r,"Number",d)}},function(e,t,n){"use strict";var r=n(0),i=n(25),o=n(92),u=n(67),a=1..toFixed,l=Math.floor,c=[0,0,0,0,0,0],f="Number.toFixed: incorrect invocation!",s=function(e,t){for(var n=-1,r=t;++n<6;)r+=e*c[n],c[n]=r%1e7,r=l(r/1e7)},p=function(e){for(var t=6,n=0;--t>=0;)n+=c[t],c[t]=l(n/e),n=n%e*1e7},d=function(){for(var e=6,t="";--e>=0;)if(""!==t||0===e||0!==c[e]){var n=String(c[e]);t=""===t?n:t+u.call("0",7-n.length)+n}return t},h=function(e,t,n){return 0===t?n:t%2==1?h(e,t-1,n*e):h(e*e,t/2,n)};r(r.P+r.F*(!!a&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!n(1)(function(){a.call({})})),"Number",{toFixed:function(e){var t,n,r,a,l=o(this,f),c=i(e),v="",y="0";if(c<0||c>20)throw RangeError(f);if(l!=l)return"NaN";if(l<=-1e21||l>=1e21)return String(l);if(l<0&&(v="-",l=-l),l>1e-21)if(n=(t=function(e){for(var t=0,n=e;n>=4096;)t+=12,n/=4096;for(;n>=2;)t+=1,n/=2;return t}(l*h(2,69,1))-69)<0?l*h(2,-t,1):l/h(2,t,1),n*=4503599627370496,(t=52-t)>0){for(s(0,n),r=c;r>=7;)s(1e7,0),r-=7;for(s(h(10,r,1),0),r=t-1;r>=23;)p(1<<23),r-=23;p(1<0?v+((a=y.length)<=c?"0."+u.call("0",c-a)+y:y.slice(0,a-c)+"."+y.slice(a-c)):v+y}})},function(e,t,n){"use strict";var r=n(0),i=n(1),o=n(92),u=1..toPrecision;r(r.P+r.F*(i(function(){return"1"!==u.call(1,void 0)})||!i(function(){u.call({})})),"Number",{toPrecision:function(e){var t=o(this,"Number#toPrecision: incorrect invocation!");return void 0===e?u.call(t):u.call(t,e)}})},function(e,t,n){var r=n(0);r(r.S,"Number",{EPSILON:Math.pow(2,-52)})},function(e,t,n){var r=n(0),i=n(2).isFinite;r(r.S,"Number",{isFinite:function(e){return"number"==typeof e&&i(e)}})},function(e,t,n){var r=n(0);r(r.S,"Number",{isInteger:n(93)})},function(e,t,n){var r=n(0);r(r.S,"Number",{isNaN:function(e){return e!=e}})},function(e,t,n){var r=n(0),i=n(93),o=Math.abs;r(r.S,"Number",{isSafeInteger:function(e){return i(e)&&o(e)<=9007199254740991}})},function(e,t,n){var r=n(0);r(r.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},function(e,t,n){var r=n(0);r(r.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},function(e,t,n){var r=n(0),i=n(91);r(r.S+r.F*(Number.parseFloat!=i),"Number",{parseFloat:i})},function(e,t,n){var r=n(0),i=n(90);r(r.S+r.F*(Number.parseInt!=i),"Number",{parseInt:i})},function(e,t,n){var r=n(0),i=n(94),o=Math.sqrt,u=Math.acosh;r(r.S+r.F*!(u&&710==Math.floor(u(Number.MAX_VALUE))&&u(1/0)==1/0),"Math",{acosh:function(e){return(e=+e)<1?NaN:e>94906265.62425156?Math.log(e)+Math.LN2:i(e-1+o(e-1)*o(e+1))}})},function(e,t,n){var r=n(0),i=Math.asinh;r(r.S+r.F*!(i&&1/i(0)>0),"Math",{asinh:function e(t){return isFinite(t=+t)&&0!=t?t<0?-e(-t):Math.log(t+Math.sqrt(t*t+1)):t}})},function(e,t,n){var r=n(0),i=Math.atanh;r(r.S+r.F*!(i&&1/i(-0)<0),"Math",{atanh:function(e){return 0==(e=+e)?e:Math.log((1+e)/(1-e))/2}})},function(e,t,n){var r=n(0),i=n(68);r(r.S,"Math",{cbrt:function(e){return i(e=+e)*Math.pow(Math.abs(e),1/3)}})},function(e,t,n){var r=n(0);r(r.S,"Math",{clz32:function(e){return(e>>>=0)?31-Math.floor(Math.log(e+.5)*Math.LOG2E):32}})},function(e,t,n){var r=n(0),i=Math.exp;r(r.S,"Math",{cosh:function(e){return(i(e=+e)+i(-e))/2}})},function(e,t,n){var r=n(0),i=n(69);r(r.S+r.F*(i!=Math.expm1),"Math",{expm1:i})},function(e,t,n){var r=n(0);r(r.S,"Math",{fround:n(162)})},function(e,t,n){var r=n(68),i=Math.pow,o=i(2,-52),u=i(2,-23),a=i(2,127)*(2-u),l=i(2,-126);e.exports=Math.fround||function(e){var t,n,i=Math.abs(e),c=r(e);return ia||n!=n?c*(1/0):c*n}},function(e,t,n){var r=n(0),i=Math.abs;r(r.S,"Math",{hypot:function(e,t){for(var n,r,o=0,u=0,a=arguments.length,l=0;u0?(r=n/l)*r:n;return l===1/0?1/0:l*Math.sqrt(o)}})},function(e,t,n){var r=n(0),i=Math.imul;r(r.S+r.F*n(1)(function(){return-5!=i(4294967295,5)||2!=i.length}),"Math",{imul:function(e,t){var n=+e,r=+t,i=65535&n,o=65535&r;return 0|i*o+((65535&n>>>16)*o+i*(65535&r>>>16)<<16>>>0)}})},function(e,t,n){var r=n(0);r(r.S,"Math",{log10:function(e){return Math.log(e)*Math.LOG10E}})},function(e,t,n){var r=n(0);r(r.S,"Math",{log1p:n(94)})},function(e,t,n){var r=n(0);r(r.S,"Math",{log2:function(e){return Math.log(e)/Math.LN2}})},function(e,t,n){var r=n(0);r(r.S,"Math",{sign:n(68)})},function(e,t,n){var r=n(0),i=n(69),o=Math.exp;r(r.S+r.F*n(1)(function(){return-2e-17!=!Math.sinh(-2e-17)}),"Math",{sinh:function(e){return Math.abs(e=+e)<1?(i(e)-i(-e))/2:(o(e-1)-o(-e-1))*(Math.E/2)}})},function(e,t,n){var r=n(0),i=n(69),o=Math.exp;r(r.S,"Math",{tanh:function(e){var t=i(e=+e),n=i(-e);return t==1/0?1:n==1/0?-1:(t-n)/(o(e)+o(-e))}})},function(e,t,n){var r=n(0);r(r.S,"Math",{trunc:function(e){return(e>0?Math.floor:Math.ceil)(e)}})},function(e,t,n){var r=n(0),i=n(33),o=String.fromCharCode,u=String.fromCodePoint;r(r.S+r.F*(!!u&&1!=u.length),"String",{fromCodePoint:function(e){for(var t,n=[],r=arguments.length,u=0;r>u;){if(t=+arguments[u++],i(t,1114111)!==t)throw RangeError(t+" is not a valid code point");n.push(t<65536?o(t):o(55296+((t-=65536)>>10),t%1024+56320))}return n.join("")}})},function(e,t,n){var r=n(0),i=n(14),o=n(9);r(r.S,"String",{raw:function(e){for(var t=i(e.raw),n=o(t.length),r=arguments.length,u=[],a=0;n>a;)u.push(String(t[a++])),a=t.length?{value:void 0,done:!0}:(e=r(t,n),this._i+=e.length,{value:e,done:!1})})},function(e,t,n){"use strict";var r=n(0),i=n(95)(!1);r(r.P,"String",{codePointAt:function(e){return i(this,e)}})},function(e,t,n){"use strict";var r=n(0),i=n(9),o=n(71),u="".endsWith;r(r.P+r.F*n(73)("endsWith"),"String",{endsWith:function(e){var t=o(this,e,"endsWith"),n=arguments.length>1?arguments[1]:void 0,r=i(t.length),a=void 0===n?r:Math.min(i(n),r),l=String(e);return u?u.call(t,l,a):t.slice(a-l.length,a)===l}})},function(e,t,n){"use strict";var r=n(0),i=n(71);r(r.P+r.F*n(73)("includes"),"String",{includes:function(e){return!!~i(this,e,"includes").indexOf(e,arguments.length>1?arguments[1]:void 0)}})},function(e,t,n){var r=n(0);r(r.P,"String",{repeat:n(67)})},function(e,t,n){"use strict";var r=n(0),i=n(9),o=n(71),u="".startsWith;r(r.P+r.F*n(73)("startsWith"),"String",{startsWith:function(e){var t=o(this,e,"startsWith"),n=i(Math.min(arguments.length>1?arguments[1]:void 0,t.length)),r=String(e);return u?u.call(t,r,n):t.slice(n,n+r.length)===r}})},function(e,t,n){"use strict";n(11)("anchor",function(e){return function(t){return e(this,"a","name",t)}})},function(e,t,n){"use strict";n(11)("big",function(e){return function(){return e(this,"big","","")}})},function(e,t,n){"use strict";n(11)("blink",function(e){return function(){return e(this,"blink","","")}})},function(e,t,n){"use strict";n(11)("bold",function(e){return function(){return e(this,"b","","")}})},function(e,t,n){"use strict";n(11)("fixed",function(e){return function(){return e(this,"tt","","")}})},function(e,t,n){"use strict";n(11)("fontcolor",function(e){return function(t){return e(this,"font","color",t)}})},function(e,t,n){"use strict";n(11)("fontsize",function(e){return function(t){return e(this,"font","size",t)}})},function(e,t,n){"use strict";n(11)("italics",function(e){return function(){return e(this,"i","","")}})},function(e,t,n){"use strict";n(11)("link",function(e){return function(t){return e(this,"a","href",t)}})},function(e,t,n){"use strict";n(11)("small",function(e){return function(){return e(this,"small","","")}})},function(e,t,n){"use strict";n(11)("strike",function(e){return function(){return e(this,"strike","","")}})},function(e,t,n){"use strict";n(11)("sub",function(e){return function(){return e(this,"sub","","")}})},function(e,t,n){"use strict";n(11)("sup",function(e){return function(){return e(this,"sup","","")}})},function(e,t,n){var r=n(0);r(r.S,"Date",{now:function(){return(new Date).getTime()}})},function(e,t,n){"use strict";var r=n(0),i=n(15),o=n(27);r(r.P+r.F*n(1)(function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}),"Date",{toJSON:function(e){var t=i(this),n=o(t);return"number"!=typeof n||isFinite(n)?t.toISOString():null}})},function(e,t,n){var r=n(0),i=n(197);r(r.P+r.F*(Date.prototype.toISOString!==i),"Date",{toISOString:i})},function(e,t,n){"use strict";var r=n(1),i=Date.prototype.getTime,o=Date.prototype.toISOString,u=function(e){return e>9?e:"0"+e};e.exports=r(function(){return"0385-07-25T07:06:39.999Z"!=o.call(new Date(-5e13-1))})||!r(function(){o.call(new Date(NaN))})?function(){if(!isFinite(i.call(this)))throw RangeError("Invalid time value");var e=this,t=e.getUTCFullYear(),n=e.getUTCMilliseconds(),r=t<0?"-":t>9999?"+":"";return r+("00000"+Math.abs(t)).slice(r?-6:-4)+"-"+u(e.getUTCMonth()+1)+"-"+u(e.getUTCDate())+"T"+u(e.getUTCHours())+":"+u(e.getUTCMinutes())+":"+u(e.getUTCSeconds())+"."+(n>99?n:"0"+u(n))+"Z"}:o},function(e,t,n){var r=Date.prototype,i=r.toString,o=r.getTime;new Date(NaN)+""!="Invalid Date"&&n(10)(r,"toString",function(){var e=o.call(this);return e==e?i.call(this):"Invalid Date"})},function(e,t,n){var r=n(5)("toPrimitive"),i=Date.prototype;r in i||n(13)(i,r,n(200))},function(e,t,n){"use strict";var r=n(4),i=n(27);e.exports=function(e){if("string"!==e&&"number"!==e&&"default"!==e)throw TypeError("Incorrect hint");return i(r(this),"number"!=e)}},function(e,t,n){var r=n(0);r(r.S,"Array",{isArray:n(62)})},function(e,t,n){"use strict";var r=n(21),i=n(0),o=n(15),u=n(97),a=n(74),l=n(9),c=n(75),f=n(76);i(i.S+i.F*!n(50)(function(e){Array.from(e)}),"Array",{from:function(e){var t,n,i,s,p=o(e),d="function"==typeof this?this:Array,h=arguments.length,v=h>1?arguments[1]:void 0,y=void 0!==v,m=0,g=f(p);if(y&&(v=r(v,h>2?arguments[2]:void 0,2)),void 0==g||d==Array&&a(g))for(n=new d(t=l(p.length));t>m;m++)c(n,m,y?v(p[m],m):p[m]);else for(s=g.call(p),n=new d;!(i=s.next()).done;m++)c(n,m,y?u(s,v,[i.value,m],!0):i.value);return n.length=m,n}})},function(e,t,n){"use strict";var r=n(0),i=n(75);r(r.S+r.F*n(1)(function(){function e(){}return!(Array.of.call(e)instanceof e)}),"Array",{of:function(){for(var e=0,t=arguments.length,n=new("function"==typeof this?this:Array)(t);t>e;)i(n,e,arguments[e++]);return n.length=t,n}})},function(e,t,n){"use strict";var r=n(0),i=n(14),o=[].join;r(r.P+r.F*(n(44)!=Object||!n(16)(o)),"Array",{join:function(e){return o.call(i(this),void 0===e?",":e)}})},function(e,t,n){"use strict";var r=n(0),i=n(63),o=n(23),u=n(33),a=n(9),l=[].slice;r(r.P+r.F*n(1)(function(){i&&l.call(i)}),"Array",{slice:function(e,t){var n=a(this.length),r=o(this);if(t=void 0===t?n:t,"Array"==r)return l.call(this,e,t);for(var i=u(e,n),c=u(t,n),f=a(c-i),s=new Array(f),p=0;p1&&(r=Math.min(r,o(arguments[1]))),r<0&&(r=n+r);r>=0;r--)if(r in t&&t[r]===e)return r||0;return-1}})},function(e,t,n){var r=n(0);r(r.P,"Array",{copyWithin:n(99)}),n(39)("copyWithin")},function(e,t,n){var r=n(0);r(r.P,"Array",{fill:n(77)}),n(39)("fill")},function(e,t,n){"use strict";var r=n(0),i=n(19)(5),o=!0;"find"in[]&&Array(1).find(function(){o=!1}),r(r.P+r.F*o,"Array",{find:function(e){return i(this,e,arguments.length>1?arguments[1]:void 0)}}),n(39)("find")},function(e,t,n){"use strict";var r=n(0),i=n(19)(6),o="findIndex",u=!0;o in[]&&Array(1)[o](function(){u=!1}),r(r.P+r.F*u,"Array",{findIndex:function(e){return i(this,e,arguments.length>1?arguments[1]:void 0)}}),n(39)(o)},function(e,t,n){n(40)("Array")},function(e,t,n){var r=n(2),i=n(66),o=n(6).f,u=n(35).f,a=n(72),l=n(79),c=r.RegExp,f=c,s=c.prototype,p=/a/g,d=/a/g,h=new c(p)!==p;if(n(7)&&(!h||n(1)(function(){return d[n(5)("match")]=!1,c(p)!=p||c(d)==d||"/a/i"!=c(p,"i")}))){c=function(e,t){var n=this instanceof c,r=a(e),o=void 0===t;return!n&&r&&e.constructor===c&&o?e:i(h?new f(r&&!o?e.source:e,t):f((r=e instanceof c)?e.source:e,r&&o?l.call(e):t),n?this:s,c)};for(var v=function(e){e in c||o(c,e,{configurable:!0,get:function(){return f[e]},set:function(t){f[e]=t}})},y=u(f),m=0;y.length>m;)v(y[m++]);s.constructor=c,c.prototype=s,n(10)(r,"RegExp",c)}n(40)("RegExp")},function(e,t,n){"use strict";n(101);var r=n(4),i=n(79),o=n(7),u=/./.toString,a=function(e){n(10)(RegExp.prototype,"toString",e,!0)};n(1)(function(){return"/a/b"!=u.call({source:"a",flags:"b"})})?a(function(){var e=r(this);return"/".concat(e.source,"/","flags"in e?e.flags:!o&&e instanceof RegExp?i.call(e):void 0)}):"toString"!=u.name&&a(function(){return u.call(this)})},function(e,t,n){n(51)("match",1,function(e,t,n){return[function(n){"use strict";var r=e(this),i=void 0==n?void 0:n[t];return void 0!==i?i.call(n,r):new RegExp(n)[t](String(r))},n]})},function(e,t,n){n(51)("replace",2,function(e,t,n){return[function(r,i){"use strict";var o=e(this),u=void 0==r?void 0:r[t];return void 0!==u?u.call(r,o,i):n.call(String(o),r,i)},n]})},function(e,t,n){n(51)("search",1,function(e,t,n){return[function(n){"use strict";var r=e(this),i=void 0==n?void 0:n[t];return void 0!==i?i.call(n,r):new RegExp(n)[t](String(r))},n]})},function(e,t,n){n(51)("split",2,function(e,t,r){"use strict";var i=n(72),o=r,u=[].push;if("c"=="abbc".split(/(b)*/)[1]||4!="test".split(/(?:)/,-1).length||2!="ab".split(/(?:ab)*/).length||4!=".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length){var a=void 0===/()??/.exec("")[1];r=function(e,t){var n=String(this);if(void 0===e&&0===t)return[];if(!i(e))return o.call(n,e,t);var r,l,c,f,s,p=[],d=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.unicode?"u":"")+(e.sticky?"y":""),h=0,v=void 0===t?4294967295:t>>>0,y=new RegExp(e.source,d+"g");for(a||(r=new RegExp("^"+y.source+"$(?!\\s)",d));(l=y.exec(n))&&!((c=l.index+l[0].length)>h&&(p.push(n.slice(h,l.index)),!a&&l.length>1&&l[0].replace(r,function(){for(s=1;s1&&l.index=v));)y.lastIndex===l.index&&y.lastIndex++;return h===n.length?!f&&y.test("")||p.push(""):p.push(n.slice(h)),p.length>v?p.slice(0,v):p}}else"0".split(void 0,0).length&&(r=function(e,t){return void 0===e&&0===t?[]:o.call(this,e,t)});return[function(n,i){var o=e(this),u=void 0==n?void 0:n[t];return void 0!==u?u.call(n,o,i):r.call(String(o),n,i)},r]})},function(e,t,n){var r=n(2),i=n(80).set,o=r.MutationObserver||r.WebKitMutationObserver,u=r.process,a=r.Promise,l="process"==n(23)(u);e.exports=function(){var e,t,n,c=function(){var r,i;for(l&&(r=u.domain)&&r.exit();e;){i=e.fn,e=e.next;try{i()}catch(r){throw e?n():t=void 0,r}}t=void 0,r&&r.enter()};if(l)n=function(){u.nextTick(c)};else if(!o||r.navigator&&r.navigator.standalone)if(a&&a.resolve){var f=a.resolve(void 0);n=function(){f.then(c)}}else n=function(){i.call(r,c)};else{var s=!0,p=document.createTextNode("");new o(c).observe(p,{characterData:!0}),n=function(){p.data=s=!s}}return function(r){var i={fn:r,next:void 0};t&&(t.next=i),e||(e=i,n()),t=i}}},function(e,t){e.exports=function(e){try{return{e:!1,v:e()}}catch(e){return{e:!0,v:e}}}},function(e,t,n){"use strict";var r=n(105),i=n(43);e.exports=n(55)("Map",function(e){return function(){return e(this,arguments.length>0?arguments[0]:void 0)}},{get:function(e){var t=r.getEntry(i(this,"Map"),e);return t&&t.v},set:function(e,t){return r.def(i(this,"Map"),0===e?0:e,t)}},r,!0)},function(e,t,n){"use strict";var r=n(105),i=n(43);e.exports=n(55)("Set",function(e){return function(){return e(this,arguments.length>0?arguments[0]:void 0)}},{add:function(e){return r.def(i(this,"Set"),e=0===e?0:e,e)}},r)},function(e,t,n){"use strict";var r,i=n(19)(0),o=n(10),u=n(28),a=n(87),l=n(106),c=n(3),f=n(1),s=n(43),p=u.getWeak,d=Object.isExtensible,h=l.ufstore,v={},y=function(e){return function(){return e(this,arguments.length>0?arguments[0]:void 0)}},m={get:function(e){if(c(e)){var t=p(e);return!0===t?h(s(this,"WeakMap")).get(e):t?t[this._i]:void 0}},set:function(e,t){return l.def(s(this,"WeakMap"),e,t)}},g=e.exports=n(55)("WeakMap",y,m,l,!0,!0);f(function(){return 7!=(new g).set((Object.freeze||Object)(v),7).get(v)})&&(a((r=l.getConstructor(y,"WeakMap")).prototype,m),u.NEED=!0,i(["delete","has","get","set"],function(e){var t=g.prototype,n=t[e];o(t,e,function(t,i){if(c(t)&&!d(t)){this._f||(this._f=new r);var o=this._f[e](t,i);return"set"==e?this:o}return n.call(this,t,i)})}))},function(e,t,n){"use strict";var r=n(106),i=n(43);n(55)("WeakSet",function(e){return function(){return e(this,arguments.length>0?arguments[0]:void 0)}},{add:function(e){return r.def(i(this,"WeakSet"),e,!0)}},r,!1,!0)},function(e,t,n){"use strict";var r=n(0),i=n(56),o=n(81),u=n(4),a=n(33),l=n(9),c=n(3),f=n(2).ArrayBuffer,s=n(53),p=o.ArrayBuffer,d=o.DataView,h=i.ABV&&f.isView,v=p.prototype.slice,y=i.VIEW;r(r.G+r.W+r.F*(f!==p),{ArrayBuffer:p}),r(r.S+r.F*!i.CONSTR,"ArrayBuffer",{isView:function(e){return h&&h(e)||c(e)&&y in e}}),r(r.P+r.U+r.F*n(1)(function(){return!new p(2).slice(1,void 0).byteLength}),"ArrayBuffer",{slice:function(e,t){if(void 0!==v&&void 0===t)return v.call(u(this),e);for(var n=u(this).byteLength,r=a(e,n),i=a(void 0===t?n:t,n),o=new(s(this,p))(l(i-r)),c=new d(this),f=new d(o),h=0;r=t.length)return{value:void 0,done:!0}}while(!((e=t[this._i++])in this._t));return{value:e,done:!1}}),r(r.S,"Reflect",{enumerate:function(e){return new o(e)}})},function(e,t,n){var r=n(17),i=n(36),o=n(12),u=n(0),a=n(3),l=n(4);u(u.S,"Reflect",{get:function e(t,n){var u,c,f=arguments.length<3?t:arguments[2];return l(t)===f?t[n]:(u=r.f(t,n))?o(u,"value")?u.value:void 0!==u.get?u.get.call(f):void 0:a(c=i(t))?e(c,n,f):void 0}})},function(e,t,n){var r=n(17),i=n(0),o=n(4);i(i.S,"Reflect",{getOwnPropertyDescriptor:function(e,t){return r.f(o(e),t)}})},function(e,t,n){var r=n(0),i=n(36),o=n(4);r(r.S,"Reflect",{getPrototypeOf:function(e){return i(o(e))}})},function(e,t,n){var r=n(0);r(r.S,"Reflect",{has:function(e,t){return t in e}})},function(e,t,n){var r=n(0),i=n(4),o=Object.isExtensible;r(r.S,"Reflect",{isExtensible:function(e){return i(e),!o||o(e)}})},function(e,t,n){var r=n(0);r(r.S,"Reflect",{ownKeys:n(108)})},function(e,t,n){var r=n(0),i=n(4),o=Object.preventExtensions;r(r.S,"Reflect",{preventExtensions:function(e){i(e);try{return o&&o(e),!0}catch(e){return!1}}})},function(e,t,n){var r=n(6),i=n(17),o=n(36),u=n(12),a=n(0),l=n(29),c=n(4),f=n(3);a(a.S,"Reflect",{set:function e(t,n,a){var s,p,d=arguments.length<4?t:arguments[3],h=i.f(c(t),n);if(!h){if(f(p=o(t)))return e(p,n,a,d);h=l(0)}if(u(h,"value")){if(!1===h.writable||!f(d))return!1;if(s=i.f(d,n)){if(s.get||s.set||!1===s.writable)return!1;s.value=a,r.f(d,n,s)}else r.f(d,n,l(0,a));return!0}return void 0!==h.set&&(h.set.call(d,a),!0)}})},function(e,t,n){var r=n(0),i=n(64);i&&r(r.S,"Reflect",{setPrototypeOf:function(e,t){i.check(e,t);try{return i.set(e,t),!0}catch(e){return!1}}})},function(e,t,n){n(261),e.exports=n(8).Array.includes},function(e,t,n){"use strict";var r=n(0),i=n(46)(!0);r(r.P,"Array",{includes:function(e){return i(this,e,arguments.length>1?arguments[1]:void 0)}}),n(39)("includes")},function(e,t,n){n(263),e.exports=n(8).String.padStart},function(e,t,n){"use strict";var r=n(0),i=n(109),o=n(54);r(r.P+r.F*/Version\/10\.\d+(\.\d+)? Safari\//.test(o),"String",{padStart:function(e){return i(this,e,arguments.length>1?arguments[1]:void 0,!0)}})},function(e,t,n){n(265),e.exports=n(8).String.padEnd},function(e,t,n){"use strict";var r=n(0),i=n(109),o=n(54);r(r.P+r.F*/Version\/10\.\d+(\.\d+)? Safari\//.test(o),"String",{padEnd:function(e){return i(this,e,arguments.length>1?arguments[1]:void 0,!1)}})},function(e,t,n){n(267),e.exports=n(59).f("asyncIterator")},function(e,t,n){n(83)("asyncIterator")},function(e,t,n){n(269),e.exports=n(8).Object.getOwnPropertyDescriptors},function(e,t,n){var r=n(0),i=n(108),o=n(14),u=n(17),a=n(75);r(r.S,"Object",{getOwnPropertyDescriptors:function(e){for(var t,n,r=o(e),l=u.f,c=i(r),f={},s=0;c.length>s;)void 0!==(n=l(r,t=c[s++]))&&a(f,t,n);return f}})},function(e,t,n){n(271),e.exports=n(8).Object.values},function(e,t,n){var r=n(0),i=n(110)(!1);r(r.S,"Object",{values:function(e){return i(e)}})},function(e,t,n){n(273),e.exports=n(8).Object.entries},function(e,t,n){var r=n(0),i=n(110)(!0);r(r.S,"Object",{entries:function(e){return i(e)}})},function(e,t,n){"use strict";n(102),n(275),e.exports=n(8).Promise.finally},function(e,t,n){"use strict";var r=n(0),i=n(8),o=n(2),u=n(53),a=n(104);r(r.P+r.R,"Promise",{finally:function(e){var t=u(this,i.Promise||o.Promise),n="function"==typeof e;return this.then(n?function(n){return a(t,e()).then(function(){return n})}:e,n?function(n){return a(t,e()).then(function(){throw n})}:e)}})},function(e,t,n){n(277),n(278),n(279),e.exports=n(8)},function(e,t,n){var r=n(2),i=n(0),o=n(54),u=[].slice,a=/MSIE .\./.test(o),l=function(e){return function(t,n){var r=arguments.length>2,i=!!r&&u.call(arguments,2);return e(r?function(){("function"==typeof t?t:Function(t)).apply(this,i)}:t,n)}};i(i.G+i.B+i.F*a,{setTimeout:l(r.setTimeout),setInterval:l(r.setInterval)})},function(e,t,n){var r=n(0),i=n(80);r(r.G+r.B,{setImmediate:i.set,clearImmediate:i.clear})},function(e,t,n){for(var r=n(78),i=n(32),o=n(10),u=n(2),a=n(13),l=n(38),c=n(5),f=c("iterator"),s=c("toStringTag"),p=l.Array,d={CSSRuleList:!0,CSSStyleDeclaration:!1,CSSValueList:!1,ClientRectList:!1,DOMRectList:!1,DOMStringList:!1,DOMTokenList:!0,DataTransferItemList:!1,FileList:!1,HTMLAllCollection:!1,HTMLCollection:!1,HTMLFormElement:!1,HTMLSelectElement:!1,MediaList:!0,MimeTypeArray:!1,NamedNodeMap:!1,NodeList:!0,PaintRequestList:!1,Plugin:!1,PluginArray:!1,SVGLengthList:!1,SVGNumberList:!1,SVGPathSegList:!1,SVGPointList:!1,SVGStringList:!1,SVGTransformList:!1,SourceBufferList:!1,StyleSheetList:!0,TextTrackCueList:!1,TextTrackList:!1,TouchList:!1},h=i(d),v=0;v=0;--o){var u=this.tryEntries[o],a=u.completion;if("root"===u.tryLoc)return r("end");if(u.tryLoc<=this.prev){var l=i.call(u,"catchLoc"),c=i.call(u,"finallyLoc");if(l&&c){if(this.prev=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&i.call(r,"finallyLoc")&&this.prev=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),O(n),v}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var r=n.completion;if("throw"===r.type){var i=r.arg;O(n)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,r){return this.delegate={iterator:F(e),resultName:t,nextLoc:r},"next"===this.method&&(this.arg=n),v}}}function w(e,t,n,r){var i=t&&t.prototype instanceof S?t:S,o=Object.create(i.prototype),u=new N(r||[]);return o._invoke=function(e,t,n){var r=s;return function(i,o){if(r===d)throw new Error("Generator is already running");if(r===h){if("throw"===i)throw o;return M()}for(n.method=i,n.arg=o;;){var u=n.delegate;if(u){var a=C(u,n);if(a){if(a===v)continue;return a}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(r===s)throw r=h,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);r=d;var l=x(e,t,n);if("normal"===l.type){if(r=n.done?h:p,l.arg===v)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(r=h,n.method="throw",n.arg=l.arg)}}}(e,n,u),o}function x(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}function S(){}function _(){}function k(){}function E(e){["next","throw","return"].forEach(function(t){e[t]=function(e){return this._invoke(t,e)}})}function T(e){var t;this._invoke=function(n,r){function o(){return new Promise(function(t,o){!function t(n,r,o,u){var a=x(e[n],e,r);if("throw"!==a.type){var l=a.arg,c=l.value;return c&&"object"==typeof c&&i.call(c,"__await")?Promise.resolve(c.__await).then(function(e){t("next",e,o,u)},function(e){t("throw",e,o,u)}):Promise.resolve(c).then(function(e){l.value=e,o(l)},u)}u(a.arg)}(n,r,t,o)})}return t=t?t.then(o,o):o()}}function C(e,t){var r=e.iterator[t.method];if(r===n){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=n,C(e,t),"throw"===t.method))return v;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return v}var i=x(r,e.iterator,t.arg);if("throw"===i.type)return t.method="throw",t.arg=i.arg,t.delegate=null,v;var o=i.arg;return o?o.done?(t[e.resultName]=o.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=n),t.delegate=null,v):o:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,v)}function P(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function O(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function N(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(P,this),this.reset(!0)}function F(e){if(e){var t=e[u];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var r=-1,o=function t(){for(;++rF.length&&F.push(e)}function A(e,t,n){return null==e?0:function e(t,n,r,i){var a=typeof t;"undefined"!==a&&"boolean"!==a||(t=null);var l=!1;if(null===t)l=!0;else switch(a){case"string":case"number":l=!0;break;case"object":switch(t.$$typeof){case o:case u:l=!0}}if(l)return r(i,t,""===n?"."+j(t,0):n),1;if(l=0,n=""===n?".":n+":",Array.isArray(t))for(var c=0;cthis.eventPool.length&&this.eventPool.push(e)}function se(e){e.eventPool=[],e.getPooled=ce,e.release=fe}i(le.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=ue)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=ue)},persist:function(){this.isPersistent=ue},isPersistent:ae,destructor:function(){var e,t=this.constructor.Interface;for(e in t)this[e]=null;this.nativeEvent=this._targetInst=this.dispatchConfig=null,this.isPropagationStopped=this.isDefaultPrevented=ae,this._dispatchInstances=this._dispatchListeners=null}}),le.Interface={type:null,target:null,currentTarget:function(){return null},eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null},le.extend=function(e){function t(){}function n(){return r.apply(this,arguments)}var r=this;t.prototype=r.prototype;var o=new t;return i(o,n.prototype),n.prototype=o,n.prototype.constructor=n,n.Interface=i({},r.Interface,e),n.extend=r.extend,se(n),n},se(le);var pe=le.extend({data:null}),de=le.extend({data:null}),he=[9,13,27,32],ve=H&&"CompositionEvent"in window,ye=null;H&&"documentMode"in document&&(ye=document.documentMode);var me=H&&"TextEvent"in window&&!ye,ge=H&&(!ve||ye&&8=ye),be=String.fromCharCode(32),we={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["compositionend","keypress","textInput","paste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"blur compositionend keydown keypress keyup mousedown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"blur compositionstart keydown keypress keyup mousedown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"blur compositionupdate keydown keypress keyup mousedown".split(" ")}},xe=!1;function Se(e,t){switch(e){case"keyup":return-1!==he.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"blur":return!0;default:return!1}}function _e(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var ke=!1;var Ee={eventTypes:we,extractEvents:function(e,t,n,r){var i=void 0,o=void 0;if(ve)e:{switch(e){case"compositionstart":i=we.compositionStart;break e;case"compositionend":i=we.compositionEnd;break e;case"compositionupdate":i=we.compositionUpdate;break e}i=void 0}else ke?Se(e,n)&&(i=we.compositionEnd):"keydown"===e&&229===n.keyCode&&(i=we.compositionStart);return i?(ge&&"ko"!==n.locale&&(ke||i!==we.compositionStart?i===we.compositionEnd&&ke&&(o=oe()):(re="value"in(ne=r)?ne.value:ne.textContent,ke=!0)),i=pe.getPooled(i,t,n,r),o?i.data=o:null!==(o=_e(n))&&(i.data=o),$(i),o=i):o=null,(e=me?function(e,t){switch(e){case"compositionend":return _e(t);case"keypress":return 32!==t.which?null:(xe=!0,be);case"textInput":return(e=t.data)===be&&xe?null:e;default:return null}}(e,n):function(e,t){if(ke)return"compositionend"===e||!ve&&Se(e,t)?(e=oe(),ie=re=ne=null,ke=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1