diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..95ef3e6 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +!/bin/.*.ts +!/tools/.*.ts \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index e5342a5..7414408 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,11 +3,12 @@ "es6": true, "node": true }, + "parser": "@typescript-eslint/parser", "parserOptions": { - "ecmaVersion": 8, - "sourceType": "module" + "project": "./tsconfig.json" }, - "extends": "eslint:recommended", + "plugins": ["@typescript-eslint"], + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier", "prettier/@typescript-eslint"], "rules": { "no-shadow": ["error", { "allow": ["err"] }], "handle-callback-err": "error", @@ -16,6 +17,8 @@ "consistent-return": ["error", {"treatUndefinedAsUnspecified": true}], "no-buffer-constructor": "error", "prefer-const": ["error", {"destructuring": "all"}], - "eqeqeq": ["error", "always", {"null": "ignore"}] + "eqeqeq": ["error", "always", {"null": "ignore"}], + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-use-before-define": ["error", { "functions": false }] } } diff --git a/.gitignore b/.gitignore index f16cfb6..5ab68ce 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ config/fs.key config/fs.crt config/fs.ca-bundle config/ext +bin/.*.ts +tools/.*.ts \ No newline at end of file diff --git a/.npmignore b/.npmignore index abca22c..c4a4602 100644 --- a/.npmignore +++ b/.npmignore @@ -17,4 +17,10 @@ config/ext debug/* !debug/.gitkeep +dist .eslintrc.json +.eslintignore +ava.config.js +tsconfig.json +bin/.* +tools/.* diff --git a/ava.config.js b/ava.config.js new file mode 100644 index 0000000..46f7c73 --- /dev/null +++ b/ava.config.js @@ -0,0 +1,6 @@ +export default { + "compileEnhancements": false, + "extensions": ["ts"], + "require": ["esm", "ts-node/register/transpile-only"] +}; + diff --git a/bin/genieacs-cwmp b/bin/genieacs-cwmp index 63fcbc6..8c5f01b 100755 --- a/bin/genieacs-cwmp +++ b/bin/genieacs-cwmp @@ -1,7 +1,6 @@ -#!/usr/bin/env -S node -r esm -"use strict"; -import path from "path"; -import fs from "fs"; +#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only +import * as path from "path"; +import * as fs from "fs"; process.chdir(path.resolve(path.dirname(fs.realpathSync(__filename)), "..")); @@ -13,7 +12,6 @@ import * as cwmp from "../lib/cwmp"; import * as db from "../lib/db"; import * as extensions from "../lib/extensions"; import * as cache from "../lib/cache"; - import { version as VERSION } from "../package.json"; logger.init("cwmp", VERSION); @@ -21,14 +19,14 @@ logger.init("cwmp", VERSION); const SERVICE_ADDRESS = config.get("CWMP_INTERFACE"); const SERVICE_PORT = config.get("CWMP_PORT"); -function exitWorkerGracefully() { +function exitWorkerGracefully(): void { db.disconnect(); cache.disconnect(); extensions.killAll(); cluster.worker.disconnect(); } -function exitWorkerUngracefully() { +function exitWorkerUngracefully(): void { extensions.killAll(() => { process.exit(1); }); @@ -66,14 +64,14 @@ if (!cluster.worker) { let ssl; if (config.get("CWMP_SSL")) { ssl = { - key: path.resolve(config.get("CONFIG_DIR"), "cwmp.key"), - cert: path.resolve(config.get("CONFIG_DIR"), "cwmp.crt"), - ca: path.resolve(config.get("CONFIG_DIR"), "cwmp.ca-bundle") + key: path.resolve("" + config.get("CONFIG_DIR"), "cwmp.key"), + cert: path.resolve("" + config.get("CONFIG_DIR"), "cwmp.crt"), + ca: path.resolve("" + config.get("CONFIG_DIR"), "cwmp.ca-bundle") }; } process.on("uncaughtException", err => { - if (err.code === "ERR_IPC_DISCONNECTED") return; + if ((err as NodeJS.ErrnoException).code === "ERR_IPC_DISCONNECTED") return; logger.error({ message: "Uncaught exception", exception: err, diff --git a/bin/genieacs-ext b/bin/genieacs-ext index 43cc772..92405e8 100755 --- a/bin/genieacs-ext +++ b/bin/genieacs-ext @@ -1,4 +1,5 @@ -#!/usr/bin/env -S node -r esm +#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only + /** * Copyright 2013-2018 Zaid Abdulla * @@ -17,18 +18,19 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; + +import { Fault } from "../lib/types"; const jobs = new Set(); const fileName = process.argv[2]; let script; -function errorToFault(err) { +function errorToFault(err: Error): Fault { if (!err) return null; if (!err.name) return { code: "ext", message: `${err}` }; - const fault = { + const fault: Fault = { code: `ext.${err.name}`, message: err.message, detail: { diff --git a/bin/genieacs-fs b/bin/genieacs-fs index a733826..1a268b4 100755 --- a/bin/genieacs-fs +++ b/bin/genieacs-fs @@ -1,7 +1,6 @@ -#!/usr/bin/env -S node -r esm -"use strict"; -import path from "path"; -import fs from "fs"; +#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only +import * as path from "path"; +import * as fs from "fs"; process.chdir(path.resolve(path.dirname(fs.realpathSync(__filename)), "..")); @@ -19,13 +18,13 @@ logger.init("fs", VERSION); const SERVICE_ADDRESS = config.get("FS_INTERFACE"); const SERVICE_PORT = config.get("FS_PORT"); -function exitWorkerGracefully() { +function exitWorkerGracefully(): void { db.disconnect(); cache.disconnect(); cluster.worker.disconnect(); } -function exitWorkerUngracefully() { +function exitWorkerUngracefully(): void { process.exit(1); } @@ -61,14 +60,14 @@ if (!cluster.worker) { let ssl; if (config.get("FS_SSL")) { ssl = { - key: path.resolve(config.get("CONFIG_DIR"), "fs.key"), - cert: path.resolve(config.get("CONFIG_DIR"), "fs.crt"), - ca: path.resolve(config.get("CONFIG_DIR"), "fs.ca-bundle") + key: path.resolve("" + config.get("CONFIG_DIR"), "fs.key"), + cert: path.resolve("" + config.get("CONFIG_DIR"), "fs.crt"), + ca: path.resolve("" + config.get("CONFIG_DIR"), "fs.ca-bundle") }; } process.on("uncaughtException", err => { - if (err.code === "ERR_IPC_DISCONNECTED") return; + if ((err as NodeJS.ErrnoException).code === "ERR_IPC_DISCONNECTED") return; logger.error({ message: "Uncaught exception", exception: err, diff --git a/bin/genieacs-nbi b/bin/genieacs-nbi index e1c4b7b..e737d1b 100755 --- a/bin/genieacs-nbi +++ b/bin/genieacs-nbi @@ -1,7 +1,6 @@ -#!/usr/bin/env -S node -r esm -"use strict"; -import path from "path"; -import fs from "fs"; +#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only +import * as path from "path"; +import * as fs from "fs"; process.chdir(path.resolve(path.dirname(fs.realpathSync(__filename)), "..")); @@ -20,14 +19,14 @@ logger.init("nbi", VERSION); const SERVICE_ADDRESS = config.get("NBI_INTERFACE"); const SERVICE_PORT = config.get("NBI_PORT"); -function exitWorkerGracefully() { +function exitWorkerGracefully(): void { db.disconnect(); cache.disconnect(); extensions.killAll(); cluster.worker.disconnect(); } -function exitWorkerUngracefully() { +function exitWorkerUngracefully(): void { extensions.killAll(() => { process.exit(1); }); @@ -65,14 +64,14 @@ if (!cluster.worker) { let ssl; if (config.get("NBI_SSL")) { ssl = { - key: path.resolve(config.get("CONFIG_DIR"), "nbi.key"), - cert: path.resolve(config.get("CONFIG_DIR"), "nbi.crt"), - ca: path.resolve(config.get("CONFIG_DIR"), "nbi.ca-bundle") + key: path.resolve("" + config.get("CONFIG_DIR"), "nbi.key"), + cert: path.resolve("" + config.get("CONFIG_DIR"), "nbi.crt"), + ca: path.resolve("" + config.get("CONFIG_DIR"), "nbi.ca-bundle") }; } process.on("uncaughtException", err => { - if (err.code === "ERR_IPC_DISCONNECTED") return; + if ((err as NodeJS.ErrnoException).code === "ERR_IPC_DISCONNECTED") return; logger.error({ message: "Uncaught exception", exception: err, diff --git a/bin/genieacs-ui b/bin/genieacs-ui index 221513d..88225de 100755 --- a/bin/genieacs-ui +++ b/bin/genieacs-ui @@ -1,5 +1,4 @@ -#!/usr/bin/env -S node -r esm -"use strict"; +#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only import * as path from "path"; import * as fs from "fs"; @@ -20,14 +19,14 @@ logger.init("ui", VERSION); const SERVICE_ADDRESS = config.get("UI_INTERFACE"); const SERVICE_PORT = config.get("UI_PORT"); -function exitWorkerGracefully() { +function exitWorkerGracefully(): void { db.disconnect(); db2.disconnect(); cache.disconnect(); cluster.worker.disconnect(); } -function exitWorkerUngracefully() { +function exitWorkerUngracefully(): void { process.exit(1); } @@ -63,16 +62,16 @@ if (!cluster.worker) { let ssl; if (config.get("UI_SSL")) { ssl = { - key: path.resolve(config.get("CONFIG_DIR"), "ui.key"), - cert: path.resolve(config.get("CONFIG_DIR"), "ui.crt"), - ca: path.resolve(config.get("CONFIG_DIR"), "ui.ca-bundle") + key: path.resolve("" + config.get("CONFIG_DIR"), "ui.key"), + cert: path.resolve("" + config.get("CONFIG_DIR"), "ui.crt"), + ca: path.resolve("" + config.get("CONFIG_DIR"), "ui.ca-bundle") }; } let stopping = false; process.on("uncaughtException", err => { - if (err.code === "ERR_IPC_DISCONNECTED") return; + if ((err as NodeJS.ErrnoException).code === "ERR_IPC_DISCONNECTED") return; logger.error({ message: "Uncaught exception", exception: err, @@ -101,7 +100,7 @@ if (!cluster.worker) { .catch(exitWorkerUngracefully); }); - const _listener = (req, res) => { + const _listener = (req, res): void => { if (stopping) res.setHeader("Connection", "close"); listener(req, res); }; diff --git a/build/build.js b/build/build.ts similarity index 75% rename from build/build.js rename to build/build.ts index 7e2e91f..23ccf12 100644 --- a/build/build.js +++ b/build/build.ts @@ -1,17 +1,18 @@ -const path = require("path"); -const fs = require("fs"); -const { promisify } = require("util"); -const { rollup } = require("rollup"); -const rollupReplace = require("rollup-plugin-replace"); -const rollupJson = require("rollup-plugin-json"); -const { terser } = require("rollup-plugin-terser"); -const webpack = require("webpack"); -const postcss = require("postcss"); -const postcssImport = require("postcss-import"); -const postcssCssNext = require("postcss-cssnext"); -const cssnano = require("cssnano"); +import * as path from "path"; +import * as fs from "fs"; +import { promisify } from "util"; +import { rollup, WarningHandler } from "rollup"; +import rollupReplace from "rollup-plugin-replace"; +import rollupJson from "rollup-plugin-json"; +import typescript from "rollup-plugin-typescript"; +import { terser } from "rollup-plugin-terser"; +import webpack from "webpack"; +import postcss from "postcss"; +import postcssImport from "postcss-import"; +import postcssCssNext from "postcss-cssnext"; +import cssnano from "cssnano"; -const MODE = "production"; +const MODE = process.env["NODE_ENV"] || "production"; const BUILD_METADATA = new Date() .toISOString() @@ -49,10 +50,12 @@ const externals = [ "jsonwebtoken", "stream", "mithril", - "parsimmon" + "parsimmon", + "codemirror", + "codemirror/mode/javascript/javascript" ]; -function rmDirSync(dirPath) { +function rmDirSync(dirPath): void { if (!fs.existsSync(dirPath)) return; const files = fs.readdirSync(dirPath); @@ -64,7 +67,7 @@ function rmDirSync(dirPath) { fs.rmdirSync(dirPath); } -async function init() { +async function init(): Promise { // Delete any old output directory rmDirSync(OUTPUT_DIR); @@ -77,7 +80,9 @@ async function init() { fs.mkdirSync(OUTPUT_DIR + "/tools"); // Create package.json - const packageJson = require("../package.json"); + const packageJson = JSON.parse( + fs.readFileSync(path.resolve(INPUT_DIR, "package.json")).toString() + ); delete packageJson["devDependencies"]; packageJson["scripts"] = { install: packageJson["scripts"].install, @@ -90,7 +95,7 @@ async function init() { ); } -async function copyStatic() { +async function copyStatic(): Promise { const files = [ "LICENSE", "README.md", @@ -111,7 +116,7 @@ async function copyStatic() { } } -async function generateCss() { +async function generateCss(): Promise { const cssInPath = path.resolve(INPUT_DIR, "ui/css/app.css"); const cssOutPath = path.resolve(OUTPUT_DIR, "public/app.css"); const cssIn = fs.readFileSync(cssInPath); @@ -123,7 +128,7 @@ async function generateCss() { fs.writeFileSync(cssOutPath, cssOut.css); } -async function generateToolsJs() { +async function generateToolsJs(): Promise { for (const bin of ["configure-ui", "dump-data-model"]) { const inputFile = path.resolve(INPUT_DIR, `tools/${bin}`); const outputFile = path.resolve(OUTPUT_DIR, `tools/${bin}`); @@ -136,7 +141,11 @@ async function generateToolsJs() { plugins: [ rollupReplace({ delimiters: ["", ""], - "#!/usr/bin/env -S node -r esm": "" + "#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only": "" + }), + typescript({ + tsconfig: "./tsconfig.json", + include: [`tools/${bin}`, "lib/**/*.ts"] }), MODE === "production" ? terser() : null ] @@ -155,7 +164,7 @@ async function generateToolsJs() { } } -async function generateBackendJs() { +async function generateBackendJs(): Promise { for (const bin of [ "genieacs-cwmp", "genieacs-ext", @@ -178,7 +187,7 @@ async function generateBackendJs() { plugins: [ rollupReplace({ delimiters: ["", ""], - "#!/usr/bin/env -S node -r esm": "" + "#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only": "" }), rollupJson({ preferConst: true }), { @@ -191,6 +200,10 @@ async function generateBackendJs() { return null; } }, + typescript({ + tsconfig: "./tsconfig.json", + include: [`bin/${bin}`, "lib/**/*.ts"] + }), MODE === "production" ? terser() : null ] }); @@ -208,23 +221,26 @@ async function generateBackendJs() { } } -async function generateFrontendJs() { - const inputFile = path.resolve(INPUT_DIR, "ui/app.js"); +async function generateFrontendJs(): Promise { + const inputFile = path.resolve(INPUT_DIR, "ui/app.ts"); const outputFile = path.resolve(OUTPUT_DIR, "public/app.js"); const bundle = await rollup({ input: inputFile, external: externals, - plugins: [rollupJson({ preferConst: true })], + plugins: [ + rollupJson({ preferConst: true }), + typescript({ tsconfig: "./tsconfig.json" }) + ], inlineDynamicImports: true, treeshake: { propertyReadSideEffects: false, pureExternalModules: true }, - onwarn: (warning, warn) => { + onwarn: ((warning, warn) => { // Ignore circular dependency warnings if (warning.code !== "CIRCULAR_DEPENDENCY") warn(warning); - } + }) as WarningHandler }); await bundle.write({ @@ -236,6 +252,9 @@ async function generateFrontendJs() { const webpackConf = { mode: MODE, entry: outputFile, + resolve: { + aliasFields: ["module"] + }, output: { path: path.resolve(OUTPUT_DIR, "public"), filename: "app.js" diff --git a/lib/api-functions.js b/lib/api-functions.ts similarity index 92% rename from lib/api-functions.js rename to lib/api-functions.ts index c438879..b925d9d 100644 --- a/lib/api-functions.js +++ b/lib/api-functions.ts @@ -16,19 +16,18 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -import crypto from "crypto"; -import dgram from "dgram"; -import URL from "url"; -import http from "http"; +import * as crypto from "crypto"; +import * as dgram from "dgram"; +import * as URL from "url"; +import * as http from "http"; import * as config from "./config"; import * as db from "./db"; import * as common from "./common"; import * as auth from "./auth"; import * as cache from "./cache"; -function udpConReq(address, un, key, callback) { +function udpConReq(address, un, key, callback): boolean { if (!address) return false; let [host, port] = address.split(":", 2); @@ -53,7 +52,9 @@ function udpConReq(address, un, key, callback) { ); const client = dgram.createSocket({ type: "udp4", reuseAddr: true }); - const UDP_CONNECTION_REQUEST_PORT = config.get("UDP_CONNECTION_REQUEST_PORT"); + const UDP_CONNECTION_REQUEST_PORT = +config.get( + "UDP_CONNECTION_REQUEST_PORT" + ); if (UDP_CONNECTION_REQUEST_PORT) // When a device is NAT'ed, the UDP Connection Request must originate from @@ -65,7 +66,7 @@ function udpConReq(address, un, key, callback) { client.bind({ port: UDP_CONNECTION_REQUEST_PORT, exclusive: true }); let count = 3; - const func = err => { + const func = (err: Error): void => { if (err || --count <= 0) { client.close(); return void callback(err); @@ -83,8 +84,8 @@ function httpConReq( allowBasicAuth, timeout, callback -) { - const options = URL.parse(url); +): void { + const options: http.RequestOptions = URL.parse(url); if (options.protocol !== "http:") { return void callback( new Error("Invalid connection request URL or protocol") @@ -92,7 +93,7 @@ function httpConReq( } options.agent = new http.Agent({ maxSockets: 1 }); - function statusToError(statusCode) { + function statusToError(statusCode): Error { switch (statusCode) { case 200: case 204: @@ -112,7 +113,7 @@ function httpConReq( const authHeader = auth.parseAuthHeader( response.headers["www-authenticate"] ); - if (authHeader.method === "Basic") { + if (authHeader["method"] === "Basic") { if (!allowBasicAuth) { request.abort(); return void callback( @@ -122,7 +123,7 @@ function httpConReq( options.headers = { Authorization: auth.basic(username || "", password || "") }; - } else if (authHeader.method === "Digest") { + } else if (authHeader["method"] === "Digest") { options.headers = { Authorization: auth.digest( username || "", @@ -187,7 +188,7 @@ function httpConReq( }); } -export function connectionRequest(deviceId, callback) { +export function connectionRequest(deviceId, callback): void { const CONNECTION_REQUEST_TIMEOUT = config.get( "CONNECTION_REQUEST_TIMEOUT", deviceId @@ -235,7 +236,7 @@ export function connectionRequest(deviceId, callback) { if (managementServer.ConnectionRequestPassword) password = managementServer.ConnectionRequestPassword._value; - const conReq = () => { + const conReq = (): void => { const udpSent = udpConReq( udpConnectionRequestAddress, username, @@ -284,7 +285,7 @@ export function connectionRequest(deviceId, callback) { }); } -export function watchTask(deviceId, taskId, timeout, callback) { +export function watchTask(deviceId, taskId, timeout, callback): void { setTimeout(() => { db.tasksCollection.findOne( { _id: taskId }, @@ -313,7 +314,7 @@ export function watchTask(deviceId, taskId, timeout, callback) { }, 500); } -function sanitizeTask(task, callback) { +function sanitizeTask(task, callback): void { task.timestamp = new Date(task.timestamp || Date.now()); if (task.expiry) { if (common.typeOf(task.expiry) === common.DATE_TYPE || isNaN(task.expiry)) @@ -324,7 +325,7 @@ function sanitizeTask(task, callback) { callback(task); } -export function insertTasks(tasks, callback) { +export function insertTasks(tasks, callback): void { if (tasks && common.typeOf(tasks) !== common.ARRAY_TYPE) tasks = [tasks]; else if (!tasks || tasks.length === 0) return void callback(null, tasks || []); @@ -344,7 +345,7 @@ export function insertTasks(tasks, callback) { } } -export function deleteDevice(deviceId, callback) { +export function deleteDevice(deviceId, callback): void { db.tasksCollection.deleteMany({ device: deviceId }, err => { if (err) return void callback(err); db.devicesCollection.deleteOne({ _id: deviceId }, err => { diff --git a/lib/auth.js b/lib/auth.ts similarity index 88% rename from lib/auth.js rename to lib/auth.ts index 9eec5c6..41728bc 100644 --- a/lib/auth.js +++ b/lib/auth.ts @@ -16,11 +16,10 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; import { createHash } from "crypto"; -export function parseAuthHeader(authHeader) { +export function parseAuthHeader(authHeader): {} { authHeader = authHeader.trim(); const method = authHeader.split(" ", 1)[0]; const res = { method: method }; @@ -53,11 +52,18 @@ export function parseAuthHeader(authHeader) { return res; } -export function basic(username, password) { +export function basic(username, password): string { return "Basic " + Buffer.from(`${username}:${password}`).toString("base64"); } -export function digest(username, password, uri, httpMethod, body, authHeader) { +export function digest( + username, + password, + uri, + httpMethod, + body, + authHeader +): string { const cnonce = "0a4f113b"; const nc = "00000001"; let qop; @@ -68,7 +74,7 @@ export function digest(username, password, uri, httpMethod, body, authHeader) { else qop = authHeader.qop; } - let ha1 = createHash("md5"); + const ha1 = createHash("md5"); ha1 .update(username) .update(":") @@ -76,19 +82,19 @@ export function digest(username, password, uri, httpMethod, body, authHeader) { .update(":") .update(password); // TODO support "MD5-sess" algorithm directive - ha1 = ha1.digest("hex"); + const ha1d = ha1.digest("hex"); - let ha2 = createHash("md5"); + const ha2 = createHash("md5"); ha2 .update(httpMethod) .update(":") .update(uri); if (qop === "auth-int") ha2.update(":").update(body); - ha2 = ha2.digest("hex"); + const ha2d = ha2.digest("hex"); const hash = createHash("md5"); hash - .update(ha1) + .update(ha1d) .update(":") .update(authHeader.nonce); if (qop) { @@ -100,7 +106,7 @@ export function digest(username, password, uri, httpMethod, body, authHeader) { .update(":") .update(qop); } - hash.update(":").update(ha2); + hash.update(":").update(ha2d); let authString = `Digest username="${username}"`; authString += `,realm="${authHeader.realm}"`; diff --git a/lib/cache.js b/lib/cache.ts similarity index 79% rename from lib/cache.js rename to lib/cache.ts index 64478c5..c9ec7c7 100644 --- a/lib/cache.js +++ b/lib/cache.ts @@ -16,19 +16,18 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; import { MongoClient } from "mongodb"; import * as config from "./config"; -const MAX_CACHE_TTL = config.get("MAX_CACHE_TTL"); +const MAX_CACHE_TTL = +config.get("MAX_CACHE_TTL"); let mongoClient; let mongoCollection; let mongoTimeOffset = 0; -export function connect(callback) { - const MONGODB_CONNECTION_URL = config.get("MONGODB_CONNECTION_URL"); +export function connect(callback): void { + const MONGODB_CONNECTION_URL = "" + config.get("MONGODB_CONNECTION_URL"); MongoClient.connect( MONGODB_CONNECTION_URL, @@ -51,11 +50,11 @@ export function connect(callback) { ); } -export function disconnect() { +export function disconnect(): void { if (mongoClient) mongoClient.close(); } -export function get(key, callback) { +export function get(key, callback): void { const expire = new Date(Date.now() - mongoTimeOffset); if (Array.isArray(key)) { mongoCollection.find({ _id: { $in: key } }).toArray((err, res) => { @@ -83,21 +82,39 @@ export function get(key, callback) { } } -export function del(key, callback) { +export function del(key, callback): void { if (Array.isArray(key)) mongoCollection.deleteMany({ _id: { $in: key } }, callback); else mongoCollection.deleteOne({ _id: key }, callback); } -export function set(key, value, ttl, callback) { - if (!callback && typeof v === "function") { +export function set( + key: string, + value: string | number, + callback: (err?: Error) => void +): void; +export function set( + key: string, + value: string | number, + ttl: number, + callback: (err?: Error) => void +): void; +export function set( + key: string, + value: string | number, + ttl: number | ((err?: Error) => void), + callback?: (err?: Error) => void +): void { + if (!callback && typeof ttl === "function") { callback = ttl; ttl = null; } if (!ttl) ttl = MAX_CACHE_TTL; - const expire = new Date(Date.now() - mongoTimeOffset + ttl * 1000); + const expire = new Date( + Date.now() - mongoTimeOffset + (ttl as number) * 1000 + ); mongoCollection.replaceOne( { _id: key }, { _id: key, value: value, expire: expire }, @@ -106,7 +123,7 @@ export function set(key, value, ttl, callback) { ); } -export function pop(key, callback) { +export function pop(key, callback): void { mongoCollection.findOneAndDelete({ _id: key }, (err, res) => { if (err || !res["value"]) return void callback(err); @@ -117,12 +134,12 @@ export function pop(key, callback) { }); } -export function lock(lockName, ttl, callback) { +export function lock(lockName, ttl, callback): void { const token = Math.random() .toString(36) .slice(2); - function unlockOrExtend(extendTtl) { + function unlockOrExtend(extendTtl): void { if (!extendTtl) { mongoCollection.deleteOne({ _id: lockName, value: token }, (err, res) => { if (err || res["result"]["n"] !== 1) @@ -135,7 +152,7 @@ export function lock(lockName, ttl, callback) { { expire: expire }, (err, res) => { if (err || res["result"]["n"] !== 1) - throw err | new Error("Lock expired"); + throw err || new Error("Lock expired"); } ); } diff --git a/lib/cluster.js b/lib/cluster.ts similarity index 91% rename from lib/cluster.js rename to lib/cluster.ts index 63647f8..c26f02d 100644 --- a/lib/cluster.js +++ b/lib/cluster.ts @@ -16,7 +16,6 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; import cluster from "cluster"; import { cpus } from "os"; @@ -25,10 +24,12 @@ import * as logger from "./logger"; let respawnTimestamp = 0; let tooManyCrashesTimestamp = 0; -function restartWorker(worker, code, signal) { +function restartWorker(worker, code, signal): void { const msg = { message: "Worker died", - pid: worker.process.pid + pid: worker.process.pid, + exitCode: null, + signal: null }; if (code != null) msg.exitCode = code; @@ -63,7 +64,7 @@ function restartWorker(worker, code, signal) { }, respawnTimestamp - now); } -export function start(workerCount, servicePort, serviceAddress) { +export function start(workerCount, servicePort, serviceAddress): void { cluster.on("listening", (worker, address) => { if ( (address.addressType === 4 || address.addressType === 6) && @@ -86,7 +87,7 @@ export function start(workerCount, servicePort, serviceAddress) { for (let i = 0; i < workerCount; ++i) cluster.fork(); } -export function stop() { +export function stop(): void { cluster.removeListener("exit", restartWorker); for (const pid in cluster.workers) cluster.workers[pid].kill(); } diff --git a/lib/common.js b/lib/common.ts similarity index 87% rename from lib/common.js rename to lib/common.ts index e94e145..23e9865 100644 --- a/lib/common.js +++ b/lib/common.ts @@ -16,7 +16,8 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; + +import { ParamPath } from "./types"; export const UNDEFINED_TYPE = "[object Undefined]"; export const NULL_TYPE = "[object Null]"; @@ -28,11 +29,11 @@ export const OBJECT_TYPE = "[object Object]"; export const REGEXP_TYPE = "[object RegExp]"; export const DATE_TYPE = "[object Date]"; -export const typeOf = obj => Object.prototype.toString.call(obj); +export const typeOf = (obj): string => Object.prototype.toString.call(obj); -export function generateDeviceId(deviceIdStruct) { +export function generateDeviceId(deviceIdStruct): string { // Escapes everything except alphanumerics and underscore - function esc(str) { + function esc(str): string { return str.replace(/[^A-Za-z0-9_]/g, chr => { const buf = Buffer.from(chr, "utf8"); let rep = ""; @@ -54,11 +55,12 @@ export function generateDeviceId(deviceIdStruct) { return esc(deviceIdStruct["OUI"]) + "-" + esc(deviceIdStruct["SerialNumber"]); } -export function parseAlias(pattern, start, res) { +export function parseAlias(pattern, start, res): number { const aliases = []; let i = start; while (i < pattern.length && pattern[i] !== "]") { const alias = []; + /* eslint-disable-next-line @typescript-eslint/no-use-before-define */ let j = (i = parsePath(pattern, i, alias) + 1); while (pattern[j] !== "]" && pattern[j] !== ",") { if (pattern[j] === '"' && i === j) { @@ -87,7 +89,7 @@ export function parseAlias(pattern, start, res) { } // Sort to ensure identical expressions have idential string representation - function srt(a, b) { + function srt(a, b): number { const jMax = Math.min(a.length, b.length); for (let j = 0; j < jMax; j += 2) { const kMax = Math.min(a[j].length, b[j].length); @@ -126,8 +128,11 @@ export function parseAlias(pattern, start, res) { return i; } -export function parsePath(pattern, start, res) { - const path = []; +/* eslint-disable @typescript-eslint/no-use-before-define */ +export function parsePath(pattern, start, res): number; +export function parsePath(pattern, start?): ParamPath; +export function parsePath(pattern, start?, res?): number | ParamPath { + const path = [] as ParamPath; path.wildcard = 0; path.alias = 0; let i = start || 0; @@ -163,7 +168,7 @@ export function parsePath(pattern, start, res) { return i; } -export function addPathMeta(path) { +export function addPathMeta(path): ParamPath { if (path.alias != null && path.wildcard != null) return path; path.alias = 0; @@ -183,6 +188,6 @@ export function addPathMeta(path) { } // Source: http://stackoverflow.com/a/6969486 -export function escapeRegExp(str) { +export function escapeRegExp(str): string { return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"); } diff --git a/lib/common/authorizer.js b/lib/common/authorizer.ts similarity index 68% rename from lib/common/authorizer.js rename to lib/common/authorizer.ts index b12f64f..6091aba 100644 --- a/lib/common/authorizer.js +++ b/lib/common/authorizer.ts @@ -1,20 +1,27 @@ -"use strict"; - import pass from "./validators/pass"; import test from "./validators/test"; +import { PermissionSet } from "../types"; const validators = { pass, test }; export default class Authorizer { - constructor(permissionSets) { + private permissionSets: PermissionSet[]; + private validatorCache: WeakMap< + object, + (mutationType, mutation, any) => boolean + >; + private hasAccessCache: Map; + + public constructor(permissionSets) { this.permissionSets = permissionSets; this.validatorCache = new WeakMap(); - this.hasAccessCache = {}; + this.hasAccessCache = new Map(); } - hasAccess(resourceType, access) { + public hasAccess(resourceType, access): boolean { const cacheKey = `${resourceType}-${access}`; - if (cacheKey in this.hasAccessCache) return this.hasAccessCache[cacheKey]; + if (this.hasAccessCache.has(cacheKey)) + return this.hasAccessCache.get(cacheKey); let has = false; for (const permissionSet of this.permissionSets) { @@ -28,11 +35,14 @@ export default class Authorizer { } } - this.hasAccessCache[cacheKey] = has; + this.hasAccessCache.set(cacheKey, has); return has; } - getValidator(resourceType, resource) { + public getValidator( + resourceType, + resource + ): (mutationType: string, mutation: any, args: any) => boolean { if (this.validatorCache.has(resource)) return this.validatorCache.get(resource); @@ -53,7 +63,11 @@ export default class Authorizer { } } - const validator = (mutationType, mutation, any) => { + const validator = ( + mutationType: string, + mutation: any, + any: any + ): boolean => { let valid = false; for (const [k, v] of Object.entries(funcs)) { if (v) { diff --git a/lib/common/expression-cnf.js b/lib/common/expression-cnf.ts similarity index 86% rename from lib/common/expression-cnf.js rename to lib/common/expression-cnf.ts index a38b483..43f80ad 100644 --- a/lib/common/expression-cnf.js +++ b/lib/common/expression-cnf.ts @@ -1,8 +1,9 @@ -"use strict"; - import { map, parseLikePattern } from "./expression-parser"; +import { Expression } from "../types"; -function or(cnf1, cnf2) { +type CNF = number[][]; + +function or(cnf1: CNF, cnf2: CNF): CNF { if (cnf1.length === 0) return cnf2; else if (cnf2.length === 0) return cnf1; @@ -19,7 +20,30 @@ function or(cnf1, cnf2) { return res; } -export function booleanCnf(exp) { +function likePatternIncludes(pat1, pat2, idx1 = 0, idx2 = 0): boolean { + while (idx1 < pat1.length && idx2 < pat2.length) { + if (pat1[idx1] === "\\%") { + for (let i = idx2; i <= pat2.length; ++i) + if (likePatternIncludes(pat1, pat2, idx1 + 1, i)) return true; + return false; + } else if (pat2[idx2] === "\\%") { + if (pat1[idx1] !== "\\%") return false; + } else if (pat1[idx1] === "\\_") { + // Ignore + } else if (pat2[idx2] === "\\_") { + return false; + } else if (pat2[idx2] !== pat1[idx1]) { + return false; + } + ++idx1; + ++idx2; + } + + if (idx1 === pat1.length && idx2 === pat2.length) return true; + return false; +} + +export function booleanCnf(exp: Expression): { vars: number; clauses: CNF } { const ranges = new Map(); const likePatterns = new Map(); map(exp, e => { @@ -51,15 +75,20 @@ export function booleanCnf(exp) { }); for (const [k, v] of ranges) { - if (k.endsWith(":number")) - ranges.set(k, Array.from(v).sort((a, b) => a - b)); - else ranges.set(k, Array.from(v).sort()); + if (k.endsWith(":number")) { + ranges.set( + k, + Array.from(v as number[]).sort((a: number, b: number) => a - b) + ); + } else { + ranges.set(k, Array.from(v).sort()); + } } - const expressions = new Map(); - const mutuallyExclusive = new Map(); + const expressions: Map = new Map(); + const mutuallyExclusive: Map> = new Map(); - function getVariable(lhs, op, rhs = "") { + function getVariable(lhs, op, rhs = ""): number { const key = `${lhs}:${op}:${rhs}`; let f = expressions.get(key); if (!f) { @@ -72,7 +101,13 @@ export function booleanCnf(exp) { return f; } - function getComparisonVariables(lhs, from, fromInclusive, to, toInclusive) { + function getComparisonVariables( + lhs, + from, + fromInclusive, + to, + toInclusive + ): number[] { const type = from != null ? typeof from : typeof to; const range = ranges.get(`${lhs}:${type}`); const vars = []; @@ -109,7 +144,7 @@ export function booleanCnf(exp) { }); } - function getLikeVariables(lhs, pat, esc) { + function getLikeVariables(lhs, pat, esc): number[] { const vars = []; const pats = likePatterns.get(lhs); pat = pats.get(`${esc || ""}:${pat}`); @@ -125,7 +160,11 @@ export function booleanCnf(exp) { }); } - const comparisonOperators = { + interface ComparisonOperators { + [name: string]: (v: string) => [string, boolean, string, boolean]; + } + + const comparisonOperators: ComparisonOperators = { "=": v => [v, true, v, true], ">": v => [v, false, null, null], ">=": v => [v, true, null, null], @@ -133,7 +172,7 @@ export function booleanCnf(exp) { "<=": v => [null, null, v, true] }; - function recursive(clause, negate) { + function recursive(clause, negate): CNF { let op = clause[0]; if ((op === "AND" && !negate) || (op === "OR" && negate)) { @@ -218,33 +257,10 @@ export function booleanCnf(exp) { const cnf = recursive(exp, false); for (const m of mutuallyExclusive.values()) { - const ar = Array.from(m); + const ar: number[] = Array.from(m); for (let i = 0; i < ar.length; ++i) for (let j = i + 1; j < ar.length; ++j) cnf.push([0 - ar[i], 0 - ar[j]]); } return { vars: expressions.size, clauses: cnf }; } - -function likePatternIncludes(pat1, pat2, idx1 = 0, idx2 = 0) { - while (idx1 < pat1.length && idx2 < pat2.length) { - if (pat1[idx1] === "\\%") { - for (let i = idx2; i <= pat2.length; ++i) - if (likePatternIncludes(pat1, pat2, idx1 + 1, i)) return true; - return false; - } else if (pat2[idx2] === "\\%") { - if (pat1[idx1] !== "\\%") return false; - } else if (pat1[idx1] === "\\_") { - // Ignore - } else if (pat2[idx2] === "\\_") { - return false; - } else if (pat2[idx2] !== pat1[idx1]) { - return false; - } - ++idx1; - ++idx2; - } - - if (idx1 === pat1.length && idx2 === pat2.length) return true; - return false; -} diff --git a/lib/common/expression-parser.js b/lib/common/expression-parser.ts similarity index 94% rename from lib/common/expression-parser.js rename to lib/common/expression-parser.ts index 964d9d0..4da1afa 100644 --- a/lib/common/expression-parser.js +++ b/lib/common/expression-parser.ts @@ -1,9 +1,8 @@ -"use strict"; - -import parsimmon from "parsimmon"; +import * as parsimmon from "parsimmon"; +import { Expression } from "../types"; // Turn escaped characters into real ones (e.g. "\\n" becomes "\n"). -function interpretEscapes(str) { +function interpretEscapes(str): string { const escapes = { b: "\b", f: "\f", @@ -22,7 +21,7 @@ function interpretEscapes(str) { }); } -export function map(exp, callback) { +export function map(exp, callback): Expression { if (!Array.isArray(exp)) return callback(exp); let clone; @@ -37,7 +36,7 @@ export function map(exp, callback) { return callback(clone || exp); } -function binaryLeft(operatorsParser, nextParser) { +function binaryLeft(operatorsParser, nextParser): parsimmon.Parser<{}> { return parsimmon.seqMap( nextParser, parsimmon.seq(operatorsParser, nextParser).many(), @@ -257,7 +256,7 @@ const lang = parsimmon.createLanguage({ ); }, Expression: function(r) { - function unary(operatorsParser, nextParser) { + function unary(operatorsParser, nextParser): parsimmon.Parser<{}> { return parsimmon.seq(operatorsParser, nextParser).or(nextParser); } @@ -271,12 +270,12 @@ const lang = parsimmon.createLanguage({ } }); -export function parse(str) { +export function parse(str): Expression { if (!str) return null; return lang.Expression.tryParse(str); } -export function stringify(exp, level = 0) { +export function stringify(exp, level = 0): string { if (!Array.isArray(exp)) return JSON.stringify(exp); const opLevels = { @@ -302,7 +301,7 @@ export function stringify(exp, level = 0) { const op = exp[0].toUpperCase(); - function wrap(e) { + function wrap(e): string { if (opLevels[op] <= level) return `(${e})`; else return e; } @@ -360,7 +359,7 @@ export function stringify(exp, level = 0) { } } -export function parseLikePattern(pat, esc) { +export function parseLikePattern(pat, esc): string[] { const chars = pat.split(""); for (let i = 0; i < chars.length; ++i) { diff --git a/lib/common/expression.js b/lib/common/expression.ts similarity index 89% rename from lib/common/expression.js rename to lib/common/expression.ts index df0fc29..d2611e4 100644 --- a/lib/common/expression.js +++ b/lib/common/expression.ts @@ -1,15 +1,14 @@ -"use strict"; - import { map, parseLikePattern } from "./expression-parser"; import { booleanCnf } from "./expression-cnf"; import { naiveDpll } from "./sat-solver"; +import { Expression } from "../types"; const isArray = Array.isArray; const regExpCache = new WeakMap(); const REDUCE_SKIP = {}; -function reduce(exp, callback) { +function reduce(exp, callback): Expression { let loop = true; while (loop) { loop = false; @@ -26,8 +25,45 @@ function reduce(exp, callback) { return exp; } -export function evaluate(exp, obj, now, cb) { - function getRegExp(pat, esc) { +export function likePatternToRegExp(pat, esc = "", flags = ""): RegExp { + const convChars = { + "-": "\\-", + "/": "\\/", + "\\": "\\/", + "^": "\\^", + $: "\\$", + "*": "\\*", + "+": "\\+", + "?": "\\?", + ".": "\\.", + "(": "\\(", + ")": "\\)", + "|": "\\|", + "[": "\\[", + "]": "\\]", + "{": "\\{", + "}": "\\}", + "\\%": ".*", + "\\_": "." + }; + let chars = parseLikePattern(pat, esc); + if (!chars.length) return new RegExp("^$", flags); + chars = chars.map(c => convChars[c] || c); + chars[0] = chars[0] === ".*" ? "" : "^" + chars[0]; + const l = chars.length - 1; + chars[l] = [".*", ""].includes(chars[l]) ? "" : chars[l] + "$"; + return new RegExp(chars.join(""), flags); +} + +export function evaluate( + exp, + obj, + now: number, + cb?: Function +): string | number | boolean | null; +export function evaluate(exp, obj?, now?: number, cb?: Function): Expression; +export function evaluate(exp, obj?, now?: number, cb?: Function): Expression { + function getRegExp(pat, esc): RegExp { const k = `${esc || ""}:${pat}`; let c = regExpCache.get(exp); if (!c) regExpCache.set(exp, (c = {})); @@ -162,11 +198,11 @@ export function evaluate(exp, obj, now, cb) { }); } -export function and(exp1, exp2) { +export function and(exp1, exp2): Expression { if (!isArray(exp1)) return exp1 ? exp2 : exp1; if (!isArray(exp2)) return exp2 ? exp1 : exp2; - let res = ["AND"]; + let res: Expression = ["AND"]; if (exp1[0] === "AND") res = res.concat(exp1.slice(1)); else res.push(exp1); @@ -177,11 +213,11 @@ export function and(exp1, exp2) { return res; } -export function or(exp1, exp2) { +export function or(exp1, exp2): Expression { if (!isArray(exp1)) return exp1 ? exp1 : exp2; if (!isArray(exp2)) return exp2 ? exp2 : exp1; - let res = ["OR"]; + let res: Expression = ["OR"]; if (exp1[0] === "OR") res = res.concat(exp1.slice(1)); else res.push(exp1); @@ -192,49 +228,19 @@ export function or(exp1, exp2) { return res; } -export function not(exp) { +export function not(exp): Expression { if (isArray(exp) && exp[0] === "NOT") return exp[1]; return ["NOT", exp]; } -export function subset(exp1, exp2) { +export function subset(exp1, exp2): boolean { const e = evaluate(["NOT", ["OR", ["NOT", exp1], exp2]]); if (!isArray(e)) return !e; const { vars, clauses } = booleanCnf(e); return !naiveDpll(clauses, vars); } -export function likePatternToRegExp(pat, esc = "", flags = "") { - const convChars = { - "-": "\\-", - "/": "\\/", - "\\": "\\/", - "^": "\\^", - $: "\\$", - "*": "\\*", - "+": "\\+", - "?": "\\?", - ".": "\\.", - "(": "\\(", - ")": "\\)", - "|": "\\|", - "[": "\\[", - "]": "\\]", - "{": "\\{", - "}": "\\}", - "\\%": ".*", - "\\_": "." - }; - let chars = parseLikePattern(pat, esc); - if (!chars.length) return new RegExp("^$", flags); - chars = chars.map(c => convChars[c] || c); - chars[0] = chars[0] === ".*" ? "" : "^" + chars[0]; - const l = chars.length - 1; - chars[l] = [".*", ""].includes(chars[l]) ? "" : chars[l] + "$"; - return new RegExp(chars.join(""), flags); -} - -export function extractParams(exp) { +export function extractParams(exp): string[] { const params = new Set(); map(exp, e => { if (isArray(e) && e[0] === "PARAM") params.add(e[1]); diff --git a/lib/common/memoize.js b/lib/common/memoize.ts similarity index 92% rename from lib/common/memoize.js rename to lib/common/memoize.ts index 20c0f7e..f7d984e 100644 --- a/lib/common/memoize.js +++ b/lib/common/memoize.ts @@ -1,10 +1,8 @@ -"use strict"; - let cache1 = new Map(); let cache2 = new Map(); const keys = new WeakMap(); -function getKey(obj) { +function getKey(obj): string { if (obj === null) return "null"; else if (obj === undefined) return "undefined"; @@ -22,7 +20,7 @@ function getKey(obj) { return k; } -export default function memoize(func) { +export default function memoize(func): Function { return (...args) => { const key = JSON.stringify(args.map(getKey)) + getKey(func); diff --git a/lib/common/sat-solver.js b/lib/common/sat-solver.ts similarity index 95% rename from lib/common/sat-solver.js rename to lib/common/sat-solver.ts index a18ea29..0e94062 100644 --- a/lib/common/sat-solver.js +++ b/lib/common/sat-solver.ts @@ -14,9 +14,10 @@ * The code is very similar to the pure table solver, except we use a * unit-propagating, derived-varlist-returing satisfiableAt. */ -"use strict"; -function satisfiableAt(clauses, varVals, varnr, val) { +/* eslint-disable @typescript-eslint/no-use-before-define */ + +function satisfiableAt(clauses, varVals, varnr, val): boolean { if (varnr !== 0) varVals[varnr] = val; const propRes = unitPropagate(clauses, varVals); @@ -87,7 +88,7 @@ function satisfiableAt(clauses, varVals, varnr, val) { * undetermined. The values of variables on the list will be restored (set to * 0) during backtracking. */ -function unitPropagate(clauses, varVals) { +function unitPropagate(clauses, varVals): number[] | 1 | -1 { // all vars with a value derived in the forthcoming main loop const derivedVars = []; @@ -167,7 +168,7 @@ function unitPropagate(clauses, varVals) { return derivedVars; } -export function naiveDpll(clauses, maxvarnr) { +export function naiveDpll(clauses, maxvarnr): boolean { // variable values are 0 if not set, 1 if positive, -1 if negative const varVals = new Int32Array(maxvarnr + 1); return satisfiableAt(clauses, varVals, 0, 0); diff --git a/lib/common/validators/pass.js b/lib/common/validators/pass.js deleted file mode 100644 index 5bc45c2..0000000 --- a/lib/common/validators/pass.js +++ /dev/null @@ -1,3 +0,0 @@ -export default function pass() { - return 1; -} diff --git a/lib/common/validators/pass.ts b/lib/common/validators/pass.ts new file mode 100644 index 0000000..f532102 --- /dev/null +++ b/lib/common/validators/pass.ts @@ -0,0 +1,3 @@ +export default function pass(): number { + return 1; +} diff --git a/lib/common/validators/test.js b/lib/common/validators/test.ts similarity index 85% rename from lib/common/validators/test.js rename to lib/common/validators/test.ts index 7467371..0732976 100644 --- a/lib/common/validators/test.js +++ b/lib/common/validators/test.ts @@ -1,4 +1,4 @@ -export default function test(resourceType, resource) { +export default function test(resourceType, resource): number { if (resourceType === "devices") { if (resource["Tags.test"] && resource["Tags.test"].value[0]) return 1; } else if (resourceType === "presets") { diff --git a/lib/config.js b/lib/config.ts similarity index 93% rename from lib/config.js rename to lib/config.ts index c5fa3e2..511f12f 100644 --- a/lib/config.js +++ b/lib/config.ts @@ -16,7 +16,6 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; import { resolve } from "path"; import { readFileSync } from "fs"; @@ -90,9 +89,9 @@ const options = { DEVICE_ONLINE_THRESHOLD: { type: "int", default: 4000 } }; -const allConfig = {}; +const allConfig: { [name: string]: string | number } = {}; -function setConfig(name, value, commandLineArgument) { +function setConfig(name, value, commandLineArgument = false): boolean { if (allConfig[name] != null) return true; // For compatibility with v1.0 @@ -119,7 +118,7 @@ function setConfig(name, value, commandLineArgument) { if (name === "FS_IP" || name === "fs-ip") setConfig("FS_HOSTNAME", value); - function cast(val, type) { + function cast(val, type): string | number | boolean { switch (type) { case "int": return Number(val); @@ -182,7 +181,9 @@ setConfig("CONFIG_DIR", options["CONFIG_DIR"]["default"]); // Configuration file const configFile = JSON.parse( - readFileSync(resolve(allConfig.CONFIG_DIR, "config.json")) + readFileSync( + resolve(allConfig.CONFIG_DIR as string, "config.json") + ).toString() ); for (const [k, v] of Object.entries(configFile)) { if (!setConfig(k, v)) @@ -194,7 +195,10 @@ for (const [k, v] of Object.entries(configFile)) { for (const [k, v] of Object.entries(options)) if (v["default"] != null) setConfig(k, v["default"]); -export function get(optionName, deviceId) { +export function get( + optionName: string, + deviceId?: string +): string | number | boolean { if (!deviceId) return allConfig[optionName]; optionName = `${optionName}-${deviceId}`; @@ -222,7 +226,7 @@ export function get(optionName, deviceId) { return null; } -export function getDefault(optionName) { +export function getDefault(optionName): string | number | boolean { const option = options[optionName]; if (!option) return null; @@ -235,7 +239,7 @@ export function getDefault(optionName) { export let auth; // Load authentication scripts try { - auth = require(resolve(allConfig.CONFIG_DIR, "auth.js")); + auth = require(resolve(allConfig.CONFIG_DIR as string, "auth.js")); } catch (error) { // No auth.js exists } diff --git a/lib/cwmp.js b/lib/cwmp.ts similarity index 92% rename from lib/cwmp.js rename to lib/cwmp.ts index b92272f..06d6aa2 100644 --- a/lib/cwmp.js +++ b/lib/cwmp.ts @@ -16,11 +16,11 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -import zlib from "zlib"; -import crypto from "crypto"; -import fs from "fs"; +import * as zlib from "zlib"; +import * as crypto from "crypto"; +import * as fs from "fs"; +import { Socket } from "net"; import * as config from "./config"; import * as common from "./common"; import * as soap from "./soap"; @@ -32,9 +32,19 @@ import * as localCache from "./local-cache"; import * as db from "./db"; import * as logger from "./logger"; import * as scheduling from "./scheduling"; +import { + SessionContext, + ParamPath, + AcsRequest, + SetAcsRequest, + SessionFault, + Operation +} from "./types"; const MAX_CYCLES = 4; -const MAX_CONCURRENT_REQUESTS = config.get("MAX_CONCURRENT_REQUESTS"); +const MAX_CONCURRENT_REQUESTS = +config.get("MAX_CONCURRENT_REQUESTS"); + +const currentSessions = new WeakMap(); const stats = { concurrentRequests: 0, @@ -43,7 +53,7 @@ const stats = { initiatedSessions: 0 }; -function throwError(err, httpResponse) { +function throwError(err, httpResponse?): never { if (httpResponse) { currentSessions.delete(httpResponse.connection); httpResponse.writeHead(500, { Connection: "close" }); @@ -53,7 +63,11 @@ function throwError(err, httpResponse) { throw err; } -function writeResponse(sessionContext, res, close) { +function writeResponse( + sessionContext: SessionContext, + res, + close = false +): void { // Close connection after last request in session if (close) res.headers["Connection"] = "close"; @@ -69,7 +83,7 @@ function writeResponse(sessionContext, res, close) { }); } - function finish() { + function finish(): void { stats.concurrentRequests -= 1; if (sessionContext.httpRequest.connection.destroyed) { logger.accessError({ @@ -130,7 +144,9 @@ function writeResponse(sessionContext, res, close) { } } -function recordFault(sessionContext, fault, provisions, channels) { +function recordFault(sessionContext, fault, provisions, channels): void; +function recordFault(sessionContext, fault): void; +function recordFault(sessionContext, fault, provisions?, channels?): void { if (!provisions) { provisions = sessionContext.provisions; channels = sessionContext.channels; @@ -185,7 +201,7 @@ function recordFault(sessionContext, fault, provisions, channels) { session.clearProvisions(sessionContext); } -function inform(sessionContext, rpc) { +function inform(sessionContext, rpc): void { session.inform(sessionContext, rpc.cpeRequest, (err, acsResponse) => { if (err) return void throwError(err, sessionContext.httpResponse); @@ -213,7 +229,7 @@ function inform(sessionContext, rpc) { }); } -function transferComplete(sessionContext, rpc) { +function transferComplete(sessionContext, rpc): void { session.transferComplete( sessionContext, rpc.cpeRequest, @@ -250,7 +266,7 @@ function transferComplete(sessionContext, rpc) { } // Append providions and remove duplicates -function appendProvisions(original, toAppend) { +function appendProvisions(original, toAppend): boolean { let modified = false; const stringified = new WeakMap(); @@ -281,7 +297,7 @@ function appendProvisions(original, toAppend) { return modified; } -function applyPresets(sessionContext) { +function applyPresets(sessionContext: SessionContext): void { const deviceData = sessionContext.deviceData; const presets = localCache.getPresets(sessionContext.cacheSnapshot); @@ -289,7 +305,7 @@ function applyPresets(sessionContext) { const blackList = {}; let whiteList = null; let whiteListProvisions = null; - const RETRY_DELAY = localCache.getConfig( + const RETRY_DELAY = +localCache.getConfig( sessionContext.cacheSnapshot, "cwmp.retryDelay", sessionContext.configContext @@ -318,13 +334,17 @@ function applyPresets(sessionContext) { deviceData.attributes.revision = 1; const deviceEvents = {}; - for (const p of deviceData.paths.find(["Events", "*"], false, true)) { + for (const p of deviceData.paths.find( + ["Events", "*"] as ParamPath, + false, + true + )) { const attrs = deviceData.attributes.get(p); if (attrs && attrs.value && attrs.value[1][0] >= sessionContext.timestamp) deviceEvents[p[1]] = true; } - const parameters = {}; + const parameters: { [name: string]: ParamPath } = {}; const filteredPresets = []; for (const preset of presets) { @@ -478,7 +498,7 @@ function applyPresets(sessionContext) { ); } -function nextRpc(sessionContext) { +function nextRpc(sessionContext: SessionContext): void { session.rpcRequest(sessionContext, null, (err, fault, id, acsRequest) => { if (err) return void throwError(err, sessionContext.httpResponse); @@ -604,7 +624,7 @@ function nextRpc(sessionContext) { }); } -function endSession(sessionContext, callback) { +function endSession(sessionContext: SessionContext, callback): void { let saveCache = sessionContext.cacheUntil != null; let counter = 3; @@ -714,24 +734,29 @@ function endSession(sessionContext, callback) { if ((counter -= 2) === 1) callback(null, sessionContext.new); } -function sendAcsRequest(sessionContext, id, acsRequest) { +function sendAcsRequest( + sessionContext: SessionContext, + id?: string, + acsRequest?: AcsRequest +): void { if (!acsRequest) return void writeResponse(sessionContext, soap.response(null), true); if (acsRequest.name === "Download") { - acsRequest.fileSize = 0; - if (!acsRequest.url) { + const downloadRequest = acsRequest as SetAcsRequest; + downloadRequest.fileSize = 0; + if (!downloadRequest.url) { const FS_PORT = config.get("FS_PORT"); const FS_HOSTNAME = config.get("FS_HOSTNAME"); const FS_SSL = config.get("FS_SSL"); - acsRequest.url = FS_SSL ? "https://" : "http://"; - acsRequest.url += FS_HOSTNAME; - if (FS_PORT !== 80) acsRequest.url += ":" + FS_PORT; - acsRequest.url += "/" + encodeURI(acsRequest.fileName); + downloadRequest.url = FS_SSL ? "https://" : "http://"; + downloadRequest.url += FS_HOSTNAME; + if (FS_PORT !== 80) downloadRequest.url += ":" + FS_PORT; + downloadRequest.url += "/" + encodeURI(downloadRequest.fileName); const files = localCache.getFiles(sessionContext.cacheSnapshot); - if (files[acsRequest.fileName]) - acsRequest.fileSize = files[acsRequest.fileName].length; + if (files[downloadRequest.fileName]) + downloadRequest.fileSize = files[downloadRequest.fileName].length; } } @@ -751,7 +776,11 @@ function sendAcsRequest(sessionContext, id, acsRequest) { writeResponse(sessionContext, res); } -function getSession(connection, sessionId, callback) { +function getSession( + connection, + sessionId, + callback: (err?: Error, sessionContext?: SessionContext) => void +): void { const sessionContext = currentSessions.get(connection); if (sessionContext) { currentSessions.delete(connection); @@ -768,10 +797,8 @@ function getSession(connection, sessionId, callback) { }, 100); } -const currentSessions = new WeakMap(); - // When socket closes, store active sessions in cache -export function onConnection(socket) { +export function onConnection(socket): void { // The property remoteAddress may be undefined after the connection is // closed, unless we read it at least once (caching?) socket.remoteAddress; @@ -840,7 +867,29 @@ setInterval(() => { stats.initiatedSessions = 0; }, 10000).unref(); -function getDueTasksAndFaultsAndOperations(deviceId, timestamp, callback) { +interface GetDueTasksAndFaultsAndOperationsCallback { + ( + err: null, + tasks: any[], + faults: { [channel: string]: SessionFault }, + operations: { [commandKey: string]: Operation }, + ttl: number + ): void; + + ( + err: Error, + tasks?: null, + faults?: null, + operations?: null, + ttl?: null + ): void; +} + +function getDueTasksAndFaultsAndOperations( + deviceId, + timestamp, + callback: GetDueTasksAndFaultsAndOperationsCallback +): void { cache.get(`${deviceId}_tasks_faults_operations`, (err, res) => { if (err) return void callback(err); @@ -850,7 +899,8 @@ function getDueTasksAndFaultsAndOperations(deviceId, timestamp, callback) { null, res.tasks || [], res.faults || {}, - res.operations || {} + res.operations || {}, + 0 ); } @@ -899,8 +949,12 @@ function cacheDueTasksAndFaultsAndOperations( operations, cacheUntil, callback -) { - const v = {}; +): void { + const v = { + tasks: null, + faults: null, + operations: null + }; if (tasks.length) v.tasks = tasks; if (Object.keys(faults).length) v.faults = faults; if (Object.keys(operations).length) v.operations = operations; @@ -917,7 +971,7 @@ function cacheDueTasksAndFaultsAndOperations( ); } -function processRequest(sessionContext, rpc) { +function processRequest(sessionContext, rpc): void { if (rpc.cpeRequest) { if (rpc.cpeRequest.name === "Inform") { logger.accessInfo({ @@ -996,7 +1050,7 @@ function processRequest(sessionContext, rpc) { } } -export function listener(httpRequest, httpResponse) { +export function listener(httpRequest, httpResponse): void { stats.totalRequests += 1; if (httpRequest.method !== "POST") { @@ -1064,7 +1118,7 @@ export function listener(httpRequest, httpResponse) { offset += chunk.length; } - function parsedRpc(sessionContext, rpc, parseWarnings) { + function parsedRpc(sessionContext, rpc, parseWarnings): void { for (const w of parseWarnings) { w.sessionContext = sessionContext; w.rpc = rpc; @@ -1143,7 +1197,7 @@ export function listener(httpRequest, httpResponse) { if (sessionContext) { if ( (rpc.cpeRequest && rpc.cpeRequest.name === "Inform") || - !sessionContext.rpcRequest ^ !(rpc.cpeResponse || rpc.cpeFault) + !sessionContext.rpcRequest !== !(rpc.cpeResponse || rpc.cpeFault) ) { logger.accessError({ message: "Bad session state", @@ -1201,7 +1255,7 @@ export function listener(httpRequest, httpResponse) { _sessionContext.cacheSnapshot = cacheSnapshot; _sessionContext.configContext = configContext; - _sessionContext.debug = localCache.getConfig( + _sessionContext.debug = !!localCache.getConfig( cacheSnapshot, "cwmp.debug", configContext diff --git a/lib/db.js b/lib/db.ts similarity index 94% rename from lib/db.js rename to lib/db.ts index 9b3c16c..bc6f4b8 100644 --- a/lib/db.js +++ b/lib/db.ts @@ -16,7 +16,6 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; import { MongoClient, ObjectID } from "mongodb"; import { get } from "./config"; @@ -36,9 +35,9 @@ export let tasksCollection, export let client; -export function connect(callback) { +export function connect(callback): void { MongoClient.connect( - get("MONGODB_CONNECTION_URL"), + "" + get("MONGODB_CONNECTION_URL"), { useNewUrlParser: true }, (err, _client) => { if (err) return void callback(err); @@ -63,13 +62,13 @@ export function connect(callback) { ); } -export function disconnect() { +export function disconnect(): void { if (client) client.close(); } // Optimize projection by removing overlaps // This can modify the object -function optimizeProjection(obj) { +function optimizeProjection(obj: {}): {} { if (obj[""]) return { "": obj[""] }; const keys = Object.keys(obj).sort(); @@ -88,14 +87,14 @@ function optimizeProjection(obj) { return obj; } -export function fetchDevice(id, timestamp, patterns, callback) { - const MAX_DEPTH = get("MAX_DEPTH", id); +export function fetchDevice(id, timestamp, patterns, callback): void { + const MAX_DEPTH = +get("MAX_DEPTH", id); if (!patterns || !patterns.length) patterns = [[[], (1 << MAX_DEPTH) - 1]]; let projection = {}; const projectionTree = {}; - function func(path, pats, projTree) { + function func(path, pats, projTree): void { const children = {}; for (const pat of pats) { const fragment = pat[0][path.length] || "*"; @@ -232,16 +231,16 @@ export function fetchDevice(id, timestamp, patterns, callback) { } } - const options = {}; + let options; if (!projection[""]) { - if (!Object.keys(projection).length) options.projection = { _id: 1 }; - else options.projection = projection; + if (!Object.keys(projection).length) options = { projection: { _id: 1 } }; + else options = { projection: projection }; } devicesCollection.findOne({ _id: id }, options, (err, device) => { if (err || !device) return void callback(err); - function storeParams(obj, path, ts, descendantsFetched, projTree) { + function storeParams(obj, path, ts, descendantsFetched, projTree): void { let thisFetched = false; if (descendantsFetched) { thisFetched = true; @@ -278,7 +277,11 @@ export function fetchDevice(id, timestamp, patterns, callback) { if (obj["_instance"] && obj["_object"] == null) obj["_object"] = true; if (thisFetched) { - const attrs = {}; + const attrs: { + object?: [number, number]; + writable?: [number, number]; + value?: [number, [string | number | boolean, string]]; + } = {}; let t = obj["_timestamp"] || 1; if (ts > t) t = ts; @@ -392,7 +395,7 @@ export function fetchDevice(id, timestamp, patterns, callback) { delete device[k]; break; case "_tags": - if (v.length) { + if ((v as string[]).length) { res.push([ ["Tags"], timestamp, @@ -400,7 +403,7 @@ export function fetchDevice(id, timestamp, patterns, callback) { ]); } - for (let t of v) { + for (let t of v as string[]) { t = t.replace(/[^a-zA-Z0-9-]+/g, "_"); res.push([ ["Tags", t], @@ -478,7 +481,7 @@ export function saveDevice( isNew, sessionTimestamp, callback -) { +): void { const update = { $set: {}, $unset: {}, $addToSet: {}, $pull: {} }; for (const diff of deviceData.timestamps.diff()) { @@ -501,7 +504,7 @@ export function saveDevice( .concat("_timestamp") .join(".") ] = 1; - } else if (diff[2] !== diff[1]) { + } else { const parent = deviceData.paths.get(diff[0].slice(0, -1)); if (parent && (!parent.length || deviceData.attributes.has(parent))) { update["$set"][ @@ -515,8 +518,6 @@ export function saveDevice( } for (const diff of deviceData.attributes.diff()) { - if (diff[1] === diff[2]) continue; - const path = diff[0]; const value1 = (((diff[1] || {}).value || [])[1] || [])[0]; const value2 = (((diff[2] || {}).value || [])[1] || [])[0]; @@ -726,7 +727,7 @@ export function saveDevice( ); } -export function getFaults(deviceId, callback) { +export function getFaults(deviceId, callback): void { faultsCollection .find({ _id: { $regex: `^${escapeRegExp(deviceId)}\\:` } }) .toArray((err, res) => { @@ -747,7 +748,7 @@ export function getFaults(deviceId, callback) { }); } -export function saveFault(deviceId, channel, fault, callback) { +export function saveFault(deviceId, channel, fault, callback): void { const id = `${deviceId}:${channel}`; fault = Object.assign({}, fault); fault._id = id; @@ -758,11 +759,11 @@ export function saveFault(deviceId, channel, fault, callback) { faultsCollection.replaceOne({ _id: id }, fault, { upsert: true }, callback); } -export function deleteFault(deviceId, channel, callback) { +export function deleteFault(deviceId, channel, callback): void { faultsCollection.deleteOne({ _id: `${deviceId}:${channel}` }, callback); } -export function getDueTasks(deviceId, timestamp, callback) { +export function getDueTasks(deviceId, timestamp, callback): void { const cur = tasksCollection.find({ device: deviceId }).sort(["timestamp"]); const tasks = []; @@ -807,14 +808,14 @@ export function getDueTasks(deviceId, timestamp, callback) { ); } -export function clearTasks(deviceId, taskIds, callback) { +export function clearTasks(deviceId, taskIds, callback): void { tasksCollection.deleteMany( { _id: { $in: taskIds.map(id => new ObjectID(id)) } }, callback ); } -export function getOperations(deviceId, callback) { +export function getOperations(deviceId, callback): void { operationsCollection .find({ _id: { $regex: `^${escapeRegExp(deviceId)}\\:` } }) .toArray((err, res) => { @@ -835,7 +836,7 @@ export function getOperations(deviceId, callback) { }); } -export function saveOperation(deviceId, commandKey, operation, callback) { +export function saveOperation(deviceId, commandKey, operation, callback): void { const id = `${deviceId}:${commandKey}`; operation = Object.assign({}, operation); operation._id = id; @@ -851,34 +852,34 @@ export function saveOperation(deviceId, commandKey, operation, callback) { ); } -export function deleteOperation(deviceId, commandKey, callback) { +export function deleteOperation(deviceId, commandKey, callback): void { operationsCollection.deleteOne( { _id: `${deviceId}:${commandKey}` }, callback ); } -export function getPresets(callback) { +export function getPresets(callback): void { presetsCollection.find().toArray(callback); } -export function getObjects(callback) { +export function getObjects(callback): void { objectsCollection.find().toArray(callback); } -export function getProvisions(callback) { +export function getProvisions(callback): void { provisionsCollection.find().toArray(callback); } -export function getVirtualParameters(callback) { +export function getVirtualParameters(callback): void { virtualParametersCollection.find().toArray(callback); } -export function getFiles(callback) { +export function getFiles(callback): void { filesCollection.find().toArray(callback); } -export function getConfig(callback) { +export function getConfig(callback): void { configCollection.find().toArray((err, res) => { if (err) return void callback(err); diff --git a/lib/default-provisions.js b/lib/default-provisions.ts similarity index 90% rename from lib/default-provisions.js rename to lib/default-provisions.ts index 1c7f5ef..edcf359 100644 --- a/lib/default-provisions.js +++ b/lib/default-provisions.ts @@ -16,16 +16,15 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; import * as config from "./config"; import * as common from "./common"; import * as device from "./device"; import * as scheduling from "./scheduling"; -const MAX_DEPTH = config.get("MAX_DEPTH"); +const MAX_DEPTH = +config.get("MAX_DEPTH"); -export function refresh(sessionContext, provision, declarations) { +export function refresh(sessionContext, provision, declarations): boolean { const path = common.parsePath(provision[1]).slice(); const l = path.length; path.length = MAX_DEPTH; @@ -48,7 +47,7 @@ export function refresh(sessionContext, provision, declarations) { return true; } -export function value(sessionContext, provision, declarations) { +export function value(sessionContext, provision, declarations): boolean { const path = common.parsePath(provision[1]); declarations.push({ path: path, @@ -62,7 +61,7 @@ export function value(sessionContext, provision, declarations) { return true; } -export function tag(sessionContext, provision, declarations) { +export function tag(sessionContext, provision, declarations): boolean { const path = ["Tags", provision[1]]; declarations.push({ @@ -77,7 +76,7 @@ export function tag(sessionContext, provision, declarations) { return true; } -export function reboot(sessionContext, provision, declarations) { +export function reboot(sessionContext, provision, declarations): boolean { declarations.push({ path: ["Reboot"], pathGet: 1, @@ -90,7 +89,7 @@ export function reboot(sessionContext, provision, declarations) { return true; } -export function reset(sessionContext, provision, declarations) { +export function reset(sessionContext, provision, declarations): boolean { declarations.push({ path: ["FactoryReset"], pathGet: 1, @@ -103,7 +102,7 @@ export function reset(sessionContext, provision, declarations) { return true; } -export function download(sessionContext, provision, declarations) { +export function download(sessionContext, provision, declarations): boolean { const alias = [ ["FileType"], provision[1] || "", @@ -140,7 +139,7 @@ export function instances( declarations, startRevision, endRevision -) { +): boolean { let count = Number(provision[2]); if (Number.isNaN(count)) return true; diff --git a/lib/device.js b/lib/device.ts similarity index 82% rename from lib/device.js rename to lib/device.ts index f19c386..21df586 100644 --- a/lib/device.js +++ b/lib/device.ts @@ -16,7 +16,8 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; + +import { ParamPath, DeviceData, Declaration, Clear } from "./types"; const CHANGE_FLAGS = { object: 2, @@ -24,7 +25,7 @@ const CHANGE_FLAGS = { value: 8 }; -function parseBool(v) { +function parseBool(v): boolean { v = "" + v; if (v === "true" || v === "TRUE" || v === "True" || v === "1") return true; else if (v === "false" || v === "FALSE" || v === "False" || v === "0") @@ -32,14 +33,16 @@ function parseBool(v) { else return null; } -export function sanitizeParameterValue(parameterValue) { +export function sanitizeParameterValue( + parameterValue +): [string | number | boolean, string?] { if (parameterValue[0] != null) { switch (parameterValue[1]) { case "xsd:boolean": if (typeof parameterValue[0] !== "boolean") { - let v = parseBool(parameterValue[0]); - if (v == null) v = "" + parameterValue[0]; - parameterValue[0] = v; + const b = parseBool(parameterValue[0]); + if (b == null) parameterValue[0] = "" + parameterValue[0]; + else parameterValue[0] = b; } break; case "xsd:string": @@ -52,20 +55,22 @@ export function sanitizeParameterValue(parameterValue) { case "xsd:int": case "xsd:unsignedInt": if (typeof parameterValue[0] !== "number") { - let v = parseInt(parameterValue[0]); - if (isNaN(v)) v = "" + parameterValue[0]; - parameterValue[0] = v; + const i = parseInt(parameterValue[0]); + if (isNaN(i)) parameterValue[0] = "" + parameterValue[0]; + else parameterValue[0] = i; } break; case "xsd:dateTime": if (typeof parameterValue[0] !== "number") { // Don't use parseInt because it reads date string as a number - let v = +parameterValue[0]; - if (isNaN(v)) { - v = Date.parse(parameterValue[0]); - if (isNaN(v)) v = "" + parameterValue[0]; + let i = +parameterValue[0]; + if (isNaN(i)) { + i = Date.parse(parameterValue[0]); + if (isNaN(i)) parameterValue[0] = "" + parameterValue[0]; + else parameterValue[0] = i; + } else { + parameterValue[0] = i; } - parameterValue[0] = v; } break; default: @@ -83,10 +88,10 @@ export function sanitizeParameterValue(parameterValue) { return parameterValue; } -export function getAliasDeclarations(path, timestamp) { - const decs = []; +export function getAliasDeclarations(path, timestamp): Declaration[] { + const decs = [] as Declaration[]; - function recursive(p, prefix) { + function recursive(p, prefix): void { const pattern = prefix.concat(p); for (let i = prefix.length; i < pattern.length; ++i) { @@ -113,13 +118,17 @@ export function getAliasDeclarations(path, timestamp) { return decs; } -export function unpack(deviceData, path, revision) { - let allMatches = []; +export function unpack( + deviceData, + path: ParamPath, + revision?: number +): ParamPath[] { + let allMatches = [] as ParamPath[]; if (!path.alias) { for (const p of deviceData.paths.find(path, false, true)) if (deviceData.attributes.has(p, revision)) allMatches.push(p); } else { - const wildcardPath = path.slice(); + const wildcardPath = path.slice() as ParamPath; wildcardPath.wildcard = path.wildcard; for (let i = 0; i < wildcardPath.length; ++i) { if (Array.isArray(wildcardPath[i])) { @@ -134,7 +143,9 @@ export function unpack(deviceData, path, revision) { for (let i = path.length - 1; i >= 0; --i) { if (Array.isArray(path[i])) { for (let j = 0; j < path[i].length; j += 2) { - const p = wildcardPath.slice(0, i + 1).concat(path[i][j]); + const p = wildcardPath + .slice(0, i + 1) + .concat(path[i][j]) as ParamPath; p.alias = ((wildcardPath.alias & ((1 << (i + 1)) - 1)) + path[i][j].alias) << (i + 1); @@ -143,7 +154,7 @@ export function unpack(deviceData, path, revision) { path[i][j].wildcard) << (i + 1); const unpacked = unpack(deviceData, p, revision); - const filtered = []; + const filtered = [] as ParamPath[]; for (const up of unpacked) { const attributes = deviceData.attributes.get(up, revision); if ( @@ -161,7 +172,7 @@ export function unpack(deviceData, path, revision) { if (k < 0) { filtered.push(allMatches[m]); - allMatches[m] = []; + allMatches[m] = null; } } } @@ -172,21 +183,19 @@ export function unpack(deviceData, path, revision) { } } - allMatches.sort((a, b) => { - for (let i = 0; i < a.length; ++i) { - if (a === b) continue; + allMatches.sort((p1, p2) => { + for (let i = 0; i < p1.length; ++i) { + const a = p1[i]; + const b = p2[i]; + if (a !== b) { + // Use numeric sorting for numbers + const ia = parseInt(a); + const ib = parseInt(b); - // Use numeric sorting for numbers - const ia = parseInt(a); - const ib = parseInt(b); - - if (ia.toString() === a && ib.toString() === b) { - a = ia; - b = ib; + if (ia === +a && ib === +b) return ia - ib; + else if (a < b) return -1; + else return 1; } - - if (a < b) return -1; - else return 1; } return 0; }); @@ -200,7 +209,7 @@ export function clear( timestamp, attributes, changeFlags = 0 -) { +): void { const changeTrackers = {}; timestamp = timestamp || 0; @@ -259,7 +268,7 @@ export function clear( if (changeTrackers[k] & changeFlags) deviceData.changes.add(k); } -function compareEquality(a, b) { +function compareEquality(a, b): boolean { const t = typeof a; if ( a === null || @@ -274,7 +283,13 @@ function compareEquality(a, b) { return JSON.stringify(a) === JSON.stringify(b); } -export function set(deviceData, path, timestamp, attributes, toClear) { +export function set( + deviceData: DeviceData, + path: ParamPath, + timestamp, + attributes, + toClear?: Clear[] +): Clear[] { path = deviceData.paths.add(path); const currentTimestamp = deviceData.timestamps.get(path); @@ -330,7 +345,7 @@ export function set(deviceData, path, timestamp, attributes, toClear) { if (path.length > 1) { toClear = set( deviceData, - path.slice(0, path.length - 1), + path.slice(0, path.length - 1) as ParamPath, timestamp, { object: [timestamp, 1] }, toClear @@ -372,7 +387,12 @@ export function set(deviceData, path, timestamp, attributes, toClear) { return toClear; } -export function track(deviceData, path, marker, attributes) { +export function track( + deviceData: DeviceData, + path: ParamPath, + marker: string, + attributes? +): void { path = deviceData.paths.add(path); let f = 1; @@ -388,7 +408,7 @@ export function track(deviceData, path, marker, attributes) { cur[marker] |= f; } -export function clearTrackers(deviceData, tracker) { +export function clearTrackers(deviceData, tracker): void { if (Array.isArray(tracker)) { for (const v of deviceData.trackers.values()) for (const t of tracker) delete v[t]; diff --git a/lib/extensions.js b/lib/extensions.ts similarity index 91% rename from lib/extensions.js rename to lib/extensions.ts index 60cf9f9..6ce729e 100644 --- a/lib/extensions.js +++ b/lib/extensions.ts @@ -16,18 +16,17 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; import { spawn } from "child_process"; -import crypto from "crypto"; +import * as crypto from "crypto"; import * as config from "./config"; -const TIMEOUT = config.get("EXT_TIMEOUT"); +const TIMEOUT = +config.get("EXT_TIMEOUT"); const processes = {}; const jobs = new Map(); -function messageHandler(message) { +function messageHandler(message): void { const func = jobs.get(message[0]); if (func) { jobs.delete(message[0]); @@ -35,7 +34,7 @@ function messageHandler(message) { } } -export function run(args, callback) { +export function run(args, callback): boolean { const scriptName = args[0]; const id = crypto.randomBytes(8).toString("hex"); @@ -77,7 +76,7 @@ export function run(args, callback) { return processes[scriptName].send([id, args.slice(1)]); } -function kill(process, callback) { +function kill(process, callback?: () => void): void { if (process.signalCode !== null || process.exitCode !== null) return; const timeToKill = Date.now() + 5000; @@ -96,7 +95,7 @@ function kill(process, callback) { }, 100); } -export function killAll(callback) { +export function killAll(callback?): void { let counter = 1; for (const n in processes) { ++counter; diff --git a/lib/fs.js b/lib/fs.ts similarity index 89% rename from lib/fs.js rename to lib/fs.ts index 9824a82..7ad7698 100644 --- a/lib/fs.js +++ b/lib/fs.ts @@ -16,14 +16,13 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -import url from "url"; -import querystring from "querystring"; +import * as url from "url"; +import * as querystring from "querystring"; import { GridFSBucket } from "mongodb"; import * as db from "./db"; -export function listener(request, response) { +export function listener(request, response): void { const urlParts = url.parse(request.url, true); if (request.method === "GET") { const filename = querystring.unescape(urlParts.pathname.substring(1)); @@ -46,7 +45,7 @@ export function listener(request, response) { }); const bucket = new GridFSBucket(db.client.db()); - const downloadStream = bucket.openDownloadStream(filename); + const downloadStream = bucket.openDownloadStreamByName(filename); downloadStream.pipe(response); }); } else { diff --git a/lib/gpn-heuristic.js b/lib/gpn-heuristic.ts similarity index 96% rename from lib/gpn-heuristic.js rename to lib/gpn-heuristic.ts index ef985cf..35d3324 100644 --- a/lib/gpn-heuristic.js +++ b/lib/gpn-heuristic.ts @@ -16,7 +16,6 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; const WILDCARD_MULTIPLIER = 2; const UNDISCOVERED_DEPTH = 7; @@ -28,7 +27,7 @@ const UNDISCOVERED_DEPTH = 7; // flags is an int where its bits mark the segments in the pattern that // need refreshing. Leading 0s indicate that the pattern up to that // point has been discovered. -export function estimateGpnCount(gpnPatterns, depth = 0) { +export function estimateGpnCount(gpnPatterns, depth = 0): number { const children = {}; const wildcardChildren = []; let wildcardDiscovered = false; diff --git a/lib/instance-set.js b/lib/instance-set.ts similarity index 82% rename from lib/instance-set.js rename to lib/instance-set.ts index 4aa2d20..17c0376 100644 --- a/lib/instance-set.js +++ b/lib/instance-set.ts @@ -16,22 +16,27 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; + +interface Instance { + [name: string]: string; +} export default class InstanceSet { - constructor() { + private set: Set; + + public constructor() { this.set = new Set(); } - add(instance) { + public add(instance: Instance): void { this.set.add(instance); } - delete(instance) { + public delete(instance: Instance): void { this.set.delete(instance); } - superset(instance) { + public superset(instance: Instance): Instance[] { const res = []; for (const inst of this.set) { let match = true; @@ -67,7 +72,7 @@ export default class InstanceSet { return res; } - subset(instance) { + public subset(instance: Instance): Instance[] { const res = []; for (const inst of this.set) { @@ -104,23 +109,23 @@ export default class InstanceSet { return res; } - [Symbol.iterator]() { + public [Symbol.iterator](): IterableIterator { return this.set.values(); } - forEach(callback) { - return this.set.forEach(callback); + public forEach(callback: (instance: Instance) => void): void { + this.set.forEach(callback); } - values() { + public values(): IterableIterator { return this.set.values(); } - clear() { + public clear(): void { this.set.clear(); } - get size() { + public get size(): number { return this.set.size; } } diff --git a/lib/local-cache.js b/lib/local-cache.ts similarity index 91% rename from lib/local-cache.js rename to lib/local-cache.ts index b7d51df..9ac9cd0 100644 --- a/lib/local-cache.js +++ b/lib/local-cache.ts @@ -16,11 +16,9 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; - -import vm from "vm"; -import crypto from "crypto"; +import * as vm from "vm"; +import * as crypto from "crypto"; import * as config from "./config"; import * as db from "./db"; import * as cache from "./cache"; @@ -28,6 +26,7 @@ import * as query from "./query"; import * as logger from "./logger"; import * as scheduling from "./scheduling"; import * as expression from "./common/expression"; +import { Preset } from "./types"; const REFRESH = 3000; const EVICT_TIMEOUT = 60000; @@ -36,7 +35,7 @@ const snapshots = new Map(); let currentSnapshot = null; let nextRefresh = 1; -function computeHash(snapshot) { +function computeHash(snapshot): string { // MD5 hash for presets, provisions, virtual parameters for detecting changes const h = crypto.createHash("md5"); for (const p of snapshot.presets) { @@ -65,7 +64,7 @@ function computeHash(snapshot) { return h.digest("hex"); } -function flattenObject(src, prefix = "", dst = {}) { +function flattenObject(src, prefix = "", dst = {}): {} { for (const k of Object.keys(src)) { const v = src[k]; if (typeof v === "object" && !Array.isArray(v)) @@ -75,7 +74,7 @@ function flattenObject(src, prefix = "", dst = {}) { return dst; } -function refresh(callback) { +function refresh(callback): void { if (!nextRefresh) { return void setTimeout(() => { refresh(callback); @@ -126,7 +125,7 @@ function refresh(callback) { else return a.weight - b.weight; }); - const presets = []; + const presets = [] as Preset[]; for (const preset of res) { let schedule = null; if (preset.schedule) { @@ -369,7 +368,16 @@ function refresh(callback) { }); } -export function getCurrentSnapshot(callback) { +interface GetCurrentSnapshotCallback { + (err: null, currentSnapshot: string): void; + (err: Error, currentSnapshot?: null): void; +} + +export function getCurrentSnapshot(callback: GetCurrentSnapshotCallback); +export function getCurrentSnapshot(): Promise; +export function getCurrentSnapshot( + callback?: GetCurrentSnapshotCallback +): Promise | void { if (Date.now() < nextRefresh) { if (callback) return callback(null, currentSnapshot); return Promise.resolve(currentSnapshot); @@ -389,35 +397,46 @@ export function getCurrentSnapshot(callback) { }); } -export function hasSnapshot(hash) { +export function hasSnapshot(hash): boolean { return snapshots.has(hash); } -export function getPresets(snapshotKey) { +export function getPresets(snapshotKey): Preset[] { const snapshot = snapshots.get(snapshotKey); if (!snapshot) throw new Error("Cache snapshot does not exist"); return snapshot.presets; } -export function getProvisions(snapshotKey) { +export function getProvisions( + snapshotKey +): { [name: string]: { md5: string; script: vm.Script } } { const snapshot = snapshots.get(snapshotKey); if (!snapshot) throw new Error("Cache snapshot does not exist"); return snapshot.provisions; } -export function getVirtualParameters(snapshotKey) { +export function getVirtualParameters( + snapshotKey +): { [name: string]: { md5: string; script: vm.Script } } { const snapshot = snapshots.get(snapshotKey); if (!snapshot) throw new Error("Cache snapshot does not exist"); return snapshot.virtualParameters; } -export function getFiles(snapshotKey) { +export function getFiles( + snapshotKey +): { [name: string]: { length: number; md5: string; contentType: string } } { const snapshot = snapshots.get(snapshotKey); if (!snapshot) throw new Error("Cache snapshot does not exist"); return snapshot.files; } -export function getConfig(snapshotKey, key, context, now) { +export function getConfig( + snapshotKey, + key, + context?, + now? +): string | number | boolean | null { const snapshot = snapshots.get(snapshotKey); if (!snapshot) throw new Error("Cache snapshot does not exist"); @@ -446,21 +465,21 @@ export function getConfig(snapshotKey, key, context, now) { return expression.evaluate(snapshot.config[key], context, now || Date.now()); } -export function getAuthConfig(snapshotKey) { +export function getAuthConfig(snapshotKey): {} { const snapshot = snapshots.get(snapshotKey); if (!snapshot) throw new Error("Cache snapshot does not exist"); return snapshot.config.auth; } -export function getPermissionsConfig(snapshotKey) { +export function getPermissionsConfig(snapshotKey): {} { const snapshot = snapshots.get(snapshotKey); if (!snapshot) throw new Error("Cache snapshot does not exist"); return snapshot.config.permissions; } -export function getUiConfig(snapshotKey) { +export function getUiConfig(snapshotKey): {} { const snapshot = snapshots.get(snapshotKey); if (!snapshot) throw new Error("Cache snapshot does not exist"); diff --git a/lib/logger.js b/lib/logger.ts similarity index 89% rename from lib/logger.js rename to lib/logger.ts index 9bf66a0..9c755e0 100644 --- a/lib/logger.js +++ b/lib/logger.ts @@ -16,10 +16,9 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -import fs from "fs"; -import os from "os"; +import * as fs from "fs"; +import * as os from "os"; import * as config from "./config"; @@ -28,20 +27,35 @@ const REOPEN_EVERY = 60000; const LOG_FORMAT = config.get("LOG_FORMAT"); const ACCESS_LOG_FORMAT = config.get("ACCESS_LOG_FORMAT") || LOG_FORMAT; -const defaultMeta = {}; +const defaultMeta: { [name: string]: any } = {}; let LOG_SYSTEMD = false; let ACCESS_LOG_SYSTEMD = false; let LOG_FILE, ACCESS_LOG_FILE; +declare global { + /* eslint-disable-next-line @typescript-eslint/no-namespace */ + namespace NodeJS { + export interface WritableStream { + fd?: number; + } + } +} + +declare module "fs" { + interface WriteStream { + fd?: number; + } +} + let logStream = fs.createWriteStream(null, { fd: process.stderr.fd }); let logStat = fs.fstatSync(logStream.fd); let accessLogStream = fs.createWriteStream(null, { fd: process.stdout.fd }); let accessLogStat = fs.fstatSync(accessLogStream.fd); // Reopen if original files have been moved (e.g. logrotate) -function reopen() { +function reopen(): void { let counter = 1; if (LOG_FILE) { @@ -90,7 +104,7 @@ function reopen() { setTimeout(reopen, REOPEN_EVERY - (Date.now() % REOPEN_EVERY)).unref(); } -export function init(service, version) { +export function init(service, version): void { defaultMeta.hostname = os.hostname(); defaultMeta.pid = process.pid; defaultMeta.name = `genieacs-${service}`; @@ -115,9 +129,7 @@ export function init(service, version) { const JOURNAL_STREAM = process.env["JOURNAL_STREAM"]; if (JOURNAL_STREAM) { - let [dev, inode] = JOURNAL_STREAM.split(":"); - dev = parseInt(dev); - inode = parseInt(inode); + const [dev, inode] = JOURNAL_STREAM.split(":").map(parseInt); LOG_SYSTEMD = logStat.dev === dev && logStat.ino === inode; ACCESS_LOG_SYSTEMD = @@ -129,12 +141,12 @@ export function init(service, version) { setTimeout(reopen, REOPEN_EVERY - (Date.now() % REOPEN_EVERY)).unref(); } -export function close() { +export function close(): void { accessLogStream.end(); logStream.end(); } -export function flatten(details) { +export function flatten(details): {} { if (details.sessionContext) { details.deviceId = details.sessionContext.deviceId; details.remoteAddress = @@ -198,7 +210,7 @@ export function flatten(details) { return details; } -function formatJson(details, systemd) { +function formatJson(details, systemd): string { if (systemd) { let severity = ""; if (details.severity === "info") severity = "<6>"; @@ -211,7 +223,7 @@ function formatJson(details, systemd) { return `${JSON.stringify(flatten(details))}${os.EOL}`; } -function formatSimple(details, systemd) { +function formatSimple(details, systemd): string { flatten(details); let remote = ""; @@ -255,7 +267,7 @@ function formatSimple(details, systemd) { }${meta}${os.EOL}`; } -function log(details) { +function log(details): void { details.timestamp = new Date().toISOString(); if (LOG_FORMAT === "json") { details = Object.assign({}, defaultMeta, details); @@ -265,22 +277,22 @@ function log(details) { } } -export function info(details) { +export function info(details): void { details.severity = "info"; log(details); } -export function warn(details) { +export function warn(details): void { details.severity = "warn"; log(details); } -export function error(details) { +export function error(details): void { details.severity = "error"; log(details); } -export function accessLog(details) { +export function accessLog(details): void { details.timestamp = new Date().toISOString(); if (ACCESS_LOG_FORMAT === "json") { Object.assign(details, defaultMeta); @@ -290,17 +302,17 @@ export function accessLog(details) { } } -export function accessInfo(details) { +export function accessInfo(details): void { details.severity = "info"; accessLog(details); } -export function accessWarn(details) { +export function accessWarn(details): void { details.severity = "warn"; accessLog(details); } -export function accessError(details) { +export function accessError(details): void { details.severity = "error"; accessLog(details); } diff --git a/lib/nbi.js b/lib/nbi.ts similarity index 94% rename from lib/nbi.js rename to lib/nbi.ts index cf76da0..84ea65f 100644 --- a/lib/nbi.js +++ b/lib/nbi.ts @@ -16,12 +16,11 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -import url from "url"; -import mongodb from "mongodb"; -import querystring from "querystring"; -import vm from "vm"; +import * as url from "url"; +import * as mongodb from "mongodb"; +import * as querystring from "querystring"; +import * as vm from "vm"; import { exec } from "child_process"; import * as config from "./config"; import * as db from "./db"; @@ -43,7 +42,7 @@ const PROVISIONS_REGEX = /^\/provisions\/([a-zA-Z0-9\-_%]+)\/?$/; const VIRTUAL_PARAMETERS_REGEX = /^\/virtual_parameters\/([a-zA-Z0-9\-_%]+)\/?$/; const FAULTS_REGEX = /^\/faults\/([a-zA-Z0-9\-_%:]+)\/?$/; -function throwError(err, httpResponse) { +function throwError(err, httpResponse?): never { if (httpResponse) { httpResponse.writeHead(500, { Connection: "close" }); httpResponse.end(`${err.name}: ${err.message}`); @@ -51,17 +50,20 @@ function throwError(err, httpResponse) { throw err; } -export function listener(request, response) { +export function listener(request, response): void { const chunks = []; let bytes = 0; response.setHeader("GenieACS-Version", VERSION); - request.addListener("data", chunk => { - chunks.push(chunk); - bytes += chunk.length; - }); + request.addListener( + "data", + (chunk): void => { + chunks.push(chunk); + bytes += chunk.length; + } + ); - function getBody() { + function getBody(): Buffer { // Write all chunks into a Buffer const body = Buffer.allocUnsafe(bytes); let offset = 0; @@ -80,7 +82,7 @@ export function listener(request, response) { PRESETS_REGEX.exec(urlParts.pathname)[1] ); if (request.method === "PUT") { - const preset = JSON.parse(body); + const preset = JSON.parse(body.toString()); preset._id = presetName; db.presetsCollection.replaceOne( { _id: presetName }, @@ -117,7 +119,7 @@ export function listener(request, response) { OBJECTS_REGEX.exec(urlParts.pathname)[1] ); if (request.method === "PUT") { - const object = JSON.parse(body); + const object = JSON.parse(body.toString()); object._id = objectName; db.objectsCollection.replaceOne( { _id: objectName }, @@ -320,7 +322,7 @@ export function listener(request, response) { DEVICE_TASKS_REGEX.exec(urlParts.pathname)[1] ); if (body.length) { - const task = JSON.parse(body); + const task = JSON.parse(body.toString()); task.device = deviceId; apiFunctions.insertTasks(task, err => { if (err) return void throwError(err, response); @@ -340,7 +342,7 @@ export function listener(request, response) { const taskTimeout = (urlParts.query.timeout && - parseInt(urlParts.query.timeout)) || + parseInt(urlParts.query.timeout as string)) || config.get("DEVICE_ONLINE_THRESHOLD", deviceId); apiFunctions.watchTask( @@ -499,15 +501,18 @@ export function listener(request, response) { const uploadStream = bucket.openUploadStreamWithId(filename, filename, { metadata: metadata }); - uploadStream.end(body, err => { - if (err) return void throwError(err, response); + uploadStream.on("error", err => { + throwError(err, response); + }); + + uploadStream.end(body, () => { response.writeHead(201); response.end(); }); } else if (request.method === "DELETE") { const bucket = new mongodb.GridFSBucket(db.client.db()); - bucket.delete(filename, err => { + bucket.delete((filename as unknown) as mongodb.ObjectId, err => { if (err) return void throwError(err, response); response.writeHead(200); @@ -577,7 +582,7 @@ export function listener(request, response) { let q = {}; if (urlParts.query.query) { try { - q = JSON.parse(urlParts.query.query); + q = JSON.parse(urlParts.query.query as string); } catch (err) { response.writeHead(400); response.end(`${err.name}: ${err.message}`); @@ -606,14 +611,14 @@ export function listener(request, response) { let projection = null; if (urlParts.query.projection) { projection = {}; - for (const p of urlParts.query.projection.split(",")) + for (const p of (urlParts.query.projection as string).split(",")) projection[p.trim()] = 1; } const cur = collection.find(q, { projection: projection }); if (urlParts.query.sort) { - const s = JSON.parse(urlParts.query.sort); + const s = JSON.parse(urlParts.query.sort as string); const sort = {}; for (const [k, v] of Object.entries(s)) { if (k[k.lastIndexOf(".") + 1] !== "_" && collectionName === "devices") @@ -624,9 +629,11 @@ export function listener(request, response) { cur.sort(sort); } - if (urlParts.query.skip) cur.skip(parseInt(urlParts.query.skip)); + if (urlParts.query.skip) + cur.skip(parseInt(urlParts.query.skip as string)); - if (urlParts.query.limit) cur.limit(parseInt(urlParts.query.limit)); + if (urlParts.query.limit) + cur.limit(parseInt(urlParts.query.limit as string)); cur.count(false, (err, total) => { if (err) return void throwError(err); diff --git a/lib/path-set.js b/lib/path-set.ts similarity index 88% rename from lib/path-set.js rename to lib/path-set.ts index db92ffb..6df6b72 100644 --- a/lib/path-set.js +++ b/lib/path-set.ts @@ -16,19 +16,23 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; + +import { ParamPath } from "./types"; export default class PathSet { - constructor() { + private lengthIndex: Set[]; + private fragmentIndex: Map>[]; + + public constructor() { this.lengthIndex = []; this.fragmentIndex = []; } - get depth() { + public get depth(): number { return this.lengthIndex.length; } - add(path) { + public add(path: ParamPath): ParamPath { const p = this.get(path); if (p) return p; @@ -50,7 +54,7 @@ export default class PathSet { let fragmentIndexSet = fragmentIndex.get(fragment); if (!fragmentIndexSet) { - fragmentIndexSet = new Set(); + fragmentIndexSet = new Set(); fragmentIndex.set(fragment, fragmentIndexSet); } @@ -65,7 +69,7 @@ export default class PathSet { return path; } - get(pattern) { + public get(pattern: ParamPath): ParamPath { const lengthIndex = this.lengthIndex[pattern.length]; if (!lengthIndex || !lengthIndex.size) return null; @@ -102,7 +106,12 @@ export default class PathSet { return null; } - find(pattern, superset = false, subset = false, depth = pattern.length) { + public find( + pattern: ParamPath, + superset: boolean = false, + subset: boolean = false, + depth: number = pattern.length + ): ParamPath[] { const res = []; const groups = [[]]; diff --git a/lib/query.js b/lib/query.ts similarity index 90% rename from lib/query.js rename to lib/query.ts index 0a742da..20e95f2 100644 --- a/lib/query.js +++ b/lib/query.ts @@ -16,11 +16,10 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; import * as common from "./common"; -function stringToRegexp(input, flags) { +function stringToRegexp(input, flags?): RegExp | false { if (input.indexOf("*") === -1) return false; let output = input.replace(/[[\]\\^$.|?+()]/, "\\$&"); @@ -34,7 +33,7 @@ function stringToRegexp(input, flags) { return new RegExp(output, flags); } -function normalize(input) { +function normalize(input): any { if (common.typeOf(input) === common.STRING_TYPE) { const vals = [input]; const m = /^\/(.*?)\/(g?i?m?y?)$/.exec(input); @@ -53,10 +52,10 @@ function normalize(input) { return input; } -export function expandValue(value) { +export function expandValue(value): any[] { if (common.typeOf(value) === common.ARRAY_TYPE) { let a = []; - for (const j of value) a = a.conact(expandValue(j)); + for (const j of value) a = a.concat(expandValue(j)); return [a]; } else if (common.typeOf(value) !== common.OBJECT_TYPE) { const n = normalize(value); @@ -89,7 +88,7 @@ export function expandValue(value) { return objs; } -function permute(param, val) { +function permute(param, val): any[] { const conditions = []; const values = expandValue(val); @@ -104,12 +103,12 @@ function permute(param, val) { return conditions; } -export function expand(query) { +export function expand(query): {} { const newQuery = {}; for (const [k, v] of Object.entries(query)) { if (k[0] === "$") { // Operator - newQuery[k] = v.map(e => expand(e)); + newQuery[k] = (v as any[]).map(e => expand(e)); } else { const conditions = permute(k, v); if (conditions.length > 1) { @@ -130,7 +129,7 @@ export function expand(query) { return newQuery; } -function testExpressions(params, expressions, lop) { +function testExpressions(params, expressions, lop): boolean { for (const f of expressions) { const res = test(params, f); switch (lop) { @@ -157,7 +156,7 @@ function testExpressions(params, expressions, lop) { } } -export function test(params, query) { +export function test(params, query): boolean { let res; for (const [k, v] of Object.entries(query)) { if (k.charAt(0) === "$") { @@ -170,7 +169,8 @@ export function test(params, query) { // TODO comparing array to regex, array to array, and object to object res = value.indexOf(v) !== -1; } else { - if (common.typeOf(v) === common.REGEXP_TYPE) res = v.test(value); + if (common.typeOf(v) === common.REGEXP_TYPE) + res = (v as RegExp).test(value); else res = v === value; } } else { @@ -216,7 +216,7 @@ export function test(params, query) { return true; } -function matchType(src, dst) { +function matchType(src, dst): string | number | boolean { const type = typeof src; if (type === "string") { return String(dst); @@ -233,7 +233,7 @@ function matchType(src, dst) { return dst; } -export function testFilter(obj, filter) { +export function testFilter(obj, filter): boolean { for (const [k, v] of Object.entries(filter)) { const [param, op] = k.split(/([^a-zA-Z0-9\-_.].*)/, 2); const val = matchType(obj[param], v); @@ -264,12 +264,11 @@ export function testFilter(obj, filter) { return true; } -export function convertMongoQueryToFilters(query, filters) { - filters = filters || {}; +export function convertMongoQueryToFilters(query, filters = {}): {} { for (let [k, v] of Object.entries(query)) { if (k[0] === "$") { if (k === "$and") - for (const vv of v) convertMongoQueryToFilters(vv, filters); + for (const vv of v as any[]) convertMongoQueryToFilters(vv, filters); else throw new Error(`Operator ${k} not supported`); } else if (k === "_tags") { if (common.typeOf(v) === common.OBJECT_TYPE) { @@ -279,7 +278,7 @@ export function convertMongoQueryToFilters(query, filters) { else throw new Error(`Operator ${kk} not supported`); } } else { - v = v.replace(/[^a-zA-Z0-9-]+/g, "_"); + v = (v as string).replace(/[^a-zA-Z0-9-]+/g, "_"); filters[`Tags.${v}`] = true; } } else { @@ -346,11 +345,11 @@ export function convertMongoQueryToFilters(query, filters) { return filters; } -export function sanitizeQueryTypes(query, types) { +export function sanitizeQueryTypes(query, types): {} { for (const [k, v] of Object.entries(query)) { if (k[0] === "$") { // Logical operator - for (const vv of v) sanitizeQueryTypes(vv, types); + for (const vv of v as any[]) sanitizeQueryTypes(vv, types); } else if (k in types) { if (common.typeOf(v) === common.OBJECT_TYPE) { for (const [kk, vv] of Object.entries(v)) { diff --git a/lib/sandbox.js b/lib/sandbox.ts similarity index 92% rename from lib/sandbox.js rename to lib/sandbox.ts index 086ae1d..66c0798 100644 --- a/lib/sandbox.js +++ b/lib/sandbox.ts @@ -16,17 +16,15 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; - -import vm from "vm"; +import * as vm from "vm"; import seedrandom from "seedrandom"; - import * as common from "./common"; import * as device from "./device"; import * as extensions from "./extensions"; import * as logger from "./logger"; import * as scheduling from "./scheduling"; +import { ParamPath, Fault } from "./types"; // Used for throwing to exit user script and commit const COMMIT = Symbol(); @@ -41,7 +39,7 @@ const context = vm.createContext(); let state; const runningExtensions = new WeakMap(); -function runExtension(sessionContext, key, extCall, callback) { +function runExtension(sessionContext, key, extCall, callback): void { let re = runningExtensions.get(sessionContext); if (!re) { re = {}; @@ -62,13 +60,23 @@ function runExtension(sessionContext, key, extCall, callback) { } class SandboxDate { - constructor() { - if (arguments.length) return new Date(...arguments); + public constructor( + ...argumentList: [ + number?, + number?, + number?, + number?, + number?, + number?, + number? + ] + ) { + if (argumentList.length) return new Date(...argumentList); return new Date(state.sessionContext.timestamp); } - static now(intervalOrCron, variance) { + public static now(intervalOrCron, variance): number { let t = state.sessionContext.timestamp; if (typeof intervalOrCron === "number") { @@ -93,7 +101,7 @@ class SandboxDate { } } -function random() { +function random(): number { if (!state.rng) state.rng = seedrandom(state.sessionContext.deviceId); return state.rng(); @@ -104,7 +112,7 @@ random.seed = function(s) { }; class ParameterWrapper { - constructor(path, attributes, unpacked, unpackedRevision) { + public constructor(path, attributes, unpacked?, unpackedRevision?) { for (const attrName of attributes) { Object.defineProperty(this, attrName, { get: function() { @@ -189,7 +197,11 @@ class ParameterWrapper { } } -function declare(path, timestamps, values) { +function declare( + path: ParamPath, + timestamps: { [attr: string]: number }, + values: { [attr: string]: any } +): ParameterWrapper { state.uncommitted = true; if (!timestamps) timestamps = {}; @@ -237,14 +249,14 @@ function declare(path, timestamps, values) { return new ParameterWrapper(parsedPath, attrs); } -function clear(path, timestamp, attributes) { +function clear(path, timestamp, attributes): void { state.uncommitted = true; if (state.revision === state.maxRevision) state.clear.push([common.parsePath(path), timestamp, attributes]); } -function commit() { +function commit(): void { ++state.revision; state.uncommitted = false; @@ -258,7 +270,7 @@ function commit() { } } -function ext() { +function ext(): any { ++state.extCounter; const extCall = Array.from(arguments).map(String); const key = `${state.revision}: ${JSON.stringify(extCall)}`; @@ -270,7 +282,7 @@ function ext() { throw EXT; } -function log(msg, meta) { +function log(msg, meta): void { if (state.revision === state.maxRevision && state.extCounter >= 0) { const details = Object.assign({}, meta, { sessionContext: state.sessionContext, @@ -300,12 +312,12 @@ context.random = random; vm.runInContext("Math.random = random;", context); delete context.random; -function errorToFault(err) { +function errorToFault(err): Fault { if (!err) return null; if (!err.name) return { code: "script", message: `${err}` }; - const fault = { + const fault: Fault = { code: `script.${err.name}`, message: err.message, detail: { @@ -335,7 +347,7 @@ export function run( maxRevision, callback, extCounter = 0 -) { +): void { state = { sessionContext: sessionContext, revision: startRevision, diff --git a/lib/scheduling.js b/lib/scheduling.ts similarity index 83% rename from lib/scheduling.js rename to lib/scheduling.ts index 94b5052..a9293ec 100644 --- a/lib/scheduling.js +++ b/lib/scheduling.ts @@ -16,13 +16,11 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -import crypto from "crypto"; +import * as crypto from "crypto"; +import * as later from "later"; -import later from "later"; - -function md532(str) { +function md532(str): number { const digest = crypto .createHash("md5") .update(str) @@ -35,22 +33,22 @@ function md532(str) { ); } -export function variance(deviceId, vrnc) { +export function variance(deviceId, vrnc): number { return (md532(deviceId) >>> 0) % vrnc; } -export function interval(timestamp, intrvl, offset = 0) { +export function interval(timestamp, intrvl, offset = 0): number { return Math.trunc((timestamp + offset) / intrvl) * intrvl - offset; } -export function parseCron(cronExp) { +export function parseCron(cronExp): any { const parts = cronExp.trim().split(/\s+/); if (parts.length === 5) parts.unshift("*"); return later.schedule(later.parse.cron(parts.join(" "), true)); } -export function cron(timestamp, schedule, offset = 0) { +export function cron(timestamp, schedule, offset = 0): number[] { // TODO later.js doesn't throw erorr if expression is invalid! const ret = [0, 0]; diff --git a/lib/server.js b/lib/server.ts similarity index 83% rename from lib/server.js rename to lib/server.ts index 68ca96e..95440d1 100644 --- a/lib/server.js +++ b/lib/server.ts @@ -16,15 +16,15 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -import fs from "fs"; -import http from "http"; -import https from "https"; +import * as fs from "fs"; +import * as http from "http"; +import * as https from "https"; -let server, listener; +let server: http.Server | https.Server; +let listener: (...args) => void; -function closeServer(timeout, callback) { +function closeServer(timeout, callback): void { if (!server) return void callback(); setTimeout(() => { @@ -48,13 +48,20 @@ function closeServer(timeout, callback) { }); } -export function start(port, networkInterface, ssl, _listener, onConnection) { +export function start( + port, + networkInterface, + ssl, + _listener, + onConnection? +): void { listener = _listener; if (ssl) { const options = { key: fs.readFileSync(ssl.key), - cert: fs.readFileSync(ssl.cert) + cert: fs.readFileSync(ssl.cert), + ca: null }; try { @@ -76,7 +83,7 @@ export function start(port, networkInterface, ssl, _listener, onConnection) { server.listen(port, networkInterface); } -export function stop() { +export function stop(): Promise { return new Promise((resolve, reject) => { setTimeout(() => { reject(new Error("Could not close server in a timely manner")); diff --git a/lib/session.js b/lib/session.ts similarity index 91% rename from lib/session.js rename to lib/session.ts index ad98a76..c2f1817 100644 --- a/lib/session.js +++ b/lib/session.ts @@ -16,7 +16,6 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; import * as config from "./config"; import * as common from "./common"; @@ -29,8 +28,20 @@ import { estimateGpnCount } from "./gpn-heuristic"; import PathSet from "./path-set"; import VersionedMap from "./versioned-map"; import InstanceSet from "./instance-set"; +import { + Attributes, + SessionContext, + ParamPath, + DeviceData, + VirtualParameterDeclaration, + GetAcsRequest, + SetAcsRequest, + AttributeTimestamps, + AttributeValues, + Fault +} from "./types"; -function initDeviceData() { +function initDeviceData(): DeviceData { return { paths: new PathSet(), timestamps: new VersionedMap(), @@ -41,9 +52,14 @@ function initDeviceData() { }; } -export function init(deviceId, cwmpVersion, timeout, callback) { +export function init( + deviceId: string, + cwmpVersion: string, + timeout: number, + callback: (err: Error, sessionContext: SessionContext) => void +): void { const timestamp = Date.now(); - const sessionContext = { + const sessionContext: SessionContext = { timestamp: timestamp, deviceId: deviceId, deviceData: initDeviceData(), @@ -63,7 +79,7 @@ export function init(deviceId, cwmpVersion, timeout, callback) { callback(null, sessionContext); } -function loadParameters(sessionContext, callback) { +function loadParameters(sessionContext: SessionContext, callback): void { if (!sessionContext.toLoad || !sessionContext.toLoad.size) return void callback(); @@ -79,7 +95,7 @@ function loadParameters(sessionContext, callback) { // Device not available in database, mark as new sessionContext.new = true; loaded = [ - [[], (1 << config.get("MAX_DEPTH", sessionContext.deviceId)) - 1] + [[], (1 << +config.get("MAX_DEPTH", sessionContext.deviceId)) - 1] ]; parameters = []; } @@ -104,7 +120,7 @@ function loadParameters(sessionContext, callback) { ); } -function generateRpcId(sessionContext) { +function generateRpcId(sessionContext: SessionContext): string { return ( sessionContext.timestamp.toString(16) + ("0" + sessionContext.cycle.toString(16)).slice(-2) + @@ -112,11 +128,11 @@ function generateRpcId(sessionContext) { ); } -export function inform(sessionContext, rpcReq, callback) { +export function inform(sessionContext: SessionContext, rpcReq, callback): void { const timestamp = sessionContext.timestamp + sessionContext.iteration + 1; - const params = [ + const params: [ParamPath, number, Attributes][] = [ [ - ["DeviceID", "Manufacturer"], + ["DeviceID", "Manufacturer"] as ParamPath, timestamp, { object: [timestamp, 0], @@ -126,7 +142,7 @@ export function inform(sessionContext, rpcReq, callback) { ], [ - ["DeviceID", "OUI"], + ["DeviceID", "OUI"] as ParamPath, timestamp, { object: [timestamp, 0], @@ -136,7 +152,7 @@ export function inform(sessionContext, rpcReq, callback) { ], [ - ["DeviceID", "ProductClass"], + ["DeviceID", "ProductClass"] as ParamPath, timestamp, { object: [timestamp, 0], @@ -146,7 +162,7 @@ export function inform(sessionContext, rpcReq, callback) { ], [ - ["DeviceID", "SerialNumber"], + ["DeviceID", "SerialNumber"] as ParamPath, timestamp, { object: [timestamp, 0], @@ -169,7 +185,7 @@ export function inform(sessionContext, rpcReq, callback) { } params.push([ - ["Events", "Inform"], + ["Events", "Inform"] as ParamPath, timestamp, { object: [timestamp, 0], @@ -180,7 +196,7 @@ export function inform(sessionContext, rpcReq, callback) { for (const e of rpcReq.event) { params.push([ - ["Events", e.replace(/\s+/g, "_")], + ["Events", e.replace(/\s+/g, "_")] as ParamPath, timestamp, { object: [timestamp, 0], @@ -191,7 +207,7 @@ export function inform(sessionContext, rpcReq, callback) { } // Preload DeviceID params - loadPath(sessionContext, ["DeviceID", "*"]); + loadPath(sessionContext, ["DeviceID", "*"] as ParamPath); for (const p of params) loadPath(sessionContext, p[0]); @@ -200,7 +216,7 @@ export function inform(sessionContext, rpcReq, callback) { if (sessionContext.new) { params.push([ - ["DeviceID", "ID"], + ["DeviceID", "ID"] as ParamPath, timestamp, { object: [timestamp, 0], @@ -209,7 +225,7 @@ export function inform(sessionContext, rpcReq, callback) { } ]); params.push([ - ["Events", "Registered"], + ["Events", "Registered"] as ParamPath, timestamp, { object: [timestamp, 0], @@ -244,7 +260,11 @@ export function inform(sessionContext, rpcReq, callback) { }); } -export function transferComplete(sessionContext, rpcReq, callback) { +export function transferComplete( + sessionContext: SessionContext, + rpcReq, + callback +): void { const revision = (sessionContext.revisions[sessionContext.revisions.length - 1] || 0) + 1; sessionContext.deviceData.timestamps.revision = revision; @@ -278,7 +298,7 @@ export function transferComplete(sessionContext, rpcReq, callback) { ); } - loadPath(sessionContext, ["Downloads", instance, "*"]); + loadPath(sessionContext, ["Downloads", instance, "*"] as ParamPath); loadParameters(sessionContext, err => { if (err) return void callback(err); @@ -292,7 +312,7 @@ export function transferComplete(sessionContext, rpcReq, callback) { "Downloads", instance, "LastDownload" - ]); + ] as ParamPath); toClear = device.set( sessionContext.deviceData, p, @@ -305,7 +325,7 @@ export function transferComplete(sessionContext, rpcReq, callback) { "Downloads", instance, "LastFileType" - ]); + ] as ParamPath); toClear = device.set( sessionContext.deviceData, p, @@ -318,7 +338,7 @@ export function transferComplete(sessionContext, rpcReq, callback) { "Downloads", instance, "LastFileName" - ]); + ] as ParamPath); toClear = device.set( sessionContext.deviceData, p, @@ -331,7 +351,7 @@ export function transferComplete(sessionContext, rpcReq, callback) { "Downloads", instance, "LastTargetFileName" - ]); + ] as ParamPath); toClear = device.set( sessionContext.deviceData, p, @@ -344,7 +364,7 @@ export function transferComplete(sessionContext, rpcReq, callback) { "Downloads", instance, "StartTime" - ]); + ] as ParamPath); toClear = device.set( sessionContext.deviceData, p, @@ -357,7 +377,7 @@ export function transferComplete(sessionContext, rpcReq, callback) { "Downloads", instance, "CompleteTime" - ]); + ] as ParamPath); toClear = device.set( sessionContext.deviceData, p, @@ -372,8 +392,12 @@ export function transferComplete(sessionContext, rpcReq, callback) { }); } -function revertDownloadParameters(sessionContext, instance, callback) { - loadPath(sessionContext, ["Downloads", instance, "*"]); +function revertDownloadParameters( + sessionContext: SessionContext, + instance, + callback +): void { + loadPath(sessionContext, ["Downloads", instance, "*"] as ParamPath); loadParameters(sessionContext, err => { if (err) return void callback(err); @@ -386,7 +410,7 @@ function revertDownloadParameters(sessionContext, instance, callback) { "Downloads", instance, "LastDownload" - ]); + ] as ParamPath); const lastDownload = sessionContext.deviceData.attributes.get(p); @@ -394,7 +418,7 @@ function revertDownloadParameters(sessionContext, instance, callback) { "Downloads", instance, "Download" - ]); + ] as ParamPath); const toClear = device.set(sessionContext.deviceData, p, timestamp, { value: [ @@ -410,7 +434,10 @@ function revertDownloadParameters(sessionContext, instance, callback) { }); } -export function timeoutOperations(sessionContext, callback) { +export function timeoutOperations( + sessionContext: SessionContext, + callback +): void { const revision = (sessionContext.revisions[sessionContext.revisions.length - 1] || 0) + 1; sessionContext.deviceData.timestamps.revision = revision; @@ -427,7 +454,7 @@ export function timeoutOperations(sessionContext, callback) { } const DOWNLOAD_TIMEOUT = - localCache.getConfig( + +localCache.getConfig( sessionContext.cacheSnapshot, "cwmp.downloadTimeout", sessionContext.configContext @@ -460,11 +487,15 @@ export function timeoutOperations(sessionContext, callback) { if ((counter -= 2) === 1) callback(null, faults, operations); } -export function addProvisions(sessionContext, channel, provisions) { +export function addProvisions( + sessionContext: SessionContext, + channel, + provisions +): void { // Multiply by two because every iteration is two // phases: read and update const MAX_ITERATIONS = - localCache.getConfig( + +localCache.getConfig( sessionContext.cacheSnapshot, "cwmp.maxCommitIterations", sessionContext.configContext @@ -513,11 +544,11 @@ export function addProvisions(sessionContext, channel, provisions) { } } -export function clearProvisions(sessionContext) { +export function clearProvisions(sessionContext: SessionContext): void { // Multiply by two because every iteration is two // phases: read and update const MAX_ITERATIONS = - localCache.getConfig( + +localCache.getConfig( sessionContext.cacheSnapshot, "cwmp.maxCommitIterations", sessionContext.configContext @@ -551,7 +582,7 @@ function runProvisions( startRevision, endRevision, callback -) { +): void { let done = true; let allDeclarations = []; let allClear = []; @@ -616,7 +647,7 @@ function runVirtualParameters( startRevision, endRevision, callback -) { +): void { let done = true; const virtualParameterUpdates = []; let allDeclarations = []; @@ -660,7 +691,11 @@ function runVirtualParameters( return void (counter = 0); } - const ret = {}; + const ret: { + writable?: number; + value?: [string | number | boolean, string?]; + } = {}; + if (_returnValue.writable != null) { ret.writable = +!!_returnValue.writable; } else if ( @@ -758,7 +793,10 @@ function runVirtualParameters( } } -function runDeclarations(sessionContext, declarations) { +function runDeclarations( + sessionContext: SessionContext, + declarations +): VirtualParameterDeclaration[] { if (!sessionContext.syncState) { sessionContext.syncState = { refreshAttributes: { @@ -768,7 +806,7 @@ function runDeclarations(sessionContext, declarations) { value: new Set() }, spv: new Map(), - gpn: new Set(), + gpn: new Set(), gpnPatterns: new Map(), tags: new Map(), virtualParameterDeclarations: [], @@ -782,14 +820,20 @@ function runDeclarations(sessionContext, declarations) { } const allDeclareTimestamps = new Map(); - const allDeclareAttributeTimestamps = new Map(); - const allDeclareAttributeValues = new Map(); + const allDeclareAttributeTimestamps = new Map< + ParamPath, + AttributeTimestamps + >(); + const allDeclareAttributeValues = new Map(); const allVirtualParameters = localCache.getVirtualParameters( sessionContext.cacheSnapshot ); - function mergeAttributeTimestamps(p, attrs) { + function mergeAttributeTimestamps( + p: ParamPath, + attrs: AttributeTimestamps + ): void { let cur = allDeclareAttributeTimestamps.get(p); if (!cur) { allDeclareAttributeTimestamps.set(p, attrs); @@ -801,7 +845,11 @@ function runDeclarations(sessionContext, declarations) { } } - function mergeAttributeValues(p, attrs, defer) { + function mergeAttributeValues( + p: ParamPath, + attrs: AttributeValues, + defer: boolean + ): void { let cur = allDeclareAttributeValues.get(p); if (!cur) { if (!defer) allDeclareAttributeValues.set(p, attrs); @@ -816,19 +864,26 @@ function runDeclarations(sessionContext, declarations) { let unpacked; if ((path.alias | path.wildcard) & 1 || path[0] === "VirtualParameters") { - sessionContext.deviceData.paths.add(["VirtualParameters"]); + sessionContext.deviceData.paths.add(["VirtualParameters"] as ParamPath); if ((path.alias | path.wildcard) & 2) { - sessionContext.deviceData.paths.add(["VirtualParameters", "*"]); - for (const k of Object.keys(allVirtualParameters)) - sessionContext.deviceData.paths.add(["VirtualParameters", k]); + sessionContext.deviceData.paths.add([ + "VirtualParameters", + "*" + ] as ParamPath); + for (const k of Object.keys(allVirtualParameters)) { + sessionContext.deviceData.paths.add([ + "VirtualParameters", + k + ] as ParamPath); + } } } if ((path.alias | path.wildcard) & 1 || path[0] === "Reboot") - sessionContext.deviceData.paths.add(["Reboot"]); + sessionContext.deviceData.paths.add(["Reboot"] as ParamPath); if ((path.alias | path.wildcard) & 1 || path[0] === "FactoryReset") - sessionContext.deviceData.paths.add(["FactoryReset"]); + sessionContext.deviceData.paths.add(["FactoryReset"] as ParamPath); if (path.alias) { const aliasDecs = device.getAliasDeclarations( @@ -958,7 +1013,11 @@ function runDeclarations(sessionContext, declarations) { ); } -export function rpcRequest(sessionContext, _declarations, callback) { +export function rpcRequest( + sessionContext: SessionContext, + _declarations, + callback +): void { if (sessionContext.rpcRequest != null) { return void callback( null, @@ -1097,7 +1156,7 @@ export function rpcRequest(sessionContext, _declarations, callback) { // Multiply by two because every iteration is two // phases: read and update const MAX_ITERATIONS = - localCache.getConfig( + +localCache.getConfig( sessionContext.cacheSnapshot, "cwmp.maxCommitIterations", sessionContext.configContext @@ -1162,7 +1221,7 @@ export function rpcRequest(sessionContext, _declarations, callback) { for (const k of Object.keys(allVirtualParameters)) { toClear = device.set( sessionContext.deviceData, - ["VirtualParameters", k], + ["VirtualParameters", k] as ParamPath, timestamp, { object: [timestamp, 0] @@ -1272,7 +1331,7 @@ export function rpcRequest(sessionContext, _declarations, callback) { if (index == null) { index = 0; for (const p of sessionContext.deviceData.paths.find( - ["Downloads", "*"], + ["Downloads", "*"] as ParamPath, false, true )) { @@ -1285,7 +1344,7 @@ export function rpcRequest(sessionContext, _declarations, callback) { toClear = device.set( sessionContext.deviceData, - ["Downloads"], + ["Downloads"] as ParamPath, timestamp, { object: [timestamp, 1], writable: [timestamp, 1] }, toClear @@ -1293,7 +1352,7 @@ export function rpcRequest(sessionContext, _declarations, callback) { toClear = device.set( sessionContext.deviceData, - ["Downloads", "" + index], + ["Downloads", "" + index] as ParamPath, timestamp, { object: [timestamp, 1], writable: [timestamp, 1] }, toClear @@ -1327,7 +1386,7 @@ export function rpcRequest(sessionContext, _declarations, callback) { for (const [k, v] of Object.entries(params)) { toClear = device.set( sessionContext.deviceData, - ["Downloads", `${index}`, k], + ["Downloads", `${index}`, k] as ParamPath, timestamp, { object: [timestamp, 0], @@ -1340,7 +1399,7 @@ export function rpcRequest(sessionContext, _declarations, callback) { toClear = device.set( sessionContext.deviceData, - ["Downloads", `${index}`, "*"], + ["Downloads", `${index}`, "*"] as ParamPath, timestamp, null, toClear @@ -1445,7 +1504,7 @@ export function rpcRequest(sessionContext, _declarations, callback) { toClear = device.set( sessionContext.deviceData, - ["VirtualParameters", vparams[i][0]], + ["VirtualParameters", vparams[i][0]] as ParamPath, timestamp, vpu, toClear @@ -1458,7 +1517,7 @@ export function rpcRequest(sessionContext, _declarations, callback) { }); } -function generateGetRpcRequest(sessionContext) { +function generateGetRpcRequest(sessionContext: SessionContext): GetAcsRequest { const syncState = sessionContext.syncState; if (!syncState) return null; @@ -1482,7 +1541,10 @@ function generateGetRpcRequest(sessionContext) { } if (!found) { - const p = sessionContext.deviceData.paths.add(path.slice(0, -1)); + const p = sessionContext.deviceData.paths.add(path.slice( + 0, + -1 + ) as ParamPath); syncState.gpn.add(p); const f = 1 << p.length; syncState.gpnPatterns.set(p, f | syncState.gpnPatterns.get(p)); @@ -1510,7 +1572,10 @@ function generateGetRpcRequest(sessionContext) { } if (!found) { - const p = sessionContext.deviceData.paths.add(path.slice(0, -1)); + const p = sessionContext.deviceData.paths.add(path.slice( + 0, + -1 + ) as ParamPath); syncState.gpn.add(p); const f = 1 << p.length; syncState.gpnPatterns.set(p, f | syncState.gpnPatterns.get(p)); @@ -1519,7 +1584,10 @@ function generateGetRpcRequest(sessionContext) { syncState.refreshAttributes.object.clear(); for (const path of syncState.refreshAttributes.writable) { - const p = sessionContext.deviceData.paths.add(path.slice(0, -1)); + const p = sessionContext.deviceData.paths.add(path.slice( + 0, + -1 + ) as ParamPath); syncState.gpn.add(p); const f = 1 << p.length; syncState.gpnPatterns.set(p, f | syncState.gpnPatterns.get(p)); @@ -1613,7 +1681,7 @@ function generateGetRpcRequest(sessionContext) { return null; } -function generateSetRpcRequest(sessionContext) { +function generateSetRpcRequest(sessionContext): SetAcsRequest { const syncState = sessionContext.syncState; if (!syncState) return null; @@ -1653,19 +1721,23 @@ function generateSetRpcRequest(sessionContext) { sessionContext.configContext ); - const DATETIME_MILLISECONDS = localCache.getConfig( + const DATETIME_MILLISECONDS = !!localCache.getConfig( sessionContext.cacheSnapshot, "cwmp.datetimeMilliseconds", sessionContext.configContext ); - const BOOLEAN_LITERAL = localCache.getConfig( + const BOOLEAN_LITERAL = !!localCache.getConfig( sessionContext.cacheSnapshot, "cwmp.booleanLiteral", sessionContext.configContext ); - const parameterValues = []; + const parameterValues = [] as [ + ParamPath, + string | number | boolean, + string + ][]; for (const [k, v] of syncState.spv) { syncState.spv.delete(k); const attrs = sessionContext.deviceData.attributes.get(k); @@ -1693,7 +1765,14 @@ function generateSetRpcRequest(sessionContext) { if (parameterValues.length) { return { name: "SetParameterValues", - parameterList: parameterValues.map(p => [p[0].join("."), p[1], p[2]]), + parameterList: parameterValues.map( + p => + [p[0].join("."), p[1], p[2]] as [ + string, + string | number | boolean, + string + ] + ), DATETIME_MILLISECONDS: DATETIME_MILLISECONDS, BOOLEAN_LITERAL: BOOLEAN_LITERAL }; @@ -1764,7 +1843,13 @@ function generateSetRpcRequest(sessionContext) { function generateGetVirtualParameterProvisions( sessionContext, virtualParameterDeclarations -) { +): [ + ParamPath, + AttributeTimestamps, + AttributeValues, + AttributeTimestamps, + AttributeValues +][] { let provisions; if (virtualParameterDeclarations) { for (const declaration of virtualParameterDeclarations) { @@ -1804,7 +1889,13 @@ function generateGetVirtualParameterProvisions( function generateSetVirtualParameterProvisions( sessionContext, virtualParameterDeclarations -) { +): [ + ParamPath, + AttributeTimestamps, + AttributeValues, + AttributeTimestamps, + AttributeValues +][] { let provisions; if (virtualParameterDeclarations) { for (const declaration of virtualParameterDeclarations) { @@ -1850,21 +1941,27 @@ function generateSetVirtualParameterProvisions( function processDeclarations( sessionContext, allDeclareTimestamps, - allDeclareAttributeTimestamps, - allDeclareAttributeValues -) { + allDeclareAttributeTimestamps: Map, + allDeclareAttributeValues: Map +): VirtualParameterDeclaration[] { const deviceData = sessionContext.deviceData; const syncState = sessionContext.syncState; const root = sessionContext.deviceData.paths.add([]); const paths = deviceData.paths.find([], false, true, 99); - paths.sort((a, b) => - a.wildcard === b.wildcard ? a.length - b.length : a.wildcard - b.wildcard + paths.sort( + (a, b): number => + a.wildcard === b.wildcard ? a.length - b.length : a.wildcard - b.wildcard ); - const virtualParameterDeclarations = []; + const virtualParameterDeclarations = [] as VirtualParameterDeclaration[]; - function func(leafParam, leafIsObject, leafTimestamp, _paths) { + function func( + leafParam: ParamPath, + leafIsObject: number, + leafTimestamp: number, + _paths: ParamPath[] + ): void { const currentPath = _paths[0]; const children = new Map(); let declareTimestamp = 0; @@ -2122,7 +2219,11 @@ function processDeclarations( return virtualParameterDeclarations; } -function loadPath(sessionContext, path, depth) { +function loadPath( + sessionContext: SessionContext, + path: ParamPath, + depth?: number +): boolean { depth = depth || (1 << path.length) - 1; if (sessionContext.new || !depth) return true; @@ -2132,12 +2233,13 @@ function loadPath(sessionContext, path, depth) { let trimWildcard = path.length; while (trimWildcard && path[trimWildcard - 1] === "*") --trimWildcard; - if (trimWildcard < path.length) path = path.slice(0, trimWildcard); + if (trimWildcard < path.length) + path = path.slice(0, trimWildcard) as ParamPath; for (let i = 0; i <= path.length; ++i) { const d = i === path.length ? 99 : i; for (const sup of sessionContext.deviceData.paths.find( - path.slice(0, i), + path.slice(0, i) as ParamPath, true, false, d @@ -2165,7 +2267,7 @@ function processInstances( minInstances, maxInstances, defer -) { +): void { let instancesToCreate, instancesToDelete; if (parent[0] === "Downloads") { if (parent.length !== 1) return; @@ -2217,10 +2319,10 @@ function processInstances( } } -function clear(sessionContext, toClear, callback) { +function clear(sessionContext, toClear, callback): void { if (!toClear || !toClear.length) return void callback(); - const MAX_DEPTH = config.get("MAX_DEPTH", sessionContext.deviceId); + const MAX_DEPTH = +config.get("MAX_DEPTH", sessionContext.deviceId); for (const c of toClear) { if (c[1]) { @@ -2250,7 +2352,7 @@ function clear(sessionContext, toClear, callback) { }); } -export function rpcResponse(sessionContext, id, rpcRes, callback) { +export function rpcResponse(sessionContext, id, rpcRes, callback): void { if (id !== generateRpcId(sessionContext)) return void callback(new Error("Request ID not recognized")); @@ -2398,7 +2500,7 @@ export function rpcResponse(sessionContext, id, rpcRes, callback) { if (rpcReq.nextLevel) { loadPath(sessionContext, root, (1 << (root.length + 1)) - 1); } else { - const MAX_DEPTH = config.get("MAX_DEPTH", sessionContext.deviceId); + const MAX_DEPTH = +config.get("MAX_DEPTH", sessionContext.deviceId); loadPath(sessionContext, root, (1 << MAX_DEPTH) - 1); } @@ -2495,7 +2597,7 @@ export function rpcResponse(sessionContext, id, rpcRes, callback) { case "DownloadResponse": toClear = device.set( sessionContext.deviceData, - ["Downloads", rpcReq.instance, "Download"], + ["Downloads", rpcReq.instance, "Download"] as ParamPath, timestamp + 1, { value: [timestamp + 1, [sessionContext.timestamp, "xsd:dateTime"]] }, toClear @@ -2504,7 +2606,7 @@ export function rpcResponse(sessionContext, id, rpcRes, callback) { if (rpcRes.status === 0) { toClear = device.set( sessionContext.deviceData, - ["Downloads", rpcReq.instance, "LastDownload"], + ["Downloads", rpcReq.instance, "LastDownload"] as ParamPath, timestamp + 1, { value: [timestamp + 1, [sessionContext.timestamp, "xsd:dateTime"]] @@ -2514,7 +2616,7 @@ export function rpcResponse(sessionContext, id, rpcRes, callback) { toClear = device.set( sessionContext.deviceData, - ["Downloads", rpcReq.instance, "LastFileType"], + ["Downloads", rpcReq.instance, "LastFileType"] as ParamPath, timestamp + 1, { value: [timestamp + 1, [rpcReq.fileType, "xsd:string"]] }, toClear @@ -2522,7 +2624,7 @@ export function rpcResponse(sessionContext, id, rpcRes, callback) { toClear = device.set( sessionContext.deviceData, - ["Downloads", rpcReq.instance, "LastFileName"], + ["Downloads", rpcReq.instance, "LastFileName"] as ParamPath, timestamp + 1, { value: [timestamp + 1, [rpcReq.fileType, "xsd:string"]] }, toClear @@ -2530,7 +2632,7 @@ export function rpcResponse(sessionContext, id, rpcRes, callback) { toClear = device.set( sessionContext.deviceData, - ["Downloads", rpcReq.instance, "LastTargetFileName"], + ["Downloads", rpcReq.instance, "LastTargetFileName"] as ParamPath, timestamp + 1, { value: [timestamp + 1, [rpcReq.fileType, "xsd:string"]] }, toClear @@ -2538,7 +2640,7 @@ export function rpcResponse(sessionContext, id, rpcRes, callback) { toClear = device.set( sessionContext.deviceData, - ["Downloads", rpcReq.instance, "StartTime"], + ["Downloads", rpcReq.instance, "StartTime"] as ParamPath, timestamp + 1, { value: [timestamp + 1, [+rpcRes.startTime, "xsd:dateTime"]] }, toClear @@ -2546,7 +2648,7 @@ export function rpcResponse(sessionContext, id, rpcRes, callback) { toClear = device.set( sessionContext.deviceData, - ["Downloads", rpcReq.instance, "CompleteTime"], + ["Downloads", rpcReq.instance, "CompleteTime"] as ParamPath, timestamp + 1, { value: [timestamp + 1, [+rpcRes.completeTime, "xsd:dateTime"]] }, toClear @@ -2583,7 +2685,12 @@ export function rpcResponse(sessionContext, id, rpcRes, callback) { clear(sessionContext, toClear, callback); } -export function rpcFault(sessionContext, id, faultResponse, callback) { +export function rpcFault( + sessionContext, + id, + faultResponse, + callback: (err: Error, fault?: Fault) => void +): void { const rpcReq = sessionContext.rpcRequest; delete sessionContext.syncState; delete sessionContext.rpcRequest; @@ -2627,7 +2734,7 @@ export function rpcFault(sessionContext, id, faultResponse, callback) { callback(null, fault); } -export function deserialize(sessionContextString, callback) { +export function deserialize(sessionContextString, callback): void { const sessionContext = JSON.parse(sessionContextString); for (const decs of sessionContext.declarations) @@ -2654,7 +2761,7 @@ export function deserialize(sessionContextString, callback) { }); } -export function serialize(sessionContext, callback) { +export function serialize(sessionContext, callback): void { const deviceData = []; for (const path of sessionContext.deviceData.paths.find( diff --git a/lib/soap.js b/lib/soap.ts similarity index 83% rename from lib/soap.js rename to lib/soap.ts index 464775d..c4a963b 100644 --- a/lib/soap.js +++ b/lib/soap.ts @@ -16,11 +16,21 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -import libxmljs from "libxmljs"; +import { parseXml, Document, Element, ParserOptions } from "libxmljs"; import * as config from "./config"; import { version as VERSION } from "../package.json"; +import { + CpeResponse, + CpeGetResponse, + CpeSetResponse, + InformRequest, + AcsResponse, + CpeRequest, + FaultStruct, + SpvFault, + CpeFault +} from "./types"; const SERVER_NAME = `GenieACS/${VERSION}`; @@ -62,21 +72,36 @@ const NAMESPACES = { } }; -const LIBXMLJS_PARSE_OPTIONS = { +const LIBXMLJS_PARSE_OPTIONS: ParserOptions = { nocdata: true, - recover: config.get("XML_RECOVER"), - ignore_enc: config.get("XML_IGNORE_ENC") + recover: !!config.get("XML_RECOVER"), + /* eslint-disable-next-line @typescript-eslint/camelcase */ + ignore_enc: !!config.get("XML_IGNORE_ENC") }; -const LIBXMLJS_SAVE_OPTIONS = { - format: config.get("XML_FORMAT"), +interface WriterOptions { + declaration?: boolean; + format?: boolean; + selfCloseEmpty?: boolean; + whitespace?: boolean; + type?: "XML" | "HTML" | "XHTML"; +} + +declare module "libxmljs" { + interface Document { + toString(formatting: boolean | WriterOptions): string; + } +} + +const LIBXMLJS_SAVE_OPTIONS: WriterOptions = { + format: !!config.get("XML_FORMAT"), declaration: !config.get("XML_NO_DECL"), selfCloseEmpty: !config.get("XML_NO_EMPTY") }; let warnings; -function parseBool(v) { +function parseBool(v): boolean { v = "" + v; if (v === "true" || v === "TRUE" || v === "True" || v === "1") return true; else if (v === "false" || v === "FALSE" || v === "False" || v === "0") @@ -84,7 +109,7 @@ function parseBool(v) { else return null; } -function event(xml) { +function event(xml): string[] { return xml .childNodes() .filter(n => n.name() === "EventStruct") @@ -97,7 +122,7 @@ function event(xml) { ); } -function parameterInfoList(xml) { +function parameterInfoList(xml): [string, boolean][] { return xml .childNodes() .filter(e => e.name() === "ParameterInfoStruct") @@ -128,7 +153,9 @@ function parameterInfoList(xml) { }); } -function parameterValueList(xml) { +function parameterValueList( + xml +): [string, string | number | boolean, string][] { return xml .childNodes() .filter(e => e.name() === "ParameterValueStruct") @@ -181,13 +208,13 @@ function parameterValueList(xml) { }); } -function GetParameterNames(xml, methodRequest) { +function GetParameterNames(xml, methodRequest): void { const el = xml.node("cwmp:GetParameterNames"); el.node("ParameterPath").text(methodRequest.parameterPath); el.node("NextLevel").text(+methodRequest.nextLevel); } -function GetParameterNamesResponse(xml) { +function GetParameterNamesResponse(xml): CpeGetResponse { return { name: "GetParameterNamesResponse", parameterList: parameterInfoList( @@ -196,7 +223,7 @@ function GetParameterNamesResponse(xml) { }; } -function GetParameterValues(xml, methodRequest) { +function GetParameterValues(xml, methodRequest): void { const el = xml.node("cwmp:GetParameterValues").node("ParameterNames"); el.attr({ "soap-enc:arrayType": `xsd:string[${methodRequest.parameterNames.length}]` @@ -205,7 +232,7 @@ function GetParameterValues(xml, methodRequest) { for (const p of methodRequest.parameterNames) el.node("string").text(p); } -function GetParameterValuesResponse(xml) { +function GetParameterValuesResponse(xml): CpeGetResponse { return { name: "GetParameterValuesResponse", parameterList: parameterValueList( @@ -214,7 +241,7 @@ function GetParameterValuesResponse(xml) { }; } -function SetParameterValues(xml, methodRequest) { +function SetParameterValues(xml, methodRequest): void { const el = xml.node("cwmp:SetParameterValues"); const paramList = el.node("ParameterList"); paramList.attr({ @@ -244,7 +271,7 @@ function SetParameterValues(xml, methodRequest) { el.node("ParameterKey").text(methodRequest.parameterKey || ""); } -function SetParameterValuesResponse(xml) { +function SetParameterValuesResponse(xml): CpeSetResponse { return { name: "SetParameterValuesResponse", status: parseInt( @@ -256,13 +283,13 @@ function SetParameterValuesResponse(xml) { }; } -function AddObject(xml, methodRequest) { +function AddObject(xml, methodRequest): void { const el = xml.node("cwmp:AddObject"); el.node("ObjectName").text(methodRequest.objectName); el.node("ParameterKey").text(methodRequest.parameterKey || ""); } -function AddObjectResponse(xml) { +function AddObjectResponse(xml): CpeSetResponse { let instanceNumber, status; for (const c of xml.childNodes()) { switch (c.name()) { @@ -282,13 +309,13 @@ function AddObjectResponse(xml) { }; } -function DeleteObject(xml, methodRequest) { +function DeleteObject(xml, methodRequest): void { const el = xml.node("cwmp:DeleteObject"); el.node("ObjectName").text(methodRequest.objectName); el.node("ParameterKey").text(methodRequest.parameterKey || ""); } -function DeleteObjectResponse(xml) { +function DeleteObjectResponse(xml): CpeSetResponse { return { name: "DeleteObjectResponse", status: parseInt( @@ -300,28 +327,28 @@ function DeleteObjectResponse(xml) { }; } -function Reboot(xml, methodRequest) { +function Reboot(xml, methodRequest): void { const el = xml.node("cwmp:Reboot"); el.node("CommandKey").text(methodRequest.commandKey || ""); } -function RebootResponse() { +function RebootResponse(): CpeSetResponse { return { name: "RebootResponse" }; } -function FactoryReset(xml) { +function FactoryReset(xml): void { xml.node("cwmp:FactoryReset"); } -function FactoryResetResponse() { +function FactoryResetResponse(): CpeSetResponse { return { name: "FactoryResetResponse" }; } -function Download(xml, methodRequest) { +function Download(xml, methodRequest): void { const el = xml.node("cwmp:Download"); el.node("CommandKey").text(methodRequest.commandKey || ""); el.node("FileType").text(methodRequest.fileType); @@ -335,7 +362,7 @@ function Download(xml, methodRequest) { el.node("FailureURL").text(methodRequest.failureUrl || ""); } -function DownloadResponse(xml) { +function DownloadResponse(xml): CpeSetResponse { let status, startTime, completeTime; for (const c of xml.childNodes()) { switch (c.name()) { @@ -359,7 +386,7 @@ function DownloadResponse(xml) { }; } -function Inform(xml) { +function Inform(xml): InformRequest { let retryCount, evnt, parameterList; const deviceId = { Manufacturer: null, @@ -397,18 +424,18 @@ function Inform(xml) { }; } -function InformResponse(xml) { +function InformResponse(xml): void { xml .node("cwmp:InformResponse") .node("MaxEnvelopes") .text(1); } -function GetRPCMethods() { +function GetRPCMethods(): AcsResponse { return { name: "GetRPCMethods" }; } -function GetRPCMethodsResponse(xml, methodResponse) { +function GetRPCMethodsResponse(xml, methodResponse): void { const el = xml.node("cwmp:GetRPCMethodsResponse").node("MethodList"); el.attr({ "soap-enc:arrayType": `xsd:string[${methodResponse.methodList.length}]` @@ -417,7 +444,7 @@ function GetRPCMethodsResponse(xml, methodResponse) { for (const m of methodResponse.methodList) el.node("string").text(m); } -function TransferComplete(xml) { +function TransferComplete(xml): AcsResponse { let commandKey, _faultStruct, startTime, completeTime; for (const c of xml.childNodes()) { switch (c.name()) { @@ -445,11 +472,11 @@ function TransferComplete(xml) { }; } -function TransferCompleteResponse(xml) { +function TransferCompleteResponse(xml): void { xml.node("cwmp:TransferCompleteResponse").text(""); } -function RequestDownload(xml) { +function RequestDownload(xml): CpeRequest { return { name: "RequestDownload", fileType: xml @@ -459,12 +486,12 @@ function RequestDownload(xml) { }; } -function RequestDownloadResponse(xml) { +function RequestDownloadResponse(xml): void { xml.node("cwmp:RequestDownloadResponse").text(""); } -function faultStruct(xml) { - let faultCode, faultString, setParameterValuesFault, pn, fc, fs; +function faultStruct(xml): FaultStruct { + let faultCode, faultString, setParameterValuesFault: SpvFault[], pn, fc, fs; for (const c of xml.childNodes()) { switch (c.name()) { case "FaultCode": @@ -499,7 +526,7 @@ function faultStruct(xml) { return { faultCode, faultString, setParameterValuesFault }; } -function fault(xml) { +function fault(xml): CpeFault { let faultCode, faultString, detail; for (const c of xml.childNodes()) { switch (c.name()) { @@ -518,7 +545,18 @@ function fault(xml) { return { faultCode, faultString, detail }; } -export function request(data, cwmpVersion, warn) { +export function request( + data, + cwmpVersion, + warn +): { + id: string; + cwmpVersion: string; + sessionTimeout: number; + cpeRequest?: CpeRequest; + cpeFault?: CpeFault; + cpeResponse?: CpeResponse; +} { warnings = warn; const rpc = { @@ -526,12 +564,13 @@ export function request(data, cwmpVersion, warn) { cwmpVersion: cwmpVersion, sessionTimeout: null, cpeRequest: null, - cpeFault: null + cpeFault: null, + cpeResponse: null }; if (!data.length) return rpc; - const xml = libxmljs.parseXml(data, LIBXMLJS_PARSE_OPTIONS); + const xml = parseXml(data, LIBXMLJS_PARSE_OPTIONS); let headerElement, bodyElement; @@ -589,7 +628,7 @@ export function request(data, cwmpVersion, warn) { rpc.cpeRequest = Inform(methodElement); break; case "GetRPCMethods": - rpc.cpeRequest = GetRPCMethods(methodElement); + rpc.cpeRequest = GetRPCMethods(); break; case "TransferComplete": rpc.cpeRequest = TransferComplete(methodElement); @@ -613,16 +652,16 @@ export function request(data, cwmpVersion, warn) { rpc.cpeResponse = DeleteObjectResponse(methodElement); break; case "RebootResponse": - rpc.cpeResponse = RebootResponse(methodElement); + rpc.cpeResponse = RebootResponse(); break; case "FactoryResetResponse": - rpc.cpeResponse = FactoryResetResponse(methodElement); + rpc.cpeResponse = FactoryResetResponse(); break; case "DownloadResponse": rpc.cpeResponse = DownloadResponse(methodElement); break; case "Fault": - rpc.cpeFault = fault(methodElement, rpc.cwmpVersion); + rpc.cpeFault = fault(methodElement); break; default: throw new Error(`8000 Method not supported ${methodName}`); @@ -632,8 +671,8 @@ export function request(data, cwmpVersion, warn) { return rpc; } -function createSoapEnv(cwmpVersion) { - const xml = libxmljs.Document(); +function createSoapEnv(cwmpVersion: string): Element { + const xml = new Document(); const env = xml.node("soap-env:Envelope"); for (const prefix of Object.keys(NAMESPACES[cwmpVersion])) @@ -642,20 +681,20 @@ function createSoapEnv(cwmpVersion) { return env; } -export function response(rpc) { +export function response(rpc): { code: number; headers: {}; data: string } { const headers = { Server: SERVER_NAME, SOAPServer: SERVER_NAME }; - if (!rpc) return { code: 204, headers: headers, data: Buffer.allocUnsafe(0) }; + if (!rpc) return { code: 204, headers: headers, data: "" }; const env = createSoapEnv(rpc.cwmpVersion); const header = env.node("soap-env:Header"); header .node("cwmp:ID") .attr({ - "soap-env:mustUnderstand": 1 + "soap-env:mustUnderstand": "1" }) .text(rpc.id); @@ -664,16 +703,16 @@ export function response(rpc) { if (rpc.acsResponse) { switch (rpc.acsResponse.name) { case "InformResponse": - InformResponse(body, rpc.acsResponse); + InformResponse(body); break; case "GetRPCMethodsResponse": GetRPCMethodsResponse(body, rpc.acsResponse); break; case "TransferCompleteResponse": - TransferCompleteResponse(body, rpc.acsResponse); + TransferCompleteResponse(body); break; case "RequestDownloadResponse": - RequestDownloadResponse(body, rpc.acsResponse); + RequestDownloadResponse(body); break; default: throw new Error(`Unknown method response type ${rpc.acsResponse.name}`); @@ -699,7 +738,7 @@ export function response(rpc) { Reboot(body, rpc.acsRequest); break; case "FactoryReset": - FactoryReset(body, rpc.acsRequest); + FactoryReset(body); break; case "Download": Download(body, rpc.acsRequest); diff --git a/lib/types.ts b/lib/types.ts new file mode 100644 index 0000000..4c726cb --- /dev/null +++ b/lib/types.ts @@ -0,0 +1,305 @@ +import PathSet from "./path-set"; +import VersionedMap from "./versioned-map"; +import InstanceSet from "./instance-set"; +import { IncomingMessage, ServerResponse } from "http"; + +export interface ParamPath extends Array { + wildcard: number; + alias: number; +} + +export type Expression = string | number | boolean | null | any[]; + +export interface Fault { + code: string; + message: string; + detail?: { + name: string; + message: string; + stack?: string; + }; +} + +export interface SessionFault extends Fault { + channel: string; + timestamp: number; + provisions: string[][]; + retryNow?: boolean; + precondition?: boolean; + retries?: number; + expiry?: number; +} + +export interface Attributes { + object?: [number, 1 | 0]; + writable?: [number, 1 | 0]; + value?: [number, [string | number | boolean, string]]; +} + +export interface AttributeTimestamps { + object?: number; + writable?: number; + value?: number; +} + +export interface AttributeValues { + object?: boolean; + writable?: boolean; + value?: [string | number | boolean, string?]; +} + +export interface DeviceData { + paths: PathSet; + timestamps: VersionedMap; + attributes: VersionedMap; + loaded: Map; + trackers: Map; + changes: Set; +} + +export type VirtualParameterDeclaration = [ + ParamPath, + { path?: number; object?: number; writable?: number; value?: number }?, + { + path?: [number, number]; + object?: boolean; + writable?: boolean; + value?: [string | number | boolean, string?]; + }? +]; + +export interface SyncState { + refreshAttributes: { + exist: Set; + object: Set; + writable: Set; + value: Set; + }; + spv: Map; + gpn: Set; + gpnPatterns: Map; + tags: Map; + virtualParameterDeclarations: VirtualParameterDeclaration[][]; + instancesToDelete: Map>; + instancesToCreate: Map; + downloadsToDelete: Set; + downloadsToCreate: InstanceSet; + downloadsValues: Map; + downloadsDownload: Map; +} + +export interface SessionContext { + sessionId?: string; + timestamp: number; + deviceId: string; + deviceData: DeviceData; + cwmpVersion: string; + timeout: number; + provisions: any[]; + channels: { [channel: string]: number }; + virtualParameters: any[]; + revisions: number[]; + rpcCount: number; + iteration: number; + cycle: number; + extensionsCache: any; + declarations: any[]; + faults?: { [channel: string]: SessionFault }; + retries?: { [channel: string]: number }; + cacheSnapshot?: string; + configContext?: { [name: string]: any }; + httpResponse?: ServerResponse; + httpRequest?: IncomingMessage; + faultsTouched?: { [channel: string]: boolean }; + presetCycles?: number; + toLoad?: Map; + new?: boolean; + debug?: boolean; + tasks?: Task[]; + operations?: { [commandKey: string]: Operation }; + cacheUntil?: number; + syncState?: SyncState; + lastActivity?: number; + rpcRequest?: AcsRequest; + operationsTouched?: { [commandKey: string]: 1 | 0 }; + provisionsRet?: any[]; + doneTasks?: string[]; +} + +export interface Task { + _id: string; + name: string; + parameterNames?: string[]; + parameterValues?: [string, string | number | boolean, string?][]; + objectName?: string; + fileType?: string; + fileName?: string; + targetFileName?: string; + expiry?: number; +} + +export interface Operation { + name: string; + timestamp: number; + provisions: string[][]; + channels: { [channel: string]: number }; + retries: { [channel: string]: number }; + args: { + instance: string; + fileType: string; + fileName: string; + targetFileName: string; + }; +} + +export interface AcsRequest { + name: string; +} + +export interface GetAcsRequest extends AcsRequest { + name: "GetParameterNames" | "GetParameterValues"; + objectName?: string; + parameterNames?: string[]; + parameterPath?: string; + nextLevel?: boolean; +} + +export interface SetAcsRequest extends AcsRequest { + name: + | "SetParameterValues" + | "AddObject" + | "DeleteObject" + | "FactoryReset" + | "Reboot" + | "Download"; + parameterList?: [string, string | number | boolean, string][]; + instanceValues?: { [param: string]: string | number | boolean }; + objectName?: string; + next?: string; + DATETIME_MILLISECONDS?: boolean; + BOOLEAN_LITERAL?: boolean; + commandKey?: string; + instance?: string; + fileType?: string; + fileSize?: number; + url?: string; + fileName?: string; + targetFileName?: string; +} + +export interface CpeResponse { + name: string; +} + +export interface SpvFault { + parameterName: string; + faultCode: string; + faultString: string; +} + +export interface FaultStruct { + faultCode: string; + faultString: string; + setParameterValuesFault?: SpvFault[]; +} + +export interface CpeFault { + faultCode: string; + faultString: string; + detail?: FaultStruct; +} + +export interface CpeGetResponse extends CpeResponse { + name: "GetParameterNamesResponse" | "GetParameterValuesResponse"; + parameterList?: + | [string, boolean][] + | [string, string | number | boolean, string][]; +} + +export interface CpeSetResponse extends CpeResponse { + name: + | "SetParameterValuesResponse" + | "AddObjectResponse" + | "DeleteObjectResponse" + | "RebootResponse" + | "FactoryResetResponse" + | "DownloadResponse"; + status?: number; + instanceNumber?: string; + startTime?: number; + completeTime?: number; +} + +export interface CpeRequest { + name: string; + fileType?: string; +} + +export interface InformRequest extends CpeRequest { + name: "Inform"; + deviceId: { + Manufacturer: string; + OUI: string; + ProductClass?: string; + SerialNumber: string; + }; + event: string[]; + retryCount: number; + parameterList: [string, string | number | boolean, string][]; +} + +export interface AcsResponse { + name: string; + commandKey?: string; + faultStruct?: FaultStruct; + startTime?: number; + completeTime?: number; +} + +export interface QueryOptions { + projection?: any; + skip?: number; + limit?: number; + sort?: { + [param: string]: number; + }; +} + +export interface Declaration { + path: ParamPath; + pathGet: number; + pathSet?: [number, number]; + attrGet?: { object?: number; writable?: number; value?: number }; + attrSet?: { + object?: boolean; + writable?: boolean; + value?: [string | number | boolean, string?]; + }; + defer: boolean; +} + +export type Clear = [ + ParamPath, + number, + { object?: number; writable?: number; value?: number }?, + number? +]; + +export interface Preset { + name: string; + channel: string; + schedule?: { md5: string; duration: number; schedule: any }; + events?: { [event: string]: boolean }; + precondition?: {}; + provisions: string[][]; +} + +export type PermissionSet = { + [resource: string]: { + access: number; + validate?: { + [validator: string]: boolean; + }; + filter: Expression; + }; +}[]; diff --git a/lib/ui.js b/lib/ui.ts similarity index 90% rename from lib/ui.js rename to lib/ui.ts index c88ab6d..36826a9 100644 --- a/lib/ui.js +++ b/lib/ui.ts @@ -1,5 +1,3 @@ -"use strict"; - import { Z_SYNC_FLUSH } from "zlib"; import Koa from "koa"; import Router from "koa-router"; @@ -14,14 +12,21 @@ import Authorizer from "./common/authorizer"; import { parse } from "./common/expression-parser"; import * as logger from "./logger"; import * as localCache from "./local-cache"; +import { PermissionSet } from "./types"; + +declare module "koa" { + interface Request { + body: any; + } +} const koa = new Koa(); const router = new Router(); -const JWT_SECRET = config.get("UI_JWT_SECRET"); +const JWT_SECRET = "" + config.get("UI_JWT_SECRET"); const JWT_COOKIE = "genieacs-ui-jwt"; -function getPermissionSets(ctx) { +function getPermissionSets(ctx): PermissionSet[] { const allPermissions = localCache.getPermissionsConfig( ctx.state.configSnapshot ); @@ -50,9 +55,9 @@ function getPermissionSets(ctx) { return permissionSets; } -function authSimple(ctx, username, password) { +function authSimple(ctx, username, password): Promise { const authConfig = localCache.getAuthConfig(ctx.state.configSnapshot); - const user = authConfig.simple.users[username]; + const user = authConfig["simple"].users[username]; if (user && user.password === password) { const roles = user.roles.split(",").map(s => s.trim()); return Promise.resolve(roles); @@ -100,10 +105,11 @@ router.post("/login", async ctx => { const log = { message: "Log in", context: ctx, - username: username + username: username, + method: null }; - function success(roles, method) { + function success(roles, method): void { log.method = method; const token = jwt.sign({ username, roles }, JWT_SECRET); ctx.cookies.set(JWT_COOKIE, token); @@ -111,7 +117,7 @@ router.post("/login", async ctx => { logger.accessInfo(log); } - function failure() { + function failure(): void { ctx.status = 400; ctx.body = "Incorrect username or password"; log.message += " failed"; diff --git a/lib/ui/api-functions.js b/lib/ui/api-functions.ts similarity index 90% rename from lib/ui/api-functions.js rename to lib/ui/api-functions.ts index d4b2cb8..dfa58b2 100644 --- a/lib/ui/api-functions.js +++ b/lib/ui/api-functions.ts @@ -1,9 +1,7 @@ -"use strict"; - +import { exec } from "child_process"; +import { ObjectID } from "mongodb"; import * as db from "./db"; import { del } from "../cache"; -import { ObjectID } from "mongodb"; -import { exec } from "child_process"; import { insertTasks, watchTask, @@ -11,7 +9,7 @@ import { deleteDevice } from "../api-functions"; -function deleteFault(id) { +function deleteFault(id): Promise { const deviceId = id.split(":", 1)[0]; const channel = id.slice(deviceId.length + 1); return new Promise((resolve, reject) => { @@ -30,7 +28,7 @@ function deleteFault(id) { }); } -export function deleteResource(resource, id) { +export function deleteResource(resource, id): Promise { return new Promise((resolve, reject) => { let promise; @@ -80,7 +78,11 @@ export function deleteResource(resource, id) { }); } -export function postTasks(deviceId, tasks, timeout) { +export function postTasks( + deviceId, + tasks, + timeout +): Promise<{ connectionRequest: string; tasks: any[] }> { return new Promise((resolve, reject) => { for (const task of tasks) task.device = deviceId; @@ -139,7 +141,17 @@ export function postTasks(deviceId, tasks, timeout) { }); } -export function ping(host) { +interface PingResponse { + packetsTransmitted: number; + packetsReceived: number; + packetLoss: string; + min: number; + avg: number; + max: number; + mdev: number; +} + +export function ping(host): Promise { return new Promise((resolve, reject) => { exec(`ping -w 1 -i 0.2 -c 3 ${host}`, (err, stdout) => { if (err) return void reject(err); @@ -162,7 +174,7 @@ export function ping(host) { }); } -export function putResource(resource, id, data) { +export function putResource(resource, id, data): Promise { return new Promise((resolve, reject) => { let promise; diff --git a/lib/ui/api.js b/lib/ui/api.ts similarity index 95% rename from lib/ui/api.js rename to lib/ui/api.ts index 0f8b6cc..a43e1c3 100644 --- a/lib/ui/api.js +++ b/lib/ui/api.ts @@ -1,6 +1,4 @@ -"use strict"; - -import stream from "stream"; +import * as stream from "stream"; import Router from "koa-router"; import * as db from "./db"; import * as apiFunctions from "./api-functions"; @@ -8,11 +6,12 @@ import { evaluate, and, extractParams } from "../common/expression"; import { parse } from "../common/expression-parser"; import * as logger from "../logger"; import { getConfig } from "../local-cache"; +import { QueryOptions, Expression } from "../types"; const router = new Router(); export default router; -function logUnauthorizedWarning(log) { +function logUnauthorizedWarning(log): void { log.message += " not authorized"; logger.accessWarn(log); } @@ -91,13 +90,14 @@ router.get(`/devices/:id.csv`, async ctx => { for (const [resource, flags] of Object.entries(resources)) { router.head(`/${resource}`, async (ctx, next) => { - let filter = true; + let filter: Expression = true; if (ctx.request.query.filter) filter = parse(ctx.request.query.filter); const log = { message: `Count ${resource}`, context: ctx, - filter: ctx.request.query.filter + filter: ctx.request.query.filter, + count: null }; if (!ctx.state.authorizer.hasAccess(resource, 1)) { @@ -115,7 +115,7 @@ for (const [resource, flags] of Object.entries(resources)) { const count = await db.count(resource, filter); - ctx.set("X-Total-Count", count); + ctx.set("X-Total-Count", `${count}`); ctx.body = ""; log.count = count; @@ -123,8 +123,8 @@ for (const [resource, flags] of Object.entries(resources)) { }); router.get(`/${resource}`, async (ctx, next) => { - const options = {}; - let filter = true; + const options: QueryOptions = {}; + let filter: Expression = true; if (ctx.request.query.filter) filter = parse(ctx.request.query.filter); if (ctx.request.query.limit) options.limit = +ctx.request.query.limit; if (ctx.request.query.skip) options.skip = +ctx.request.query.skip; @@ -174,8 +174,8 @@ for (const [resource, flags] of Object.entries(resources)) { // CSV download router.get(`/${resource}.csv`, async (ctx, next) => { - const options = { projection: {} }; - let filter = true; + const options: QueryOptions = { projection: {} }; + let filter: Expression = true; if (ctx.request.query.filter) filter = parse(ctx.request.query.filter); if (ctx.request.query.limit) options.limit = +ctx.request.query.limit; if (ctx.request.query.skip) options.skip = +ctx.request.query.skip; @@ -356,9 +356,9 @@ for (const [resource, flags] of Object.entries(resources)) { return void (ctx.status = 403); } - const err = await apiFunctions.putResource(resource, id, obj); - - if (err) { + try { + await apiFunctions.putResource(resource, id, obj); + } catch (err) { log.message += " failed"; logger.accessWarn(log); ctx.body = err; @@ -379,7 +379,8 @@ router.put("/files/:id", async (ctx, next) => { const log = { message: `Upload ${resource}`, context: ctx, - id: id + id: id, + metadata: null }; const authorizer = ctx.state.authorizer; @@ -412,7 +413,8 @@ router.post("/devices/:id/tasks", async (ctx, next) => { const log = { message: "Commit tasks", context: ctx, - deviceId: ctx.params.id + deviceId: ctx.params.id, + tasks: null }; const authorizer = ctx.state.authorizer; diff --git a/lib/ui/db.js b/lib/ui/db.ts similarity index 85% rename from lib/ui/db.js rename to lib/ui/db.ts index 2f1d62f..039eeb3 100644 --- a/lib/ui/db.js +++ b/lib/ui/db.ts @@ -1,10 +1,9 @@ -"use strict"; - import { MongoClient, GridFSBucket } from "mongodb"; import * as config from "../config"; import * as mongodbFunctions from "./mongodb-functions"; import * as expression from "../common/expression"; import { preProcessPreset } from "./mongodb-functions"; +import { QueryOptions } from "../types"; const CACHE_TTL = 300000; @@ -14,17 +13,17 @@ const RESOURCE_COLLECTION = { files: "fs.files" }; -function ensureIndexes(client) { +function ensureIndexes(client): void { client .db() .collection("cache") .createIndex({ expire: 1 }, { expireAfterSeconds: 0 }); } -function getClient() { +function getClient(): Promise { if (!_clientPromise) { _clientPromise = new Promise((resolve, reject) => { - const CONNECTION_URL = config.get("MONGODB_CONNECTION_URL"); + const CONNECTION_URL = "" + config.get("MONGODB_CONNECTION_URL"); MongoClient.connect( CONNECTION_URL, { useNewUrlParser: true }, @@ -40,14 +39,14 @@ function getClient() { return _clientPromise; } -export function cache(key, valueGetter, ttl) { +export function cache(key, valueGetter: () => Promise, ttl): Promise { return new Promise((resolve, reject) => { getClient() .then(client => { const collection = client.db().collection("cache"); collection.findOne({ _id: key }, (err, doc) => { if (err) return void reject(err); - if (doc != null) return void resolve(JSON.parse(doc.value)); + if (doc != null) return void resolve(JSON.parse(doc.value) as T); valueGetter() .then(res => { const expire = Date.now() + (ttl || CACHE_TTL); @@ -73,7 +72,12 @@ export function cache(key, valueGetter, ttl) { }); } -export function query(resource, filter, options, callback) { +export function query( + resource, + filter, + options?: QueryOptions, + callback?: (doc: any) => void +): Promise { options = options || {}; let q; filter = expression.evaluate(filter, null, Date.now()); @@ -159,7 +163,7 @@ export function query(resource, filter, options, callback) { }); } -export function count(resource, filter) { +export function count(resource, filter): Promise { let q; filter = expression.evaluate(filter, null, Date.now()); @@ -188,7 +192,7 @@ export function count(resource, filter) { }); } -export function updateDeviceTags(deviceId, tags) { +export function updateDeviceTags(deviceId, tags): Promise { return new Promise((resolve, reject) => { const add = []; const pull = []; @@ -213,7 +217,7 @@ export function updateDeviceTags(deviceId, tags) { }); } -function putResource(resource, id, object) { +function putResource(resource, id, object): Promise { return new Promise((resolve, reject) => { getClient() .then(client => { @@ -229,7 +233,7 @@ function putResource(resource, id, object) { }); } -function deleteResource(resource, id) { +function deleteResource(resource, id): Promise { return new Promise((resolve, reject) => { getClient() .then(client => { @@ -245,40 +249,40 @@ function deleteResource(resource, id) { }); } -export function putPreset(id, object) { +export function putPreset(id, object): Promise { object = preProcessPreset(object); return putResource("presets", id, object); } -export function deletePreset(id) { +export function deletePreset(id): Promise { return deleteResource("presets", id); } -export function putProvision(id, object) { +export function putProvision(id, object): Promise { return putResource("provisions", id, object); } -export function deleteProvision(id) { +export function deleteProvision(id): Promise { return deleteResource("provisions", id); } -export function putVirtualParameter(id, object) { +export function putVirtualParameter(id, object): Promise { return putResource("virtualParameters", id, object); } -export function deleteVirtualParameter(id) { +export function deleteVirtualParameter(id): Promise { return deleteResource("virtualParameters", id); } -export function putConfig(id, object) { +export function putConfig(id, object): Promise { return putResource("config", id, object); } -export function deleteConfig(id) { +export function deleteConfig(id): Promise { return deleteResource("config", id); } -export function putFile(filename, metadata, contentStream) { +export function putFile(filename, metadata, contentStream): Promise { return new Promise((resolve, reject) => { getClient() .then(client => { @@ -295,7 +299,7 @@ export function putFile(filename, metadata, contentStream) { }); } -export function deleteFile(filename) { +export function deleteFile(filename): Promise { return new Promise((resolve, reject) => { getClient() .then(client => { @@ -309,15 +313,15 @@ export function deleteFile(filename) { }); } -export function deleteFault(id) { +export function deleteFault(id): Promise { return deleteResource("faults", id); } -export function deleteTask(id) { +export function deleteTask(id): Promise { return deleteResource("tasks", id); } -export function disconnect() { +export function disconnect(): void { if (_clientPromise) { _clientPromise.then(client => { client.close(); diff --git a/lib/ui/mongodb-functions.js b/lib/ui/mongodb-functions.ts similarity index 92% rename from lib/ui/mongodb-functions.js rename to lib/ui/mongodb-functions.ts index 04d2e9e..058fd29 100644 --- a/lib/ui/mongodb-functions.js +++ b/lib/ui/mongodb-functions.ts @@ -1,11 +1,11 @@ -"use strict"; import { ObjectID } from "mongodb"; import { map, parse, stringify } from "../common/expression-parser"; import { likePatternToRegExp, evaluate } from "../common/expression"; +import { Expression, Fault, Task } from "../types"; const isArray = Array.isArray; -export function processDeviceFilter(filter) { +export function processDeviceFilter(filter): Expression { return map(filter, exp => { if (!isArray(exp)) return exp; @@ -46,7 +46,7 @@ export function processDeviceFilter(filter) { }); if (typeof e[2] === "number") { - const alt = e.slice(); + const alt = (e as any[]).slice(); alt[2] = new Date(e[2]); e = ["OR", e, alt]; } @@ -56,7 +56,7 @@ export function processDeviceFilter(filter) { }); } -export function processTasksFilter(filter) { +export function processTasksFilter(filter): Expression { return map(filter, exp => { if (!isArray(exp)) return exp; if (["=", "<>", ">", ">=", "<", "<="].includes(exp[0])) { @@ -72,7 +72,7 @@ export function processTasksFilter(filter) { }); } -export function processFaultsFilter(filter) { +export function processFaultsFilter(filter): Expression { return map(filter, exp => { if (!isArray(exp)) return exp; if (["=", "<>", ">", ">=", "<", "<="].includes(exp[0])) { @@ -86,7 +86,7 @@ export function processFaultsFilter(filter) { }); } -export function filterToMongoQuery(exp) { +export function filterToMongoQuery(exp: Expression): {} { const ops = { OR: 0, AND: 0, @@ -103,7 +103,7 @@ export function filterToMongoQuery(exp) { "IS NOT NULL": 1 }; - function recursive(filter, negate, res = {}) { + function recursive(filter, negate, res = {}): {} { const op = filter[0]; if (ops[op] === 0) { @@ -219,7 +219,7 @@ export function filterToMongoQuery(exp) { return recursive(_exp, false); } -export function processDeviceProjection(projection) { +export function processDeviceProjection(projection: {}): {} { if (!projection) return projection; const p = {}; for (const [k, v] of Object.entries(projection)) { @@ -245,7 +245,7 @@ export function processDeviceProjection(projection) { return p; } -export function processDeviceSort(sort) { +export function processDeviceSort(sort: {}): {} { if (!sort) return sort; const s = {}; for (const [k, v] of Object.entries(sort)) { @@ -261,13 +261,24 @@ export function processDeviceSort(sort) { return s; } -function parseDate(d) { +function parseDate(d): number | string { const n = +d; return isNaN(n) ? "" + d : n; } -export function flattenDevice(device) { - function recursive(input, root, output, timestamp) { +interface FlatDevice { + [param: string]: { + object: boolean; + objectTimestamp: number; + writable: boolean; + writableTimestamp: number; + value: [string | number | boolean, string]; + valueTimestamp: number; + }; +} + +export function flattenDevice(device): FlatDevice { + function recursive(input, root, output, timestamp): void { for (const [name, tree] of Object.entries(input)) { if (!root) { if (name === "_lastInform") { @@ -356,7 +367,7 @@ export function flattenDevice(device) { objectTimestamp: timestamp }; - for (const t of tree) { + for (const t of tree as string[]) { output[`Tags.${t}`] = { value: [true, "xsd:boolean"], valueTimestamp: timestamp, @@ -410,14 +421,14 @@ export function flattenDevice(device) { return newDevice; } -export function flattenFault(fault) { +export function flattenFault(fault): Fault { const f = Object.assign({}, fault); if (f.timestamp) f.timestamp = +f.timestamp; if (f.expiry) f.expiry = +f.expiry; return f; } -export function flattenTask(task) { +export function flattenTask(task): Task { const t = Object.assign({}, task); t._id = "" + t._id; if (t.timestamp) t.timestamp = +t.timestamp; @@ -425,9 +436,9 @@ export function flattenTask(task) { return t; } -function mongoQueryToFilter(query) { +function mongoQueryToFilter(query): Expression { const expressions = []; - function recursive(_query) { + function recursive(_query): void { for (const [k, v] of Object.entries(_query)) { if (k[0] === "$") { if (k === "$and") for (const vv of Object.values(v)) recursive(vv); @@ -492,7 +503,7 @@ function mongoQueryToFilter(query) { return expressions; } -export function flattenPreset(preset) { +export function flattenPreset(preset): {} { const p = Object.assign({}, preset); if (p.precondition) { p.precondition = mongoQueryToFilter(JSON.parse(p.precondition)); @@ -521,7 +532,7 @@ export function flattenPreset(preset) { return p; } -export function flattenFile(file) { +export function flattenFile(file): {} { const f = {}; f["_id"] = file["_id"]; if (file.metadata) { @@ -533,7 +544,7 @@ export function flattenFile(file) { return f; } -export function preProcessPreset(data) { +export function preProcessPreset(data): {} { const preset = Object.assign({}, data); preset.precondition = preset.precondition ? filterToMongoQuery(parse(preset.precondition)) @@ -561,7 +572,8 @@ export function preProcessPreset(data) { const configuration = { type: "provision", - name: preset.provision + name: preset.provision, + args: null }; if (preset.provisionArgs) diff --git a/lib/versioned-map.js b/lib/versioned-map.ts similarity index 78% rename from lib/versioned-map.js rename to lib/versioned-map.ts index 5f8591b..951ab1e 100644 --- a/lib/versioned-map.js +++ b/lib/versioned-map.ts @@ -16,44 +16,53 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -const NONEXISTENT = new Object(); +const NONEXISTENT = Symbol(); const UNDEFINED = undefined; -export default class VersionedMap { - constructor() { +interface Revisions { + [rev: number]: V; + delete?: number; +} + +export default class VersionedMap { + private _sizeDiff: number[]; + private _revision: number; + private map: Map; + public dirty: number; + + public constructor() { this._sizeDiff = [0]; this._revision = 0; this.map = new Map(); this.dirty = 0; } - get size() { + public get size(): number { return this.map.size + this._sizeDiff[this.revision]; } - get revision() { + public get revision(): number { return this._revision; } - set revision(rev) { + public set revision(rev) { for (let i = this._sizeDiff.length; i <= rev; ++i) this._sizeDiff[i] = this._sizeDiff[i - 1]; this._revision = rev; } - get(key, rev = this._revision) { + public get(key: K, rev = this._revision): V { const revisions = this.map.get(key); if (!revisions) return UNDEFINED; const v = revisions[Math.min(revisions.length - 1, rev)]; if (v === NONEXISTENT) return UNDEFINED; - return v; + return v as V; } - has(key, rev = this._revision) { + public has(key: K, rev = this._revision): boolean { const revisions = this.map.get(key); if (!revisions) return false; @@ -62,7 +71,7 @@ export default class VersionedMap { return true; } - set(key, value, rev = this._revision) { + public set(key: K, value: V, rev = this._revision): this { let revisions = this.map.get(key); if (!revisions) { this.dirty |= 1 << rev; @@ -72,7 +81,7 @@ export default class VersionedMap { for (let i = 0; i < rev; ++i) revisions[i] = NONEXISTENT; revisions[rev] = value; this.map.set(key, revisions); - return true; + return this; } // Can't modify old revisions @@ -86,10 +95,10 @@ export default class VersionedMap { for (let i = revisions.length; i < rev; ++i) revisions[i] = old; revisions[rev] = value; - return true; + return this; } - delete(key, rev = this._revision) { + public delete(key: K, rev = this._revision): boolean { const revisions = this.map.get(key); if (!revisions) return false; @@ -108,24 +117,24 @@ export default class VersionedMap { return true; } - getRevisions(key) { + public getRevisions(key: K): Revisions { const revisions = this.map.get(key); if (!revisions) return null; - const res = {}; + const res: Revisions = {}; - let prev = NONEXISTENT; + let prev: V | symbol = NONEXISTENT; for (const [i, v] of revisions.entries()) { if (v === prev) continue; if (v === NONEXISTENT) res.delete |= 1 << i; - else res[i] = v; + else res[i] = v as V; prev = v; } return res; } - setRevisions(key, revisionsObj) { + public setRevisions(key: K, revisionsObj: Revisions): void { const del = revisionsObj.delete || 0; const maxRev = Object.keys(revisionsObj).reduce( (acc, cur) => (+cur > acc ? +cur : acc), @@ -134,7 +143,7 @@ export default class VersionedMap { const revisions = []; - let prev = NONEXISTENT; + let prev: V | symbol = NONEXISTENT; for (let i = 0; i <= maxRev; ++i) { let v = prev; if (del & (1 << i)) v = NONEXISTENT; @@ -147,28 +156,28 @@ export default class VersionedMap { this.map.set(key, revisions); } - getDiff(key) { + public getDiff(key: K): [V, V] { const revisions = this.map.get(key); if (!revisions) return [UNDEFINED, UNDEFINED]; let first = revisions[0]; if (first === NONEXISTENT) first = UNDEFINED; let last = revisions[revisions.length - 1]; if (last === NONEXISTENT) last = UNDEFINED; - return [first, last]; + return [first as V, last as V]; } - *diff() { + public *diff(): IterableIterator<[K, V, V]> { for (const [key, revisions] of this.map) { let first = revisions[0]; let last = revisions[revisions.length - 1]; - if ((first === last) === NONEXISTENT) continue; + if (first === NONEXISTENT && last === NONEXISTENT) continue; if (first === NONEXISTENT) first = UNDEFINED; if (last === NONEXISTENT) last = UNDEFINED; - yield [key, first, last]; + yield [key, first as V, last as V]; } } - collapse(revision) { + public collapse(revision: number): void { if (this._sizeDiff.length <= revision) return; this._sizeDiff[revision] = this._sizeDiff[this._sizeDiff.length - 1]; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 964690b..e20e082 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -4,6 +4,48 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@ava/babel-plugin-throws-helper": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-3.0.0.tgz", + "integrity": "sha512-mN9UolOs4WX09QkheU1ELkVy2WPnwonlO3XMdN8JF8fQqRVgVTR21xDbvEOUsbwz6Zwjq7ji9yzyjuXqDPalxg==", + "dev": true + }, + "@ava/babel-preset-stage-4": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ava/babel-preset-stage-4/-/babel-preset-stage-4-2.0.0.tgz", + "integrity": "sha512-OWqMYeTSZ16AfLx0Vn0Uj7tcu+uMRlbKmks+DVCFlln7vomVsOtst+Oz+HCussDSFGpE+30VtHAUHLy6pLDpHQ==", + "dev": true, + "requires": { + "@babel/plugin-proposal-async-generator-functions": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-dotall-regex": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0" + } + }, + "@ava/babel-preset-transform-test-files": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-4.0.1.tgz", + "integrity": "sha512-D7Z92B8Rgsj35JZveKJGwpUDuBKLiRKH6eyKpNmDHy7TJjr8y3VSDr3bUK+O456F3SkkBXrUihQuMrr39nWQhQ==", + "dev": true, + "requires": { + "@ava/babel-plugin-throws-helper": "^3.0.0", + "babel-plugin-espower": "^3.0.1" + } + }, + "@ava/write-file-atomic": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ava/write-file-atomic/-/write-file-atomic-2.2.0.tgz", + "integrity": "sha512-BTNB3nGbEfJT+69wuqXFr/bQH7Vr7ihx2xGOMNqPgDGhwspoZhiWumDDZNjBy7AScmqS5CELIOGtPVXESyrnDA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + }, "@babel/code-frame": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", @@ -13,6 +55,194 @@ "@babel/highlight": "^7.0.0" } }, + "@babel/core": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.3.3.tgz", + "integrity": "sha512-w445QGI2qd0E0GlSnq6huRZWPMmQGCp5gd5ZWS4hagn0EiwzxD5QMFkpchyusAyVC1n27OKXzQ0/88aVU9n4xQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.3", + "@babel/helpers": "^7.2.0", + "@babel/parser": "^7.3.3", + "@babel/template": "^7.2.2", + "@babel/traverse": "^7.2.2", + "@babel/types": "^7.3.3", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.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" + } + } + } + }, + "@babel/generator": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.3.tgz", + "integrity": "sha512-aEADYwRRZjJyMnKN7llGIlircxTCofm3dtV5pmY6ob18MSIuipHpA2yZWkPlycwu5HJcx/pADS3zssd8eY7/6A==", + "dev": true, + "requires": { + "@babel/types": "^7.3.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.2.2.tgz", + "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/template": "^7.2.2", + "@babel/types": "^7.2.2", + "lodash": "^4.17.10" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.0.0.tgz", + "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "dev": true, + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } + }, + "@babel/helpers": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.3.1.tgz", + "integrity": "sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA==", + "dev": true, + "requires": { + "@babel/template": "^7.1.2", + "@babel/traverse": "^7.1.5", + "@babel/types": "^7.3.0" + } + }, "@babel/highlight": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", @@ -24,15 +254,654 @@ "js-tokens": "^4.0.0" } }, + "@babel/parser": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.3.tgz", + "integrity": "sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.2.tgz", + "integrity": "sha512-DjeMS+J2+lpANkYLLO+m6GjoTMygYglKmRe6cDTbFv3L9i6mmiE8fe6B8MtCSLZpVXscD5kn7s6SgtHrDoBWoA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.2.0.tgz", + "integrity": "sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.2.0.tgz", + "integrity": "sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.2.0.tgz", + "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" + } + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "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" + } + } + } + }, + "@babel/types": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.3.tgz", + "integrity": "sha512-2tACZ80Wg09UnPg5uGAOUvvInaqLk3l/IAhQzlxLQOIXacr6bMsra5SH6AWw/hIDRCSbCdHP2KzSOD+cT7TzMQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@concordance/react": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@concordance/react/-/react-2.0.0.tgz", + "integrity": "sha512-huLSkUuM2/P+U0uy2WwlKuixMsTODD8p4JVQBI4VKeopkiN0C7M3N9XYVawb4M+4spN5RrO/eLhk7KoQX6nsfA==", + "dev": true, + "requires": { + "arrify": "^1.0.1" + } + }, + "@types/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/body-parser": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", + "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/bson": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.0.tgz", + "integrity": "sha512-pq/rqJwJWkbS10crsG5bgnrisL8pML79KlMKQMoQwLUjlPAkrUHMvHJ3oGwE7WHR61Lv/nadMwXVAD2b+fpD8Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.32", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", + "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/cookies": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.1.tgz", + "integrity": "sha512-ku6IvbucEyuC6i4zAVK/KnuzWNXdbFd1HkXlNLg/zhWDGTtQT5VhumiPruB/BHW34PWVFwyfwGftDQHfWNxu3Q==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/express": "*", + "@types/keygrip": "*", + "@types/node": "*" + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/express": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.16.1.tgz", + "integrity": "sha512-V0clmJow23WeyblmACoxbHBu2JKlE5TiIme6Lem14FnPW9gsttyHtk6wq7njcdIWH1njAaFgR8gW09lgY98gQg==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.1.tgz", + "integrity": "sha512-QgbIMRU1EVRry5cIu1ORCQP4flSYqLM1lS5LYyGWfKnFT3E58f0gKto7BR13clBFVrVZ0G0rbLZ1hUpSkgQQOA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/range-parser": "*" + } + }, + "@types/http-assert": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.4.0.tgz", + "integrity": "sha512-TZDqvFW4nQwL9DVSNJIJu4lPLttKgzRF58COa7Vs42Ki/MrhIqUbeIw0MWn4kGLiZLXB7oCBibm7nkSjPkzfKQ==", + "dev": true + }, + "@types/jsonwebtoken": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz", + "integrity": "sha512-YKnUTR4VxwljbPORPrRon9E3uel1aD8nUdvzqArCCdMTWPvo0gnI2UZkwIHN2QATdj6HYXV/Iq3/KcecAO42Ww==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/keygrip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.1.tgz", + "integrity": "sha1-/1QEYtL7TQqIRBzq8n0oewHD2Hg=", + "dev": true + }, + "@types/koa": { + "version": "2.0.48", + "resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.0.48.tgz", + "integrity": "sha512-CiIUYhHlOFJhSCTmsFoFkV2t9ij1JwW26nt0W9XZoWTvmAw6zTE0+k3IAoGICtjzIfhZpZcO323NHmI1LGmdDw==", + "dev": true, + "requires": { + "@types/accepts": "*", + "@types/cookies": "*", + "@types/http-assert": "*", + "@types/keygrip": "*", + "@types/koa-compose": "*", + "@types/node": "*" + } + }, + "@types/koa-compose": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.3.tgz", + "integrity": "sha512-kXvR0DPyZ3gaFxZs4WycA8lpzlPGtFmwdbgce+NWd+TG3PycPO3o5FkePH60HoBPd8BBaSiw3vhtgM42O2kQcg==", + "dev": true, + "requires": { + "@types/koa": "*" + } + }, + "@types/koa-compress": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@types/koa-compress/-/koa-compress-2.0.8.tgz", + "integrity": "sha512-ewDLlqKmn+rS1uwQntBeKY8okG7220pZgl66gORdDE8Sq465/dRequ/ZzbNYWRrRmYDaElZZ0Gfk/dliHUoCkg==", + "dev": true, + "requires": { + "@types/koa": "*", + "@types/node": "*" + } + }, + "@types/koa-router": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/@types/koa-router/-/koa-router-7.0.39.tgz", + "integrity": "sha512-B8b2qyl7ijLFz7ocqkWva4IJ1n4uY5dK7jtGhQ+YHIGTpzcZr4ldDSjZi/xIM+ko3xSu8oqlGbzWxeVXK3WnNg==", + "dev": true, + "requires": { + "@types/koa": "*" + } + }, + "@types/koa-send": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/koa-send/-/koa-send-4.1.1.tgz", + "integrity": "sha512-ODeofnQxlkAl5PvJXhgOF/hjX9cH47oDFDqH9nE0G6zcp/Rr0vjswe7tuA+b0ZhlBrkfmN9X8VhRqQCBeOtZrw==", + "dev": true, + "requires": { + "@types/koa": "*" + } + }, + "@types/koa-static": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/koa-static/-/koa-static-4.0.1.tgz", + "integrity": "sha512-SSpct5fEcAeRkBHa3RiwCIRfDHcD1cZRhwRF///ZfvRt8KhoqRrhK6wpDlYPk/vWHVFE9hPGqh68bhzsHkir4w==", + "dev": true, + "requires": { + "@types/koa": "*", + "@types/koa-send": "*" + } + }, + "@types/libxmljs": { + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@types/libxmljs/-/libxmljs-0.18.3.tgz", + "integrity": "sha512-EvYww5XELtacMKQkvvEj2DrFSm9F4cusPoegt4C2S9OTw2MCJ2RZW5FMUP4MiU5307yIMZDCP25C/oBuJros1w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/mime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", + "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", + "dev": true + }, + "@types/mithril": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@types/mithril/-/mithril-1.1.16.tgz", + "integrity": "sha512-+HlRvSpKwXP8RXh1hrIcgSHQ/Fh+5O9nYfG7fgNN7PGr2K03G+hLoiA+HXzmUJCsQfPEuNiBQ+TwRl6n7kerSw==", + "dev": true + }, + "@types/mongodb": { + "version": "3.1.19", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.1.19.tgz", + "integrity": "sha512-H54hQEovAhyLrIZOhPNfGyCCDoTqKsjb8GQBy8nptJqfxrYCp5WVcPJf9v0kfTPR72xOhaz9+WcYxOXWwEg1Vg==", + "dev": true, + "requires": { + "@types/bson": "*", + "@types/node": "*" + } + }, + "@types/node": { + "version": "11.9.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.9.4.tgz", + "integrity": "sha512-Zl8dGvAcEmadgs1tmSPcvwzO1YRsz38bVJQvH1RvRqSR9/5n61Q1ktcDL0ht3FXWR+ZpVmXVwN1LuH4Ax23NsA==", + "dev": true + }, + "@types/parsimmon": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@types/parsimmon/-/parsimmon-1.10.0.tgz", + "integrity": "sha512-bsTIJFVQv7jnvNiC42ld2pQW2KRI+pAG243L+iATvqzy3X6+NH1obz2itRKDZZ8VVhN3wjwYax/VBGCcXzgTqQ==", + "dev": true + }, + "@types/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.1.tgz", + "integrity": "sha512-eqz8c/0kwNi/OEHQfvIuJVLTst3in0e7uTKeuY+WL/zfKn0xVujOTp42bS/vUUokhK5P2BppLd9JXMOMHcgbjA==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, + "@types/seedrandom": { + "version": "2.4.27", + "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-2.4.27.tgz", + "integrity": "sha1-nbVjk33YaRX2kJK8QyWdL0hXjkE=", + "dev": true + }, + "@types/serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.4.0.tgz", + "integrity": "sha512-LXLxWdq7nwGrJhMB78EKV+PJw4uWLyQLePRbJjbz6klItPaTa+5zxAr3+GGPaKlhTHKdoCsUaIGfCLjopUA65w==", + "dev": true, + "requires": { + "@typescript-eslint/parser": "1.4.0", + "@typescript-eslint/typescript-estree": "1.4.0", + "requireindex": "^1.2.0", + "tsutils": "^3.7.0" + } + }, + "@typescript-eslint/parser": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.4.0.tgz", + "integrity": "sha512-OvXhpgFCKLxuvoGgtFHQP5gvJvqKGpGjarSPg27E07+OPIcZJ3EpZDdELZuY+0hCA4wqnQ9JzHoTBhdEOMo9Pg==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "1.4.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.4.0.tgz", + "integrity": "sha512-s0Y1/nMSRwIRK+8umAkvUoKsP12Ze8QMAdjVSYLZbrWy8NlsrTLLhpTR5rPEEW7uCnmJtv40kr51PrYAyaJVOw==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + } + } + }, + "@webassemblyjs/ast": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.3.tgz", + "integrity": "sha512-xy3m06+Iu4D32+6soz6zLnwznigXJRuFNTovBX2M4GqVqLb0dnyWLbPnpcXvUSdEN+9DVyDeaq2jyH1eIL2LZQ==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.8.3", + "@webassemblyjs/helper-wasm-bytecode": "1.8.3", + "@webassemblyjs/wast-parser": "1.8.3" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.3.tgz", + "integrity": "sha512-vq1TISG4sts4f0lDwMUM0f3kpe0on+G3YyV5P0IySHFeaLKRYZ++n2fCFfG4TcCMYkqFeTUYFxm75L3ddlk2xA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.3.tgz", + "integrity": "sha512-BmWEynI4FnZbjk8CaYZXwcv9a6gIiu+rllRRouQUo73hglanXD3AGFJE7Q4JZCoVE0p5/jeX6kf5eKa3D4JxwQ==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.3.tgz", + "integrity": "sha512-iVIMhWnNHoFB94+/2l7LpswfCsXeMRnWfExKtqsZ/E2NxZyUx9nTeKK/MEMKTQNEpyfznIUX06OchBHQ+VKi/Q==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.3.tgz", + "integrity": "sha512-K1UxoJML7GKr1QXR+BG7eXqQkvu+eEeTjlSl5wUFQ6W6vaOc5OwSxTcb3oE9x/3+w4NHhrIKD4JXXCZmLdL2cg==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.8.3" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.3.tgz", + "integrity": "sha512-387zipfrGyO77/qm7/SDUiZBjQ5KGk4qkrVIyuoubmRNIiqn3g+6ijY8BhnlGqsCCQX5bYKOnttJobT5xoyviA==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.3.tgz", + "integrity": "sha512-lPLFdQfaRssfnGEJit5Sk785kbBPPPK4ZS6rR5W/8hlUO/5v3F+rN8XuUcMj/Ny9iZiyKhhuinWGTUuYL4VKeQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.3", + "mamacro": "^0.0.3" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.3.tgz", + "integrity": "sha512-R1nJW7bjyJLjsJQR5t3K/9LJ0QWuZezl8fGa49DZq4IVaejgvkbNlKEQxLYTC579zgT4IIIVHb5JA59uBPHXyw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.3.tgz", + "integrity": "sha512-P6F7D61SJY73Yz+fs49Q3+OzlYAZP86OfSpaSY448KzUy65NdfzDmo2NPVte+Rw4562MxEAacvq/mnDuvRWOcg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.3", + "@webassemblyjs/helper-buffer": "1.8.3", + "@webassemblyjs/helper-wasm-bytecode": "1.8.3", + "@webassemblyjs/wasm-gen": "1.8.3" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.3.tgz", + "integrity": "sha512-UD4HuLU99hjIvWz1pD68b52qsepWQlYCxDYVFJQfHh3BHyeAyAlBJ+QzLR1nnS5J6hAzjki3I3AoJeobNNSZlg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.3.tgz", + "integrity": "sha512-XXd3s1BmkC1gpGABuCRLqCGOD6D2L+Ma2BpwpjrQEHeQATKWAQtxAyU9Z14/z8Ryx6IG+L4/NDkIGHrccEhRUg==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.3.tgz", + "integrity": "sha512-Wv/WH9Zo5h5ZMyfCNpUrjFsLZ3X1amdfEuwdb7MLdG3cPAjRS6yc6ElULlpjLiiBTuzvmLhr3ENsuGyJ3wyCgg==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.3.tgz", + "integrity": "sha512-nB19eUx3Yhi1Vvv3yev5r+bqQixZprMtaoCs1brg9Efyl8Hto3tGaUoZ0Yb4Umn/gQCyoEGFfUxPLp1/8+Jvnw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.3", + "@webassemblyjs/helper-buffer": "1.8.3", + "@webassemblyjs/helper-wasm-bytecode": "1.8.3", + "@webassemblyjs/helper-wasm-section": "1.8.3", + "@webassemblyjs/wasm-gen": "1.8.3", + "@webassemblyjs/wasm-opt": "1.8.3", + "@webassemblyjs/wasm-parser": "1.8.3", + "@webassemblyjs/wast-printer": "1.8.3" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.3.tgz", + "integrity": "sha512-sDNmu2nLBJZ/huSzlJvd9IK8B1EjCsOl7VeMV9VJPmxKYgTJ47lbkSP+KAXMgZWGcArxmcrznqm7FrAPQ7vVGg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.3", + "@webassemblyjs/helper-wasm-bytecode": "1.8.3", + "@webassemblyjs/ieee754": "1.8.3", + "@webassemblyjs/leb128": "1.8.3", + "@webassemblyjs/utf8": "1.8.3" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.3.tgz", + "integrity": "sha512-j8lmQVFR+FR4/645VNgV4R/Jz8i50eaPAj93GZyd3EIJondVshE/D9pivpSDIXyaZt+IkCodlzOoZUE4LnQbeA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.3", + "@webassemblyjs/helper-buffer": "1.8.3", + "@webassemblyjs/wasm-gen": "1.8.3", + "@webassemblyjs/wasm-parser": "1.8.3" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.3.tgz", + "integrity": "sha512-NBI3SNNtRoy4T/KBsRZCAWUzE9lI94RH2nneLwa1KKIrt/2zzcTavWg6oY05ArCbb/PZDk3OUi63CD1RYtN65w==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.3", + "@webassemblyjs/helper-api-error": "1.8.3", + "@webassemblyjs/helper-wasm-bytecode": "1.8.3", + "@webassemblyjs/ieee754": "1.8.3", + "@webassemblyjs/leb128": "1.8.3", + "@webassemblyjs/utf8": "1.8.3" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.3.tgz", + "integrity": "sha512-gZPst4CNcmGtKC1eYQmgCx6gwQvxk4h/nPjfPBbRoD+Raw3Hs+BS3yhrfgyRKtlYP+BJ8LcY9iFODEQofl2qbg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.3", + "@webassemblyjs/floating-point-hex-parser": "1.8.3", + "@webassemblyjs/helper-api-error": "1.8.3", + "@webassemblyjs/helper-code-frame": "1.8.3", + "@webassemblyjs/helper-fsm": "1.8.3", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.3.tgz", + "integrity": "sha512-DTA6kpXuHK4PHu16yAD9QVuT1WZQRT7079oIFFmFSjqjLWGXS909I/7kiLTn931mcj7wGsaUNungjwNQ2lGQ3Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.3", + "@webassemblyjs/wast-parser": "1.8.3", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, "acorn": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz", - "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz", + "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", "dev": true }, "acorn-jsx": { @@ -41,10 +910,19 @@ "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", "dev": true }, + "aggregate-error": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-1.0.0.tgz", + "integrity": "sha1-iINE2tAiCnLjr1CQYRf0h3GSX6w=", + "requires": { + "clean-stack": "^1.0.0", + "indent-string": "^3.0.0" + } + }, "ajv": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.1.tgz", - "integrity": "sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", + "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -53,10 +931,70 @@ "uri-js": "^4.2.2" } }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", + "dev": true + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "ansi-escapes": { - "version": "3.1.0", - "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "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-regex": { @@ -73,6 +1011,32 @@ "color-convert": "^1.9.0" } }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", @@ -87,6 +1051,12 @@ "readable-stream": "^2.0.6" } }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -96,22 +1066,479 @@ "sprintf-js": "~1.0.2" } }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-differ": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.0.3.tgz", + "integrity": "sha1-AZW7AMzM8nEQbv7kpHhkiLcYBxI=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "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" + }, + "dependencies": { + "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-uniq": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-2.0.0.tgz", + "integrity": "sha512-O3QZEr+3wDj7otzF7PjNGs6CA3qmYMLvt5xGkjY/V0VxS+ovvqVo/5wKM/OVOAyuX4DTh9H31zE/yKtO66hTkg==", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", + "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==", + "dev": true, + "requires": { + "browserslist": "^2.11.3", + "caniuse-lite": "^1.0.30000805", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^6.0.17", + "postcss-value-parser": "^3.2.3" + }, + "dependencies": { + "browserslist": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", + "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000792", + "electron-to-chromium": "^1.3.30" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "ava": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ava/-/ava-1.2.1.tgz", + "integrity": "sha512-EHqbPGdd8aNvlvRNL7liD1J9Auf9kByHj5Zi7zF7Z5ukn2ZStZgVBf7LSqirKIOWScB3XZzFQbO59SnTvzD5kA==", + "dev": true, + "requires": { + "@ava/babel-preset-stage-4": "^2.0.0", + "@ava/babel-preset-transform-test-files": "^4.0.1", + "@ava/write-file-atomic": "^2.2.0", + "@babel/core": "^7.2.2", + "@babel/generator": "^7.3.0", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@concordance/react": "^2.0.0", + "ansi-escapes": "^3.1.0", + "ansi-styles": "^3.2.1", + "arr-flatten": "^1.1.0", + "array-union": "^1.0.1", + "array-uniq": "^2.0.0", + "arrify": "^1.0.0", + "bluebird": "^3.5.3", + "chalk": "^2.4.2", + "chokidar": "^2.0.4", + "chunkd": "^1.0.0", + "ci-parallel-vars": "^1.0.0", + "clean-stack": "^2.0.0", + "clean-yaml-object": "^0.1.0", + "cli-cursor": "^2.1.0", + "cli-truncate": "^1.1.0", + "code-excerpt": "^2.1.1", + "common-path-prefix": "^1.0.0", + "concordance": "^4.0.0", + "convert-source-map": "^1.6.0", + "currently-unhandled": "^0.4.1", + "debug": "^4.1.1", + "del": "^3.0.0", + "dot-prop": "^4.2.0", + "emittery": "^0.4.1", + "empower-core": "^1.2.0", + "equal-length": "^1.0.0", + "escape-string-regexp": "^1.0.5", + "esm": "^3.1.3", + "figures": "^2.0.0", + "find-up": "^3.0.0", + "get-port": "^4.1.0", + "globby": "^7.1.1", + "ignore-by-default": "^1.0.0", + "import-local": "^2.0.0", + "indent-string": "^3.2.0", + "is-ci": "^2.0.0", + "is-error": "^2.2.1", + "is-observable": "^1.1.0", + "is-plain-object": "^2.0.4", + "is-promise": "^2.1.0", + "lodash.clone": "^4.5.0", + "lodash.clonedeep": "^4.5.0", + "lodash.clonedeepwith": "^4.5.0", + "lodash.debounce": "^4.0.3", + "lodash.difference": "^4.3.0", + "lodash.flatten": "^4.2.0", + "loud-rejection": "^1.2.0", + "make-dir": "^1.3.0", + "matcher": "^1.1.1", + "md5-hex": "^2.0.0", + "meow": "^5.0.0", + "ms": "^2.1.1", + "multimatch": "^3.0.0", + "observable-to-promise": "^0.5.0", + "ora": "^3.0.0", + "package-hash": "^3.0.0", + "pkg-conf": "^2.1.0", + "plur": "^3.0.1", + "pretty-ms": "^4.0.0", + "require-precompiled": "^0.1.0", + "resolve-cwd": "^2.0.0", + "slash": "^2.0.0", + "source-map-support": "^0.5.10", + "stack-utils": "^1.0.2", + "strip-ansi": "^5.0.0", + "strip-bom-buf": "^1.0.0", + "supertap": "^1.0.0", + "supports-color": "^6.1.0", + "trim-off-newlines": "^1.0.1", + "trim-right": "^1.0.1", + "unique-temp-dir": "^1.0.0", + "update-notifier": "^2.5.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + }, + "clean-stack": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.0.0.tgz", + "integrity": "sha512-VEoL9Qh7I8s8iHnV53DaeWSt8NJ0g3khMfK6NiCPB7H657juhro+cSw2O88uo3bo0c0X5usamtXk0/Of0wXa5A==", + "dev": true + }, + "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" + } + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" + } + } + } + }, + "babel-plugin-espower": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-espower/-/babel-plugin-espower-3.0.1.tgz", + "integrity": "sha512-Ms49U7VIAtQ/TtcqRbD6UBmJBUCSxiC3+zPc+eGqxKUIFO1lTshyEDRUjhoAbd2rWfwYf3cZ62oXozrd8W6J0A==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "call-matcher": "^1.0.0", + "core-js": "^2.0.0", + "espower-location-detector": "^1.0.0", + "espurify": "^1.6.0", + "estraverse": "^4.1.1" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", + "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==", + "dev": true + }, "bindings": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz", "integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew==" }, + "bluebird": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -121,35 +1548,337 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", + "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000929", + "electron-to-chromium": "^1.3.103", + "node-releases": "^1.1.3" + } + }, "bson": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.0.tgz", "integrity": "sha512-9Aeai9TacfNtWXOYarkFJRW2CWo+dRon+fuLZYJmvLV3+MiUp0bEI6IAZfXEIg7/Pl/7IWlLaDnhzTsD81etQA==" }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { - "callsites": "^0.2.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "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==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cacache": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", + "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "requires": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + } + }, + "call-matcher": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.1.0.tgz", + "integrity": "sha512-IoQLeNwwf9KTNbtSA7aEBb1yfDbdnzwjCetjkC8io5oGeOmK2CBNdg0xr+tadRYKO0p7uQyZzvon0kXlZbvGrw==", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "deep-equal": "^1.0.0", + "espurify": "^1.6.0", + "estraverse": "^4.0.0" + } + }, + "call-signature": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/call-signature/-/call-signature-0.0.2.tgz", + "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", + "dev": true + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" } }, "callsites": { - "version": "0.2.0", - "resolved": "http://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + } + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30000938", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000938.tgz", + "integrity": "sha512-ekW8NQ3/FvokviDxhdKLZZAx7PptXNwxKgXtnR5y+PR3hckwuP3yJ1Ir+4/c97dsHNqtAyfKUGdw8P4EYzBNgw==", + "dev": true + }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", "dev": true }, "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "chardet": { @@ -158,15 +1887,106 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "chokidar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.2.tgz", + "integrity": "sha512-IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.0" + } + }, "chownr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "chrome-trace-event": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz", + "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "chunkd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-1.0.0.tgz", + "integrity": "sha512-xx3Pb5VF9QaqCotolyZ1ywFBgyuJmu6+9dLiqBxgelEse9Xsr3yUlpoX3O4Oh11M00GT2kYMsRByTKIMJW2Lkg==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "ci-parallel-vars": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.0.tgz", + "integrity": "sha512-u6dx20FBXm+apMi+5x7UVm6EH7BL1gc4XrcnQewjcB7HWRcor/V5qWc3RG2HwpgDJ26gIi2DSEu3B7sXynAw/g==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-stack": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", + "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=" + }, + "clean-yaml-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", + "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", + "dev": true + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", "dev": true }, "cli-cursor": { @@ -178,17 +1998,134 @@ "restore-cursor": "^2.0.0" } }, + "cli-spinners": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", + "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==", + "dev": true + }, + "cli-truncate": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-1.1.0.tgz", + "integrity": "sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA==", + "dev": true, + "requires": { + "slice-ansi": "^1.0.0", + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "co-body": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/co-body/-/co-body-6.0.0.tgz", + "integrity": "sha512-9ZIcixguuuKIptnY8yemEOuhb71L/lLf+Rl5JfJEUiDNJk0e02MBt7BPxR2GEh5mw8dPthQYR4jPI/BnS1MQgw==", + "requires": { + "inflation": "^2.0.0", + "qs": "^6.5.2", + "raw-body": "^2.3.3", + "type-is": "^1.6.16" + } + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + } + }, + "code-excerpt": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-2.1.1.tgz", + "integrity": "sha512-tJLhH3EpFm/1x7heIW0hemXJTUU5EWl2V0EIX558jp05Mt1U6DVryCgkp3l37cxqs+DNbNgxG43SkwJXpQ14Jw==", + "dev": true, + "requires": { + "convert-to-spaces": "^1.0.1" + } + }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, + "codemirror": { + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.43.0.tgz", + "integrity": "sha512-mljwQWUaWIf85I7QwTBryF2ASaIvmYAL4s5UCanCJFfKeXOKhrqdHWdHiZWAMNT+hjLTCnVx2S/SYTORIgxsgA==", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.0.tgz", + "integrity": "sha512-CwyopLkuRYO5ei2EpzpIh6LqJMt6Mt+jZhO5VI5f/wJLZriXQE32/SSqzmrh+QB+AZT81Cj8yv+7zwToW8ahZg==", + "dev": true, + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -204,42 +2141,578 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "common-path-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-1.0.0.tgz", + "integrity": "sha1-zVL28HEuC6q5fW+XModPIvR3UsA=", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "compressible": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz", + "integrity": "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==", + "requires": { + "mime-db": ">= 1.38.0 < 2" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "concordance": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-4.0.0.tgz", + "integrity": "sha512-l0RFuB8RLfCS0Pt2Id39/oCPykE01pyxgAFypWTlaGRgvLkZrtczZ8atEHpTeEIW+zYWXTBuA9cCSeEOScxReQ==", + "dev": true, + "requires": { + "date-time": "^2.1.0", + "esutils": "^2.0.2", + "fast-diff": "^1.1.2", + "js-string-escape": "^1.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.flattendeep": "^4.4.0", + "lodash.islength": "^4.0.1", + "lodash.merge": "^4.6.1", + "md5-hex": "^2.0.0", + "semver": "^5.5.1", + "well-known-symbols": "^2.0.0" + } + }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "convert-to-spaces": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", + "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", + "dev": true + }, + "cookies": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.3.tgz", + "integrity": "sha512-+gixgxYSgQLTaTIilDHAdlNPZDENDQernEMiIcZpYYP14zgHsCt4Ce1FEjFtcp6GefhozebB6orvhAAWx/IS0A==", + "requires": { + "depd": "~1.1.2", + "keygrip": "~1.0.3" + } + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-to": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz", + "integrity": "sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU=" + }, + "core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "cosmiconfig": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.1.0.tgz", + "integrity": "sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "lodash.get": "^4.4.2", + "parse-json": "^4.0.0" + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, + "css-color-function": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/css-color-function/-/css-color-function-1.3.3.tgz", + "integrity": "sha1-jtJMLAIFBzM5+voAS8jBQfzLKC4=", + "dev": true, + "requires": { + "balanced-match": "0.1.0", + "color": "^0.11.0", + "debug": "^3.1.0", + "rgb": "~0.1.0" + }, + "dependencies": { + "balanced-match": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.1.0.tgz", + "integrity": "sha1-tQS9BYabOSWd0MXvw12EMXbczEo=", + "dev": true + }, + "color": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", + "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", + "dev": true, + "requires": { + "clone": "^1.0.2", + "color-convert": "^1.3.0", + "color-string": "^0.3.0" + } + }, + "color-string": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz", + "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=", + "dev": true, + "requires": { + "color-name": "^1.0.0" + } + } + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-select": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", + "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^2.1.2", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-tree": { + "version": "1.0.0-alpha.28", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", + "integrity": "sha512-joNNW1gCp3qFFzj4St6zk+Wh/NBv0vM5YbEreZk0SD4S23S+1xBKb6cLDg2uj4P4k/GUMlIm6cKIDqIG+vdt0w==", + "dev": true, + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + } + }, + "css-unit-converter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", + "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=", + "dev": true + }, + "css-url-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/css-url-regex/-/css-url-regex-1.1.0.tgz", + "integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w=", + "dev": true + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "dev": true + }, + "cssesc": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz", + "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==", + "dev": true + }, + "cssnano": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", + "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.7", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", + "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "dev": true, + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.2", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "dev": true + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "dev": true + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true + }, + "csso": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", + "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "dev": true, + "requires": { + "css-tree": "1.0.0-alpha.29" + }, + "dependencies": { + "css-tree": { + "version": "1.0.0-alpha.29", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", + "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", + "dev": true, + "requires": { + "mdn-data": "~1.1.0", + "source-map": "^0.5.3" + } + } + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "dev": true + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "date-time": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-2.1.0.tgz", + "integrity": "sha512-/9+C44X7lot0IeiyfgJmETtRMhBidBYM2QFFIkGa0U1k+hSyY87Nw7PY3eDqpvCBm7I3WCSfPeZskW/YYq6m4g==", + "dev": true, + "requires": { + "time-zone": "^1.0.0" + } + }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "requires": { "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "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=" + }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -251,30 +2724,378 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "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" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://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": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + } + } + }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" } }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", - "optional": true + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "dev": true, + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz", + "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=", + "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", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron-to-chromium": { + "version": "1.3.113", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz", + "integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g==", + "dev": true + }, + "elliptic": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emittery": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.4.1.tgz", + "integrity": "sha512-r4eRSeStEGf6M5SKdrQhhLK5bOwOBxQhIE3YSTnZE3GpKiLfnnhE+tPtrJE79+eDJgm39BM6LSoI8SCx4HbwlQ==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "empower-core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/empower-core/-/empower-core-1.2.0.tgz", + "integrity": "sha512-g6+K6Geyc1o6FdXs9HwrXleCFan7d66G5xSCfSF7x1mJDCes6t0om9lFQG3zOrzh3Bkb/45N0cZ5Gqsf7YrzGQ==", + "dev": true, + "requires": { + "call-signature": "0.0.2", + "core-js": "^2.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "equal-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/equal-length/-/equal-length-1.0.1.tgz", + "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-inject": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/error-inject/-/error-inject-1.0.0.tgz", + "integrity": "sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=" + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-string-regexp": { "version": "1.0.5", @@ -283,47 +3104,46 @@ "dev": true }, "eslint": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.10.0.tgz", - "integrity": "sha512-HpqzC+BHULKlnPwWae9MaVZ5AXJKpkxCVXQHrFaRw3hbDj26V/9ArYM4Rr/SQ8pi6qUPLXSSXC4RBJlyq2Z2OQ==", + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.14.1.tgz", + "integrity": "sha512-CyUMbmsjxedx8B0mr79mNOqetvkbij/zrXnFeK2zc3pGRn3/tibjiNAv/3UxFEyfMDjh+ZqTrJrEGBFiGfD5Og==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "ajv": "^6.5.3", + "ajv": "^6.9.1", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", - "doctrine": "^2.1.0", + "doctrine": "^3.0.0", "eslint-scope": "^4.0.0", "eslint-utils": "^1.3.1", "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.0", + "espree": "^5.0.1", "esquery": "^1.0.1", "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", + "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", "globals": "^11.7.0", "ignore": "^4.0.6", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.1.0", + "inquirer": "^6.2.2", "js-yaml": "^3.12.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.17.5", + "lodash": "^4.17.11", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", "progress": "^2.0.0", "regexpp": "^2.0.1", - "require-uncached": "^1.0.3", "semver": "^5.5.1", "strip-ansi": "^4.0.0", "strip-json-comments": "^2.0.1", - "table": "^5.0.2", + "table": "^5.2.3", "text-table": "^0.2.0" }, "dependencies": { @@ -333,19 +3153,48 @@ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, "debug": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", - "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "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==", + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "strip-ansi": { @@ -359,6 +3208,15 @@ } } }, + "eslint-config-prettier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.0.0.tgz", + "integrity": "sha512-kWuiJxzV5NwOwZcpyozTzDT5KJhBw292bbYro9Is7BWnbNMg15Gmpluc1CTetiCatF8DRkNvgPAOaSyg+bYr3g==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, "eslint-scope": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", @@ -381,13 +3239,31 @@ "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, - "espree": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.0.tgz", - "integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==", + "esm": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.5.tgz", + "integrity": "sha512-rukU6Nd3agbHQCJWV4rrlZxqpbO3ix8qhUxK1BhKALGS2E465O0BFwgCOqJjNnYfO/I2MwpUBmPsW8DXoe8tcA==", + "dev": true + }, + "espower-location-detector": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/espower-location-detector/-/espower-location-detector-1.0.0.tgz", + "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", "dev": true, "requires": { - "acorn": "^6.0.2", + "is-url": "^1.2.1", + "path-is-absolute": "^1.0.0", + "source-map": "^0.5.0", + "xtend": "^4.0.0" + } + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", "acorn-jsx": "^5.0.0", "eslint-visitor-keys": "^1.0.0" } @@ -398,6 +3274,15 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "espurify": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.8.1.tgz", + "integrity": "sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg==", + "dev": true, + "requires": { + "core-js": "^2.0.0" + } + }, "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", @@ -422,12 +3307,120 @@ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", "dev": true }, + "estree-walker": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.0.tgz", + "integrity": "sha512-peq1RfVAVzr3PU/jL31RaOjUKLoZJpObQWJJ+LgfcxDUifyLZ1RjPQZTl0pzj2uJ45b7A7XpyppXvxdEqzo4rw==", + "dev": true + }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, "external-editor": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", @@ -437,6 +3430,82 @@ "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } } }, "fast-deep-equal": { @@ -445,6 +3514,12 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", @@ -457,6 +3532,12 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dev": true + }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -467,25 +3548,118 @@ } }, "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz", + "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.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" } }, "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dev": true, "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, + "flatten": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" } }, "fs-minipass": { @@ -496,11 +3670,558 @@ "minipass": "^2.2.1" } }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "fsevents": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": 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" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", @@ -522,6 +4243,30 @@ "wide-align": "^1.1.0" } }, + "get-port": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-4.1.0.tgz", + "integrity": "sha512-4/fqAYrzrzOiqDrdeZRKXGdTGgbkfTEumGlNQPeP6Jy8w0PzN9mzeNQ3XgHaTNie8pQ3hOUkrwlZt2Fzk5H9mA==", + "dev": true + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", @@ -535,41 +4280,274 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, "globals": { - "version": "11.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.9.0.tgz", - "integrity": "sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", "dev": true }, + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "dependencies": { + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + } + } + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + }, "graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", + "dev": true + }, + "http-assert": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.4.0.tgz", + "integrity": "sha512-tPVv62a6l3BbQoM/N5qo969l0OFxqpnQzNUPeYfTP6Spo4zkgWeDBD1D5thI7sDLg7jCCihXTLB0X8UtdyAy8A==", + "requires": { + "deep-equal": "~1.0.1", + "http-errors": "~1.7.1" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "requires": { "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", "dev": true }, "ignore-walk": { @@ -580,12 +4558,68 @@ "minimatch": "^3.0.4" } }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=" + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflation": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/inflation/-/inflation-2.0.0.tgz", + "integrity": "sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -606,21 +4640,21 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", - "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz", + "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==", "dev": true, "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", - "external-editor": "^3.0.0", + "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.17.10", + "lodash": "^4.17.11", "mute-stream": "0.0.7", "run-async": "^2.2.0", - "rxjs": "^6.1.0", + "rxjs": "^6.4.0", "string-width": "^2.1.0", "strip-ansi": "^5.0.0", "through": "^2.3.6" @@ -678,6 +4712,157 @@ } } }, + "irregular-plurals": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", + "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==", + "dev": true + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-error": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz", + "integrity": "sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -686,16 +4871,189 @@ "number-is-nan": "^1.0.0" } }, + "is-generator-function": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz", + "integrity": "sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw==" + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "requires": { + "symbol-observable": "^1.1.0" + } + }, + "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", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, - "isarray": { + "is-redirect": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-svg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "dev": true, + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, "isexe": { "version": "2.0.0", @@ -703,6 +5061,34 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "isnumeric": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/isnumeric/-/isnumeric-0.2.0.tgz", + "integrity": "sha1-ojR7o2DeGeM9D/1ZD933dVy/LmQ=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "jest-worker": { + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.0.0.tgz", + "integrity": "sha512-s64/OThpfQvoCeHG963MiEZOAAxu8kHsaL/rCMF7lpdzo7vgF0CtPml9hfguOMgykgH/eOm4jFP4ibfHLruytg==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + } + }, + "js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -710,15 +5096,27 @@ "dev": true }, "js-yaml": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", - "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -731,11 +5129,239 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "jsonwebtoken": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz", + "integrity": "sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg==", + "requires": { + "jws": "^3.1.5", + "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" + } + }, + "jwa": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.2.0.tgz", + "integrity": "sha512-Grku9ZST5NNQ3hqNUodSkDfEBqAmGA1R8yiyPHOnLzEKI0GaCQC/XhFmsheXYuXzFQJdILbh+lYBiliqG5R/Vg==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.10", + "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" + } + }, + "keygrip": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.3.tgz", + "integrity": "sha512-/PpesirAIfaklxUzp4Yb7xBper9MwP6hNRA6BGGUFCgbJ+BM5CKBtsoxinNXkLHAr+GXS1/lSlF2rP7cv5Fl+g==" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "koa": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.7.0.tgz", + "integrity": "sha512-7ojD05s2Q+hFudF8tDLZ1CpCdVZw8JQELWSkcfG9bdtoTDzMmkRF6BQBU7JzIzCCOY3xd3tftiy/loHBUYaY2Q==", + "requires": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.7.1", + "debug": "~3.1.0", + "delegates": "^1.0.0", + "depd": "^1.1.2", + "destroy": "^1.0.4", + "error-inject": "^1.0.0", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^1.2.0", + "koa-is-json": "^1.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + } + }, + "koa-bodyparser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/koa-bodyparser/-/koa-bodyparser-4.2.1.tgz", + "integrity": "sha512-UIjPAlMZfNYDDe+4zBaOAUKYqkwAGcIU6r2ARf1UOXPAlfennQys5IiShaVeNf7KkVBlf88f2LeLvBFvKylttw==", + "requires": { + "co-body": "^6.0.0", + "copy-to": "^2.0.1" + } + }, + "koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==" + }, + "koa-compress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/koa-compress/-/koa-compress-3.0.0.tgz", + "integrity": "sha512-xol+LkNB1mozKJkB5Kj6nYXbJXhkLkZlXl9BsGBPjujVfZ8MsIXwU4GHRTT7TlSfUcl2DU3JtC+j6wOWcovfuQ==", + "requires": { + "bytes": "^3.0.0", + "compressible": "^2.0.0", + "koa-is-json": "^1.0.0", + "statuses": "^1.0.0" + } + }, + "koa-convert": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-1.2.0.tgz", + "integrity": "sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=", + "requires": { + "co": "^4.6.0", + "koa-compose": "^3.0.0" + }, + "dependencies": { + "koa-compose": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-3.2.1.tgz", + "integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=", + "requires": { + "any-promise": "^1.1.0" + } + } + } + }, + "koa-is-json": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/koa-is-json/-/koa-is-json-1.0.0.tgz", + "integrity": "sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ=" + }, + "koa-jwt": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/koa-jwt/-/koa-jwt-3.5.1.tgz", + "integrity": "sha512-Wy1TZzyPdMw2X72HPhy9GPUy0BMxafS8Wq0JzvXCPi4pEBWQDtz1lzxYWpE2ghMuXWJ0vKKRrR5e+CyYGS8LBA==", + "requires": { + "jsonwebtoken": "8.3.0", + "koa-unless": "1.0.7", + "p-any": "1.1.0" + }, + "dependencies": { + "jsonwebtoken": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz", + "integrity": "sha512-oge/hvlmeJCH+iIz1DwcO7vKPkNGJHhgkspk8OH3VKlw+mbi42WtD4ig1+VXRln765vxptAv+xT26Fd3cteqag==", + "requires": { + "jws": "^3.1.5", + "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" + } + } + } + }, + "koa-router": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/koa-router/-/koa-router-7.4.0.tgz", + "integrity": "sha512-IWhaDXeAnfDBEpWS6hkGdZ1ablgr6Q6pGdXCyK38RbzuH4LkUOpPqPw+3f8l8aTDrQmBQ7xJc0bs2yV4dzcO+g==", + "requires": { + "debug": "^3.1.0", + "http-errors": "^1.3.1", + "koa-compose": "^3.0.0", + "methods": "^1.0.1", + "path-to-regexp": "^1.1.1", + "urijs": "^1.19.0" + }, + "dependencies": { + "koa-compose": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-3.2.1.tgz", + "integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=", + "requires": { + "any-promise": "^1.1.0" + } + } + } + }, + "koa-send": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.0.tgz", + "integrity": "sha512-90ZotV7t0p3uN9sRwW2D484rAaKIsD8tAVtypw/aBU+ryfV+fR2xrcAwhI8Wl6WRkojLUs/cB9SBSCuIb+IanQ==", + "requires": { + "debug": "^3.1.0", + "http-errors": "^1.6.3", + "mz": "^2.7.0", + "resolve-path": "^1.4.0" + } + }, + "koa-static": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/koa-static/-/koa-static-5.0.0.tgz", + "integrity": "sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==", + "requires": { + "debug": "^3.1.0", + "koa-send": "^5.0.0" + } + }, + "koa-unless": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/koa-unless/-/koa-unless-1.0.7.tgz", + "integrity": "sha1-ud83XitNowQ5GNSGIlIMLAt58DI=" + }, "later": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/later/-/later-1.2.0.tgz", "integrity": "sha1-8s9sTdeVbdL1IK3wMpg26YdrrQ8=" }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -756,24 +5382,461 @@ "node-pre-gyp": "~0.11.0" } }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "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" + } + }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.clonedeepwith": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz", + "integrity": "sha1-buMFc6A6GmDWcKYu8zwQzxr9vdQ=", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "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.islength": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.islength/-/lodash.islength-4.0.1.tgz", + "integrity": "sha1-Tpho1FJXXXUK/9NYyXlUPcIO1Xc=", + "dev": true + }, + "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.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", + "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.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0" + } + }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + }, + "dependencies": { + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, + "magic-string": { + "version": "0.25.2", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz", + "integrity": "sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", + "dev": true + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "matcher": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-1.1.1.tgz", + "integrity": "sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.4" + } + }, + "math-expression-evaluator": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", + "dev": true + }, + "md5-hex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-2.0.0.tgz", + "integrity": "sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM=", + "dev": true, + "requires": { + "md5-o-matic": "^0.1.1" + } + }, + "md5-o-matic": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", + "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdn-data": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", + "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, "memory-pager": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.3.1.tgz", - "integrity": "sha512-pUf/sGkym2WqFZYTVmdASnSbNfpGc9rwxEHOePx4lT/fD+NHGL1U16Uy4o6PMiVcDv4mp6MI/vaF0c/Kd1QEUQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "optional": true }, + "meow": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", + "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0", + "yargs-parser": "^10.0.0" + } + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "requires": { + "mime-db": "~1.38.0" + } + }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -784,9 +5847,19 @@ }, "minimist": { "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + } + }, "minipass": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", @@ -804,27 +5877,72 @@ "minipass": "^2.2.1" } }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mithril": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/mithril/-/mithril-1.1.6.tgz", + "integrity": "sha512-fWcUrQTCqu8M916rj1MFGlHaPh65rznPu6U/N2U9g81H89klDCIptSK5bnkNkC+jyi3sJIXjyGhSQjUnR8jzZA==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" } }, "mongodb": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.10.tgz", - "integrity": "sha512-Uml42GeFxhTGQVml1XQ4cD0o/rp7J2ROy0fdYUcVitoE7vFqEhKH4TYVqRDpQr/bXtCJVxJdNQC1ntRxNREkPQ==", + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.13.tgz", + "integrity": "sha512-sz2dhvBZQWf3LRNDhbd30KHVzdjZx9IKC0L+kSZ/gzYquCF5zPOgGqRz6sSCqYZtKP2ekB4nfLxhGtzGHnIKxA==", "requires": { - "mongodb-core": "3.1.9", + "mongodb-core": "3.1.11", "safe-buffer": "^5.1.2" } }, "mongodb-core": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.9.tgz", - "integrity": "sha512-MJpciDABXMchrZphh3vMcqu8hkNf/Mi+Gk6btOimVg1XMxLXh87j6FAvRm+KmwD1A9fpu3qRQYcbQe4egj23og==", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.11.tgz", + "integrity": "sha512-rD2US2s5qk/ckbiiGFHeu+yKYDXdJ1G87F6CG3YdaZpzdOm5zpoAZd/EKbPmFO6cQZ+XVXBXBJ660sSI0gc6qg==", "requires": { "bson": "^1.1.0", "require_optional": "^1.0.1", @@ -832,10 +5950,36 @@ "saslprep": "^1.0.0" } }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "multimatch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-3.0.0.tgz", + "integrity": "sha512-22foS/gqQfANZ3o+W7ST2x25ueHDVNWl/b9OlGcLpy/iKxjCpvcNCM51YCenUi7Mt/jAjjqv8JwZRs8YP5sRjA==", + "dev": true, + "requires": { + "array-differ": "^2.0.3", + "array-union": "^1.0.2", + "arrify": "^1.0.1", + "minimatch": "^3.0.4" + } }, "mute-stream": { "version": "0.0.7", @@ -843,11 +5987,40 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "nan": { "version": "2.10.0", - "resolved": "http://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -862,14 +6035,79 @@ "debug": "^2.1.2", "iconv-lite": "^0.4.4", "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } } }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "neo-async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", + "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node-libs-browser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", + "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.0", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, "node-pre-gyp": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz", @@ -887,6 +6125,15 @@ "tar": "^4" } }, + "node-releases": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.8.tgz", + "integrity": "sha512-gQm+K9mGCiT/NXHy+V/ZZS1N/LOaGGqRAAJJs3X9Ah1g+CIbRcBgNyoNYQ+SEtcyAtB9KqDruu+fF7nWjsqRaA==", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, "nopt": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", @@ -896,20 +6143,59 @@ "osenv": "^0.1.4" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true + }, "npm-bundled": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.5.tgz", - "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==" }, "npm-packlist": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.12.tgz", - "integrity": "sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.0.tgz", + "integrity": "sha512-zCAmKshsFx2MhOsXdYmZd1DO2d8ts80kVASSWX6lv8654i0edCnNCoEqwVsMygl1BSroCPW6Zh5Dcw+ann775g==", "requires": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", @@ -921,6 +6207,21 @@ "set-blocking": "~2.0.0" } }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -931,6 +6232,120 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", + "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "observable-to-promise": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/observable-to-promise/-/observable-to-promise-0.5.0.tgz", + "integrity": "sha1-yCjw8NxH6fhq+KSXfF1VB2znqR8=", + "dev": true, + "requires": { + "is-observable": "^0.2.0", + "symbol-observable": "^1.0.4" + }, + "dependencies": { + "is-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", + "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", + "dev": true, + "requires": { + "symbol-observable": "^0.2.2" + }, + "dependencies": { + "symbol-observable": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", + "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", + "dev": true + } + } + } + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -939,6 +6354,12 @@ "wrappy": "1" } }, + "onecolor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/onecolor/-/onecolor-3.1.0.tgz", + "integrity": "sha512-YZSypViXzu3ul5LMu/m6XjJ9ol8qAy9S2VjHl5E6UlhUH1KGKWabyEJifn0Jjpw23bYDzC2ucKMPGiH5kfwSGQ==", + "dev": true + }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", @@ -948,6 +6369,11 @@ "mimic-fn": "^1.0.0" } }, + "only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=" + }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", @@ -962,14 +6388,51 @@ "wordwrap": "~1.0.0" } }, + "ora": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.1.0.tgz", + "integrity": "sha512-vRBPaNCclUi8pUxRF/G8+5qEQkc6EgzKK1G2ZNJUIGu088Un5qIxFXeDgymvPRM9nmrcUOGzQgS1Vmtz+NtlMw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^1.3.1", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" + } + } + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, "os-homedir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-tmpdir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { @@ -981,9 +6444,183 @@ "os-tmpdir": "^1.0.0" } }, + "p-any": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-any/-/p-any-1.1.0.tgz", + "integrity": "sha512-Ef0tVa4CZ5pTAmKn+Cg3w8ABBXh+hHO1aV8281dKOoUHfX+3tjG2EaFcC+aZyagg9b4EYGsHEjz21DnEE8Og2g==", + "requires": { + "p-some": "^2.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "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-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-some": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-some/-/p-some-2.0.1.tgz", + "integrity": "sha1-Zdh8ixVO289SIdFnd4ttLhUPbwY=", + "requires": { + "aggregate-error": "^1.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 + }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, + "pako": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", + "dev": true + }, + "parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "dev": true, + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parent-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.0.tgz", + "integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", + "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", + "dev": true + } + } + }, + "parse-asn1": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.0.0.tgz", + "integrity": "sha512-AddiXFSLLCqj+tCRJ9MrUtHZB4DWojO3tk0NVZ+g5MaMQHF2+p2ktqxuoXyPFLljz/aUK0Nfhd/uGWnhXVXEyA==", + "dev": true + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "parsimmon": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.12.0.tgz", + "integrity": "sha512-uC/BjuSfb4jfaWajKCp1mVncXXq+V1twbcYChbTxN3GM7fn+8XoHwUdvUz+PTaFtDSCRQxU8+Rnh+iMhAkVwdw==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { @@ -998,22 +6635,1788 @@ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pixrem": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pixrem/-/pixrem-4.0.1.tgz", + "integrity": "sha1-LaSh3m7EQjxfw3lOkwuB1EkOxoY=", + "dev": true, + "requires": { + "browserslist": "^2.0.0", + "postcss": "^6.0.0", + "reduce-css-calc": "^1.2.7" + }, + "dependencies": { + "browserslist": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", + "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000792", + "electron-to-chromium": "^1.3.30" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pleeease-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pleeease-filters/-/pleeease-filters-4.0.0.tgz", + "integrity": "sha1-ZjKy+wVkjSdY2GU4T7zteeHMrsc=", + "dev": true, + "requires": { + "onecolor": "^3.0.4", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "plur": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/plur/-/plur-3.0.1.tgz", + "integrity": "sha512-lJl0ojUynAM1BZn58Pas2WT/TXeC1+bS+UqShl0x9+49AtOn7DixRXVzaC8qrDOIxNDmepKnLuMTH7NQmkX0PA==", + "dev": true, + "requires": { + "irregular-plurals": "^2.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-apply": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/postcss-apply/-/postcss-apply-0.8.0.tgz", + "integrity": "sha1-FOVEu7XLbxweBIhXll15rgZrE0M=", + "dev": true, + "requires": { + "babel-runtime": "^6.23.0", + "balanced-match": "^0.4.2", + "postcss": "^6.0.0" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-attribute-case-insensitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-2.0.0.tgz", + "integrity": "sha1-lNxCLI+QmX8WvTOjZUu77AhJY7Q=", + "dev": true, + "requires": { + "postcss": "^6.0.0", + "postcss-selector-parser": "^2.2.3" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-calc": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz", + "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==", + "dev": true, + "requires": { + "css-unit-converter": "^1.1.1", + "postcss": "^7.0.5", + "postcss-selector-parser": "^5.0.0-rc.4", + "postcss-value-parser": "^3.3.1" + } + }, + "postcss-color-function": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-color-function/-/postcss-color-function-4.0.1.tgz", + "integrity": "sha1-QCs/LOvD9pR+YY+2vjZU++zvZEQ=", + "dev": true, + "requires": { + "css-color-function": "~1.3.3", + "postcss": "^6.0.1", + "postcss-message-helpers": "^2.0.0", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-gray": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-color-gray/-/postcss-color-gray-4.1.0.tgz", + "integrity": "sha512-L4iLKQLdqChz6ZOgGb6dRxkBNw78JFYcJmBz1orHpZoeLtuhDDGegRtX9gSyfoCIM7rWZ3VNOyiqqvk83BEN+w==", + "dev": true, + "requires": { + "color": "^2.0.1", + "postcss": "^6.0.14", + "postcss-message-helpers": "^2.0.0", + "reduce-function-call": "^1.0.2" + }, + "dependencies": { + "color": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color/-/color-2.0.1.tgz", + "integrity": "sha512-ubUCVVKfT7r2w2D3qtHakj8mbmKms+tThR8gI8zEYCbUBl8/voqFGt3kgBqGwXAopgXybnkuOq+qMYCRrp4cXw==", + "dev": true, + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-hex-alpha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-3.0.0.tgz", + "integrity": "sha1-HlPmyKyyN5Vej9CLfs2xuLgwn5U=", + "dev": true, + "requires": { + "color": "^1.0.3", + "postcss": "^6.0.1", + "postcss-message-helpers": "^2.0.0" + }, + "dependencies": { + "color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", + "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "dev": true, + "requires": { + "color-convert": "^1.8.2", + "color-string": "^1.4.0" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-hsl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hsl/-/postcss-color-hsl-2.0.0.tgz", + "integrity": "sha1-EnA2ZvoxBDDj8wpFTawThjF9WEQ=", + "dev": true, + "requires": { + "postcss": "^6.0.1", + "postcss-value-parser": "^3.3.0", + "units-css": "^0.4.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-hwb": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-hwb/-/postcss-color-hwb-3.0.0.tgz", + "integrity": "sha1-NAKxnvTYSXVAwftQcr6YY8qVVx4=", + "dev": true, + "requires": { + "color": "^1.0.3", + "postcss": "^6.0.1", + "postcss-message-helpers": "^2.0.0", + "reduce-function-call": "^1.0.2" + }, + "dependencies": { + "color": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/color/-/color-1.0.3.tgz", + "integrity": "sha1-5I6DLYXxTvaU+0aIEcLVz+cptV0=", + "dev": true, + "requires": { + "color-convert": "^1.8.2", + "color-string": "^1.4.0" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-rebeccapurple": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-3.1.0.tgz", + "integrity": "sha512-212hJUk9uSsbwO5ECqVjmh/iLsmiVL1xy9ce9TVf+X3cK/ZlUIlaMdoxje/YpsL9cmUH3I7io+/G2LyWx5rg1g==", + "dev": true, + "requires": { + "postcss": "^6.0.22", + "postcss-values-parser": "^1.5.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-rgb": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rgb/-/postcss-color-rgb-2.0.0.tgz", + "integrity": "sha1-FFOcinExSUtILg3RzCZf9lFLUmM=", + "dev": true, + "requires": { + "postcss": "^6.0.1", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-color-rgba-fallback": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-color-rgba-fallback/-/postcss-color-rgba-fallback-3.0.0.tgz", + "integrity": "sha1-N9XJNToHoJJwkSqCYGu0Kg1wLAQ=", + "dev": true, + "requires": { + "postcss": "^6.0.6", + "postcss-value-parser": "^3.3.0", + "rgb-hex": "^2.1.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-cssnext": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-cssnext/-/postcss-cssnext-3.1.0.tgz", + "integrity": "sha512-awPDhI4OKetcHCr560iVCoDuP6e/vn0r6EAqdWPpAavJMvkBSZ6kDpSN4b3mB3Ti57hQMunHHM8Wvx9PeuYXtA==", + "dev": true, + "requires": { + "autoprefixer": "^7.1.1", + "caniuse-api": "^2.0.0", + "chalk": "^2.0.1", + "pixrem": "^4.0.0", + "pleeease-filters": "^4.0.0", + "postcss": "^6.0.5", + "postcss-apply": "^0.8.0", + "postcss-attribute-case-insensitive": "^2.0.0", + "postcss-calc": "^6.0.0", + "postcss-color-function": "^4.0.0", + "postcss-color-gray": "^4.0.0", + "postcss-color-hex-alpha": "^3.0.0", + "postcss-color-hsl": "^2.0.0", + "postcss-color-hwb": "^3.0.0", + "postcss-color-rebeccapurple": "^3.0.0", + "postcss-color-rgb": "^2.0.0", + "postcss-color-rgba-fallback": "^3.0.0", + "postcss-custom-media": "^6.0.0", + "postcss-custom-properties": "^6.1.0", + "postcss-custom-selectors": "^4.0.1", + "postcss-font-family-system-ui": "^3.0.0", + "postcss-font-variant": "^3.0.0", + "postcss-image-set-polyfill": "^0.3.5", + "postcss-initial": "^2.0.0", + "postcss-media-minmax": "^3.0.0", + "postcss-nesting": "^4.0.1", + "postcss-pseudo-class-any-link": "^4.0.0", + "postcss-pseudoelements": "^5.0.0", + "postcss-replace-overflow-wrap": "^2.0.0", + "postcss-selector-matches": "^3.0.1", + "postcss-selector-not": "^3.0.1" + }, + "dependencies": { + "browserslist": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", + "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000792", + "electron-to-chromium": "^1.3.30" + } + }, + "caniuse-api": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-2.0.0.tgz", + "integrity": "sha1-sd21pZZrFvSNxJmERNS7xsfZ2DQ=", + "dev": true, + "requires": { + "browserslist": "^2.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-calc": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-6.0.2.tgz", + "integrity": "sha512-fiznXjEN5T42Qm7qqMCVJXS3roaj9r4xsSi+meaBVe7CJBl8t/QLOXu02Z2E6oWAMWIvCuF6JrvzFekmVEbOKA==", + "dev": true, + "requires": { + "css-unit-converter": "^1.1.1", + "postcss": "^7.0.2", + "postcss-selector-parser": "^2.2.2", + "reduce-css-calc": "^2.0.0" + }, + "dependencies": { + "postcss": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "reduce-css-calc": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.6.tgz", + "integrity": "sha512-+l5/qlQmdsbM9h6JerJ/y5vR5Ci0k93aszLNpCmbadC3nBcbRGmIBm0s9Nj59i22LvCjTGftWzdQRwdknayxhw==", + "dev": true, + "requires": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-custom-media": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-6.0.0.tgz", + "integrity": "sha1-vlMnhBEOyylQRPtTlaGABushpzc=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-custom-properties": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-6.3.1.tgz", + "integrity": "sha512-zoiwn4sCiUFbr4KcgcNZLFkR6gVQom647L+z1p/KBVHZ1OYwT87apnS42atJtx6XlX2yI7N5fjXbFixShQO2QQ==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "postcss": "^6.0.18" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-custom-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-4.0.1.tgz", + "integrity": "sha1-eBOC+UxS5yfvXKR3bqKt9JphE4I=", + "dev": true, + "requires": { + "postcss": "^6.0.1", + "postcss-selector-matches": "^3.0.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-font-family-system-ui": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-family-system-ui/-/postcss-font-family-system-ui-3.0.0.tgz", + "integrity": "sha512-58G/hTxMSSKlIRpcPUjlyo6hV2MEzvcVO2m4L/T7Bb2fJTG4DYYfQjQeRvuimKQh1V1sOzCIz99g+H2aFNtlQw==", + "dev": true, + "requires": { + "postcss": "^6.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-font-variant": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-3.0.0.tgz", + "integrity": "sha1-CMzIj2BQuoLtjvLMdsDGprQfGD4=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-image-set-polyfill": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/postcss-image-set-polyfill/-/postcss-image-set-polyfill-0.3.5.tgz", + "integrity": "sha1-Dxk0E3AM8fgr05Bm7wFtZaShgYE=", + "dev": true, + "requires": { + "postcss": "^6.0.1", + "postcss-media-query-parser": "^0.2.3" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-import": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", + "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", + "dev": true, + "requires": { + "postcss": "^7.0.1", + "postcss-value-parser": "^3.2.3", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-initial": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-2.0.0.tgz", + "integrity": "sha1-cnFfczbgu3k1HZnuZcSiU6hEG6Q=", + "dev": true, + "requires": { + "lodash.template": "^4.2.4", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-media-minmax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-3.0.0.tgz", + "integrity": "sha1-Z1JWA3pD70C8Twdgv9BtTcadSNI=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + } + }, + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "dev": true, + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-message-helpers": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", + "dev": true + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "dev": true, + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-nesting": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-4.2.1.tgz", + "integrity": "sha512-IkyWXICwagCnlaviRexi7qOdwPw3+xVVjgFfGsxmztvRVaNxAlrypOIKqDE5mxY+BVxnId1rnUKBRQoNE2VDaA==", + "dev": true, + "requires": { + "postcss": "^6.0.11" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-pseudo-class-any-link": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-4.0.0.tgz", + "integrity": "sha1-kVKgYT00UHIFE+iJKFS65C0O5o4=", + "dev": true, + "requires": { + "postcss": "^6.0.1", + "postcss-selector-parser": "^2.2.3" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-pseudoelements": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-pseudoelements/-/postcss-pseudoelements-5.0.0.tgz", + "integrity": "sha1-7vGU6NUkZFylIKlJ6V5RjoEkAss=", + "dev": true, + "requires": { + "postcss": "^6.0.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + } + }, + "postcss-replace-overflow-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-2.0.0.tgz", + "integrity": "sha1-eU22+qVPjbEAhUOSqTr0V2i04ls=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-selector-matches": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-matches/-/postcss-selector-matches-3.0.1.tgz", + "integrity": "sha1-5WNAEeE5UIgYYbvdWMLQER/8lqs=", + "dev": true, + "requires": { + "balanced-match": "^0.4.2", + "postcss": "^6.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-selector-not": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-3.0.1.tgz", + "integrity": "sha1-Lk2y8JZTNsAefOx9tsYN/3ZzNdk=", + "dev": true, + "requires": { + "balanced-match": "^0.4.2", + "postcss": "^6.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-selector-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz", + "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==", + "dev": true, + "requires": { + "cssesc": "^2.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "postcss-svgo": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", + "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "dev": true, + "requires": { + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "postcss-values-parser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-1.5.0.tgz", + "integrity": "sha512-3M3p+2gMp0AH3da530TlX8kiO1nxdTnc3C6vr8dMxRLIlh8UYkz0/wcwptSXjhtx2Fr0TySI7a+BHDQ8NL7LaQ==", + "dev": true, + "requires": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, "prettier": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz", - "integrity": "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==", + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "dev": true + }, + "pretty-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-4.0.0.tgz", + "integrity": "sha512-qG66ahoLCwpLXD09ZPHSCbUWYTqdosB7SMP4OffgTgL2PBKXMuUsrk5Bwg8q4qPkjTXsKBMr+YK3Ltd/6F9s/Q==", + "dev": true, + "requires": { + "parse-ms": "^2.0.0" + } + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true }, "process-nextick-args": { @@ -1027,12 +8430,154 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.6.0.tgz", + "integrity": "sha512-KIJqT9jQJDQx5h5uAVPimw6yVg2SekOKu959OCtktD3FjzbpvaPr8i4zzg07DOMz+igA4W/aNM7OV8H37pFYfA==" + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + } + } + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -1046,14 +8591,97 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" } } }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "dev": true, + "requires": { + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "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", @@ -1063,30 +8691,102 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + } } }, - "redis": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", - "optional": true, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, "requires": { - "double-ended-queue": "^2.1.0-0", - "redis-commands": "^1.2.0", - "redis-parser": "^2.6.0" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" } }, - "redis-commands": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.4.0.tgz", - "integrity": "sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==", - "optional": true + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + } }, - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", - "optional": true + "reduce-css-calc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "dev": true, + "requires": { + "balanced-match": "^0.4.2", + "math-expression-evaluator": "^1.2.14", + "reduce-function-call": "^1.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + } + } + }, + "reduce-function-call": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", + "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "dev": true, + "requires": { + "balanced-match": "^0.4.2" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + } + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz", + "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } }, "regexpp": { "version": "2.0.1", @@ -1094,24 +8794,95 @@ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, - "require-uncached": { - "version": "1.0.3", - "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "regexpu-core": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.4.0.tgz", + "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==", "dev": true, "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^7.0.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.0.2" + } + }, + "registry-auth-token": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "dev": true + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" }, "dependencies": { - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true } } }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "require-precompiled": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/require-precompiled/-/require-precompiled-0.1.0.tgz", + "integrity": "sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo=", + "dev": true + }, "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", @@ -1121,11 +8892,76 @@ "semver": "^5.1.0" } }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, + "resolve-path": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/resolve-path/-/resolve-path-1.4.0.tgz", + "integrity": "sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc=", + "requires": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + } + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -1136,12 +8972,115 @@ "signal-exit": "^3.0.2" } }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rgb": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/rgb/-/rgb-0.1.0.tgz", + "integrity": "sha1-vieykej+/+rBvZlylyG/pA/AN7U=", + "dev": true + }, + "rgb-hex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rgb-hex/-/rgb-hex-2.1.0.tgz", + "integrity": "sha1-x3PF/iJoolV42SU5qCp6XOU77aY=", + "dev": true + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rollup": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.2.2.tgz", + "integrity": "sha512-fsn5KJcfSuejjrv8GV7kZNciElqxyzZdUq8rA3e528JsR3ccxrWwoptyUY8GGLlgMFAQMB3dZW8nWF2I1/xrZA==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "@types/node": "*", + "acorn": "^6.1.0" + } + }, + "rollup-plugin-json": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-3.1.0.tgz", + "integrity": "sha512-BlYk5VspvGpjz7lAwArVzBXR60JK+4EKtPkCHouAWg39obk9S61hZYJDBfMK+oitPdoe11i69TlxKlMQNFC/Uw==", + "dev": true, + "requires": { + "rollup-pluginutils": "^2.3.1" + } + }, + "rollup-plugin-replace": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.1.0.tgz", + "integrity": "sha512-SxrAIgpH/B5/W4SeULgreOemxcpEgKs2gcD42zXw50bhqGWmcnlXneVInQpAqzA/cIly4bJrOpeelmB9p4YXSQ==", + "dev": true, + "requires": { + "magic-string": "^0.25.1", + "minimatch": "^3.0.2", + "rollup-pluginutils": "^2.0.1" + } + }, + "rollup-plugin-terser": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-4.0.4.tgz", + "integrity": "sha512-wPANT5XKVJJ8RDUN0+wIr7UPd0lIXBo4UdJ59VmlPCtlFsE20AM+14pe+tk7YunCsWEiuzkDBY3QIkSCjtrPXg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "jest-worker": "^24.0.0", + "serialize-javascript": "^1.6.1", + "terser": "^3.14.1" + } + }, + "rollup-plugin-typescript": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript/-/rollup-plugin-typescript-1.0.0.tgz", + "integrity": "sha512-d2KDNMJXgaaB//dDGd/YmyMiopt1Pz965Iu3zmEoL08YqNcKRBz26uHqqc47rFGfrJV5kFqifC9IYlh6dpSCLg==", + "dev": true, + "requires": { + "resolve": "^1.8.1", + "rollup-pluginutils": "^2.3.1" + } + }, + "rollup-pluginutils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.4.1.tgz", + "integrity": "sha512-wesMQ9/172IJDIW/lYWm0vW0LiKe5Ekjws481R7z9WTRtmO59cqyM/2uUlxvf6yzm/fElFmHUobeQOYz46dZJw==", + "dev": true, + "requires": { + "estree-walker": "^0.6.0", + "micromatch": "^3.1.10" } }, "run-async": { @@ -1153,10 +9092,19 @@ "is-promise": "^2.1.0" } }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -1167,6 +9115,15 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -1186,6 +9143,17 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, "seedrandom": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", @@ -1196,11 +9164,76 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, + "serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", + "dev": true + }, + "serialize-javascript": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", + "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", + "dev": true + }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -1221,14 +9254,35 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + } + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, "slice-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.0.0.tgz", - "integrity": "sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" }, "dependencies": { @@ -1240,6 +9294,189 @@ } } }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "sourcemap-codec": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz", + "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==", + "dev": true + }, "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -1249,12 +9486,139 @@ "memory-pager": "^1.0.2" } }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, "sprintf-js": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -1267,7 +9631,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "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" @@ -1275,35 +9639,924 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-bom-buf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", + "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", + "dev": true, + "requires": { + "is-utf8": "^0.2.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz", + "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=", + "dev": true, + "requires": { + "dot-prop": "^4.1.1", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "supertap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-1.0.0.tgz", + "integrity": "sha512-HZJ3geIMPgVwKk2VsmO5YHqnnJYl6bV5A9JW2uzqV43WmpgliNEYbuvukfor7URpaqpxuw3CfZ3ONdVbZjCgIA==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "indent-string": "^3.2.0", + "js-yaml": "^3.10.0", + "serialize-error": "^2.1.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" } }, - "table": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/table/-/table-5.1.1.tgz", - "integrity": "sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw==", + "svgo": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.1.1.tgz", + "integrity": "sha512-GBkJbnTuFpM4jFbiERHDWhZc/S/kpHToqmZag3aEBjPYK44JAN2QBjvrGIxLOoCyMZjuFQIfTO2eJd8uwLY/9g==", "dev": true, "requires": { - "ajv": "^6.6.1", + "coa": "~2.0.1", + "colors": "~1.1.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "~0.1.0", + "css-tree": "1.0.0-alpha.28", + "css-url-regex": "^1.1.0", + "csso": "^3.5.0", + "js-yaml": "^3.12.0", + "mkdirp": "~0.5.1", + "object.values": "^1.0.4", + "sax": "~1.2.4", + "stable": "~0.1.6", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, + "table": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz", + "integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==", + "dev": true, + "requires": { + "ajv": "^6.9.1", "lodash": "^4.17.11", - "slice-ansi": "2.0.0", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "string-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.0.0.tgz", + "integrity": "sha512-rr8CUxBbvOZDUvc5lNIJ+OC1nPVpz+Siw9VBtUjB9b6jZehZLFt0JMCZzShFHIsI8cbhm0EsNIfWJMFV3cu3Ew==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.0.0" + } + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" + } + } + } + }, + "tapable": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", + "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==", + "dev": true + }, + "tar": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, + "terser": { + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.16.1.tgz", + "integrity": "sha512-JDJjgleBROeek2iBcSNzOHLKsB/MdDf+E/BOAJ0Tk9r7p9/fVobfv7LMJ/g/k3v9SXdmjZnIlFd5nfn/Rt0Xow==", + "dev": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1", + "source-map-support": "~0.5.9" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.2.tgz", + "integrity": "sha512-1DMkTk286BzmfylAvLXwpJrI7dWa5BnFmscV/2dCr8+c56egFcbaeFAl7+sujAjdmpLam21XRdhA4oifLyiWWg==", + "dev": true, + "requires": { + "cacache": "^11.0.2", + "find-cache-dir": "^2.0.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "terser": "^3.16.1", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "thenify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", + "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha1-mcW/VZWJZq9tBtg73zgA3IL67F0=", + "dev": true + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", + "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "ts-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tsutils": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.8.0.tgz", + "integrity": "sha512-XQdPhgcoTbCD8baXC38PQ0vpTZ8T3YrE+vR66YIj/xvDt1//8iAhafpIT/4DmvzzC1QFapEImERu48Pa01dIUA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3.tgz", + "integrity": "sha512-Y21Xqe54TBVp+VDSNbuDYdGw0BpoR/Q6wo/+35M8PAU0vipahnyduJWirxxdxjsAkS7hue53x2zp8gz7F05u0A==", + "dev": true + }, + "uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", + "dev": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz", + "integrity": "sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz", + "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", + "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "unique-temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", + "integrity": "sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1", + "os-tmpdir": "^1.0.1", + "uid2": "0.0.3" + } + }, + "units-css": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/units-css/-/units-css-0.4.0.tgz", + "integrity": "sha1-1iKGU6UZg9fBb/KPi53Dsf/tOgc=", + "dev": true, + "requires": { + "isnumeric": "^0.2.0", + "viewport-dimensions": "^0.2.0" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urijs": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.1.tgz", + "integrity": "sha512-xVrGVi94ueCJNrBSTjWqjvtgvl3cyOTThp2zaMaFNGp3F542TR6sM3f2o8RqZl+AwteClSVmoCyt0ka4RjQOQg==" + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "vendors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", + "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==", + "dev": true + }, + "viewport-dimensions": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/viewport-dimensions/-/viewport-dimensions-0.2.0.tgz", + "integrity": "sha1-3nQHR9tTh/0XJfUXXpG6x2r982w=", + "dev": true + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, + "requires": { + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webpack": { + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.29.5.tgz", + "integrity": "sha512-DuWlYUT982c7XVHodrLO9quFbNpVq5FNxLrMUfYUTlgKW0+yPimynYf1kttSQpEneAL1FH3P3OLNgkyImx8qIQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.3", + "@webassemblyjs/helper-module-context": "1.8.3", + "@webassemblyjs/wasm-edit": "1.8.3", + "@webassemblyjs/wasm-parser": "1.8.3", + "acorn": "^6.0.5", + "acorn-dynamic-import": "^4.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chrome-trace-event": "^1.0.0", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.0", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "micromatch": "^3.1.8", + "mkdirp": "~0.5.0", + "neo-async": "^2.5.0", + "node-libs-browser": "^2.0.0", + "schema-utils": "^1.0.0", + "tapable": "^1.1.0", + "terser-webpack-plugin": "^1.1.0", + "watchpack": "^1.5.0", + "webpack-sources": "^1.3.0" + } + }, + "webpack-sources": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", + "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "well-known-symbols": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", + "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { "string-width": "^2.1.1" }, "dependencies": { @@ -1340,111 +10593,94 @@ } } }, - "tar": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, + "worker-farm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", + "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, "requires": { "mkdirp": "^0.5.1" } }, + "write-file-atomic": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + }, + "yaml": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.3.2.tgz", + "integrity": "sha512-ZZZIdcApMRcAez37EVrtCim+8JUESX0zRcsv+HMfatIX79cX22CAnVkxDrZhAmzsnka2nb/mvaTybzDYcnrIew==", + "dev": true + }, + "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" + } + }, + "ylru": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz", + "integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==" + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true } } } diff --git a/package.json b/package.json index a1392d9..62e23e1 100644 --- a/package.json +++ b/package.json @@ -16,39 +16,54 @@ "license": "AGPL-3.0", "preferGlobal": true, "directories": { - "bin": "bin" + "bin": "bin", + "tools": "tools" }, "dependencies": { - "jsonwebtoken": "^8.3.0", + "jsonwebtoken": "^8.4.0", + "koa": "^2.7.0", "koa-bodyparser": "^4.2.1", "koa-compress": "^3.0.0", - "koa-jwt": "^3.3.2", + "koa-jwt": "^3.5.1", "koa-router": "^7.4.0", "koa-static": "^5.0.0", - "koa": "^2.5.2", "later": "^1.2.0", "libxmljs": "^0.19.5", - "mongodb": "^3.1.10", + "mongodb": "^3.1.13", "parsimmon": "^1.12.0", "seedrandom": "^2.4.4" }, "devDependencies": { - "ava": "^1.1.0", - "babel-eslint": "^8.2.6", - "codemirror": "^5.40.0", - "cssnano": "^4.0.5", - "eslint": "^5.10.0", - "esm": "^3.1.1", + "@types/jsonwebtoken": "^8.3.0", + "@types/koa": "^2.0.48", + "@types/koa-compress": "^2.0.8", + "@types/koa-router": "^7.0.39", + "@types/koa-static": "^4.0.1", + "@types/libxmljs": "^0.18.3", + "@types/mithril": "^1.1.16", + "@types/mongodb": "^3.1.19", + "@types/parsimmon": "^1.10.0", + "@types/seedrandom": "^2.4.27", + "@typescript-eslint/eslint-plugin": "^1.3.0", + "ava": "^1.2.1", + "codemirror": "^5.43.0", + "cssnano": "^4.1.10", + "eslint": "^5.14.1", + "eslint-config-prettier": "^4.0.0", + "esm": "^3.2.5", "mithril": "^1.1.6", "postcss-cssnext": "^3.1.0", - "postcss-import": "^11.1.0", - "prettier": "^1.15.3", - "rollup": "^1.1.2", + "postcss-import": "^12.0.1", + "prettier": "^1.16.4", + "rollup": "^1.2.1", "rollup-plugin-json": "^3.1.0", "rollup-plugin-replace": "^2.1.0", - "rollup-plugin-terser": "^4.0.2", - "webpack": "^4.16.3", - "yaml": "^1.0.0" + "rollup-plugin-terser": "^4.0.4", + "rollup-plugin-typescript": "^1.0.0", + "ts-node": "^8.0.2", + "typescript": "^3.3.3", + "webpack": "^4.29.5", + "yaml": "^1.3.2" }, "engines": { "node": ">=8.14.0" @@ -57,8 +72,12 @@ "compile": "echo 'Compile step no longer required, skipping.'", "configure": "if [ ! -f ./config/config.json ]; then cp ./config/config-sample.json ./config/config.json; fi", "install": "npm run configure", - "test": "ava -r esm --verbose --color", - "lint": "eslint --fix lib ui build test bin/* tools/*; prettier --parser babylon --write \"lib/**/*.js\" \"ui/**/*.js\" \"build/**/*.js\" \"test/**/*.js\" bin/* tools/*", - "build": "node build/build" + "test": "ava --verbose --color", + "lint-ln": "find bin -type f -exec sh -c 'ln -fsr \"$1\" \"bin/.${1#bin/}.ts\"' _ {} \\;; find tools -type f -exec sh -c 'ln -fsr \"$1\" \"tools/.${1#tools/}.ts\"' _ {} \\;", + "lint-eslint": "eslint --fix \"bin/**/*.ts\" \"lib/**/*.ts\" \"ui/**/*.ts\" \"test/**/*.ts\" \"build/**/*.ts\" \"tools/**/*.ts\"", + "lint-prettier": "prettier --parser typescript --write \"bin/**/*.ts\" \"lib/**/*.ts\" \"ui/**/*.ts\" \"test/**/*.ts\" \"build/**/*.ts\" \"tools/**/*.ts\"", + "lint-tsc": "tsc --noEmit", + "lint": "npm run lint-ln && npm run lint-eslint && npm run lint-prettier && npm run lint-tsc", + "build": "node -r esm -r ts-node/register/transpile-only build/build" } } diff --git a/test/common.js b/test/common.ts similarity index 83% rename from test/common.js rename to test/common.ts index 06f724b..5af7c57 100644 --- a/test/common.js +++ b/test/common.ts @@ -1,7 +1,6 @@ -"use strict"; - import ava from "ava"; -import * as common from "../lib/common.js"; +import * as common from "../lib/common"; +import { ParamPath } from "../lib/types"; ava("typeOf", t => { const cases = [ @@ -65,24 +64,24 @@ ava("generateDeviceId", t => { }); ava("parsePath", t => { - const case1 = ["Seg1.Seg2.Seg3", ["Seg1", "Seg2", "Seg3"]]; + const case1 = ["Seg1.Seg2.Seg3", ["Seg1", "Seg2", "Seg3"]] as ParamPath; case1[1].alias = 0; case1[1].wildcard = 0; - const case2 = ["Seg1.*.*.Seg4", ["Seg1", "*", "*", "Seg4"]]; + const case2 = ["Seg1.*.*.Seg4", ["Seg1", "*", "*", "Seg4"]] as ParamPath; case2[1].alias = 0; case2[1].wildcard = 6; const case3 = [ "Seg1.Seg2.[Seg6:Seg9].Seg3", ["Seg1", "Seg2", [["Seg6"], "Seg9"], "Seg3"] - ]; + ] as ParamPath; case3[1].alias = 4; case3[1].wildcard = 0; case3[1][2][0].alias = 0; case3[1][2][0].wildcard = 0; - const case4 = ["Seg1.[*:SegAny]", ["Seg1", [["*"], "SegAny"]]]; + const case4 = ["Seg1.[*:SegAny]", ["Seg1", [["*"], "SegAny"]]] as ParamPath; case4[1].alias = 2; case4[1].wildcard = 0; case4[1][1][0].alias = 0; @@ -93,24 +92,33 @@ ava("parsePath", t => { }); ava("addPathMeta", t => { - const case1 = [["Seg1", "Seg2", "Seg3"], ["Seg1", "Seg2", "Seg3"]]; + const case1 = [ + ["Seg1", "Seg2", "Seg3"], + ["Seg1", "Seg2", "Seg3"] + ] as ParamPath; case1[1].alias = 0; case1[1].wildcard = 0; - const case2 = [["Seg1", "*", "*", "Seg4"], ["Seg1", "*", "*", "Seg4"]]; + const case2 = [ + ["Seg1", "*", "*", "Seg4"], + ["Seg1", "*", "*", "Seg4"] + ] as ParamPath; case2[1].alias = 0; case2[1].wildcard = 6; const case3 = [ ["Seg1", "Seg2", [["Seg6"], "Seg9"], "Seg3"], ["Seg1", "Seg2", [["Seg6"], "Seg9"], "Seg3"] - ]; + ] as ParamPath; case3[1].alias = 4; case3[1].wildcard = 0; case3[1][2][0].alias = 0; case3[1][2][0].wildcard = 0; - const case4 = [["Seg1", [["*"], "SegAny"]], ["Seg1", [["*"], "SegAny"]]]; + const case4 = [ + ["Seg1", [["*"], "SegAny"]], + ["Seg1", [["*"], "SegAny"]] + ] as ParamPath; case4[1].alias = 2; case4[1].wildcard = 0; case4[1][1][0].alias = 0; diff --git a/tools/configure-ui b/tools/configure-ui index 01931e6..a899ed0 100755 --- a/tools/configure-ui +++ b/tools/configure-ui @@ -1,6 +1,4 @@ -#!/usr/bin/env -S node -r esm -"use strict"; - +#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only import { MongoClient } from "mongodb"; import { get } from "../lib/config"; @@ -160,11 +158,10 @@ const configData = { "ui.pageSize": "10" }; -async function run() { - const client = await MongoClient.connect( - get("MONGODB_CONNECTION_URL"), - { useNewUrlParser: true } - ); +async function run(): Promise { + const client = await MongoClient.connect(get("MONGODB_CONNECTION_URL"), { + useNewUrlParser: true + }); const collection = client.db().collection("config"); await collection.deleteMany({}); const objs = Object.entries(configData).map(c => ({ diff --git a/tools/dump-data-model b/tools/dump-data-model index af0bd1b..771d005 100755 --- a/tools/dump-data-model +++ b/tools/dump-data-model @@ -1,4 +1,4 @@ -#!/usr/bin/env -S node -r esm +#!/usr/bin/env -S node -r esm -r ts-node/register/transpile-only /** * Copyright 2013-2017 Zaid Abdulla * @@ -17,10 +17,9 @@ * You should have received a copy of the GNU Affero General Public License * along with GenieACS. If not, see . */ -"use strict"; -import fs from "fs"; -import path from "path"; +import * as fs from "fs"; +import * as path from "path"; import { connect, devicesCollection } from "../lib/db"; const outputFilename = path.resolve(`data_model_${process.argv[2]}.json`); @@ -28,7 +27,7 @@ process.chdir(path.resolve(path.dirname(fs.realpathSync(__filename)), "..")); const dataModel = {}; -function recursive(object, p) { +function recursive(object, p): void { if (!p) p = ""; for (const key in object) { diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c3f0f21 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "lib": [ + "esnext", "dom" + ], + "module": "esnext", + "moduleResolution": "node", + "target": "esnext", + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "alwaysStrict": true, + "noImplicitReturns": true, + "strictFunctionTypes": true, + "allowJs": true + }, + "include": [ + "./bin/.*.ts", + "./lib/**/*", + "./ui/**/*", + "./test/**/*", + "./build/**/*", + "./toos/.*.ts" + ] +} diff --git a/ui/.eslintrc.json b/ui/.eslintrc.json index 35ee742..1147cf1 100644 --- a/ui/.eslintrc.json +++ b/ui/.eslintrc.json @@ -2,9 +2,5 @@ "env": { "browser": true, "node": false - }, - "parser": "babel-eslint", - "parserOptions": { - "allowImportExportEverywhere": true } } diff --git a/ui/admin-menu.js b/ui/admin-menu.ts similarity index 87% rename from ui/admin-menu.js rename to ui/admin-menu.ts index 0727f6a..50f9add 100644 --- a/ui/admin-menu.js +++ b/ui/admin-menu.ts @@ -1,11 +1,10 @@ -"use strict"; - import m from "mithril"; +import { ClosureComponent, Component } from "mithril"; -export default function menu() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const active = { [vnode.attrs.page]: "active" }; + const active = { [vnode.attrs["page"]]: "active" }; const tabs = []; if (window.authorizer.hasAccess("presets", 1)) { @@ -61,4 +60,6 @@ export default function menu() { return m("nav#side-menu", m("ul", tabs)); } }; -} +}; + +export default component; diff --git a/ui/app.js b/ui/app.ts similarity index 85% rename from ui/app.js rename to ui/app.ts index 3716cce..2f02062 100644 --- a/ui/app.js +++ b/ui/app.ts @@ -1,7 +1,4 @@ -"use strict"; - -import m from "mithril"; - +import m, { RouteResolver } from "mithril"; import layout from "./layout"; import * as store from "./store"; import * as loginPage from "./login-page"; @@ -19,6 +16,15 @@ import Authorizer from "../lib//common/authorizer"; import * as notifications from "./notifications"; import { contextifyComponent } from "./components"; +declare global { + interface Window { + authorizer: Authorizer; + permissionSets: any; + username: string; + clientConfig: any; + } +} + window.authorizer = new Authorizer(window.permissionSets); const adminPages = [ @@ -35,7 +41,7 @@ let lastRenderTimestamp = 0; let pageVisitTimestamp = 0; let fulfillTimeout = null; -function fulfill() { +function fulfill(): void { clearTimeout(fulfillTimeout); fulfillTimeout = setTimeout(() => { store.fulfill(lastRenderTimestamp, pageVisitTimestamp).then(updated => { @@ -44,16 +50,19 @@ function fulfill() { }, 100); } -function pagify(pageName, page) { - const component = { +function pagify(pageName, page): RouteResolver { + const component: RouteResolver = { render: () => { lastRenderTimestamp = Date.now(); let p; if (state && state.error) p = m(errorPage.component, state); else p = m(contextifyComponent(page.component), state); fulfill(); - return m(layout, { page: pageName }, p); - } + const attrs = {}; + attrs["page"] = pageName; + return m(layout, attrs, p); + }, + onmatch: null }; component.onmatch = (args, requestedPath) => { @@ -87,8 +96,8 @@ function pagify(pageName, page) { return component; } -function redirectAdminPage() { - const component = { +function redirectAdminPage(): RouteResolver { + const component: RouteResolver = { onmatch: () => { for (const page of adminPages) { if (window.authorizer.hasAccess(page, 2)) { diff --git a/ui/autocomplete-compnent.js b/ui/autocomplete-compnent.ts similarity index 86% rename from ui/autocomplete-compnent.js rename to ui/autocomplete-compnent.ts index 19a3c8e..8bf76d4 100644 --- a/ui/autocomplete-compnent.js +++ b/ui/autocomplete-compnent.ts @@ -1,7 +1,16 @@ -"use strict"; +export default class Autocomplete { + private callback: ( + value: string, + callback: (suggestions: string[]) => void + ) => void; + private element: HTMLInputElement; + private hideTimeout: NodeJS.Timeout; + private visible: boolean; + private default: string; + private selection: number; + private container: HTMLElement; -class Autocomplete { - constructor(className, callback) { + public constructor(className, callback) { this.callback = callback; this.element = null; this.hideTimeout = null; @@ -12,11 +21,11 @@ class Autocomplete { this.container = document.createElement("div"); this.container.style.position = "absolute"; this.container.style.display = "block"; - this.container.style.opacity = 0; + this.container.style.opacity = "0"; this.container.className = className; } - attach(el) { + public attach(el): void { el.setAttribute("autocomplete", "off"); el.addEventListener("focus", () => { @@ -63,8 +72,8 @@ class Autocomplete { }); } - hide() { - this.container.style.opacity = 0; + private hide(): void { + this.container.style.opacity = "0"; this.visible = false; this.default = null; this.selection = null; @@ -77,7 +86,7 @@ class Autocomplete { }, 500); } - update() { + private update(): void { const el = this.element; this.callback(el.value, suggestions => { @@ -101,7 +110,7 @@ class Autocomplete { clearTimeout(this.hideTimeout); this.hideTimeout = null; } - this.container.style.opacity = 1; + this.container.style.opacity = "1"; this.visible = true; } @@ -128,7 +137,7 @@ class Autocomplete { e.addEventListener("mousedown", ev => { ev.preventDefault(); el.value = suggestion; - if (this.element === el) this.update(el); + if (this.element === el) this.update(); }); this.container.appendChild(e); } @@ -150,5 +159,3 @@ class Autocomplete { }); } } - -export default Autocomplete; diff --git a/ui/components.js b/ui/components.ts similarity index 65% rename from ui/components.js rename to ui/components.ts index b006fd0..5e57510 100644 --- a/ui/components.js +++ b/ui/components.ts @@ -1,6 +1,12 @@ -"use strict"; - -import m from "mithril"; +import m, { + Static, + Attributes, + Children, + ComponentTypes, + Lifecycle, + ClosureComponent, + Vnode +} from "mithril"; import parameter from "./components/parameter"; import parameterList from "./components/parameter-list"; import parameterTable from "./components/parameter-table"; @@ -31,13 +37,33 @@ const comps = { "long-text": longTextComponent }; -const contextifiedComponents = new WeakMap(); -const vnodeContext = new WeakMap(); +const contextifiedComponents = new WeakMap(); +const vnodeContext = new WeakMap(); -function contextFn(context, ...argumentsList) { - const vnode = Reflect.apply(M, undefined, argumentsList); - vnodeContext.set(vnode, context); - return vnode; +interface MC extends Static { + context: { + (ctx: Attributes, selector: string, ...children: Children[]): Vnode< + any, + any + >; + ( + ctx: Attributes, + selector: string, + attributes: Attributes, + ...children: Children[] + ): Vnode; + ( + ctx: Attributes, + component: ComponentTypes, + ...args: Children[] + ): Vnode; + ( + ctx: Attributes, + component: ComponentTypes, + attributes: Attrs & Lifecycle & { key?: string | number }, + ...args: Children[] + ): Vnode; + }; } const M = new Proxy(m, { @@ -52,9 +78,15 @@ const M = new Proxy(m, { if (prop === "context") return contextFn; else return Reflect.get(target, prop); } -}); +}) as MC; -function applyContext(vnode, parentContext) { +function contextFn(context, ...argumentsList): Vnode { + const vnode = Reflect.apply(M, undefined, argumentsList); + vnodeContext.set(vnode, context); + return vnode; +} + +function applyContext(vnode, parentContext): void { if (Array.isArray(vnode)) { for (const c of vnode) applyContext(c, parentContext); } else if (vnode && typeof vnode === "object" && vnode.tag) { @@ -66,25 +98,25 @@ function applyContext(vnode, parentContext) { } } -export function contextifyComponent(component) { +export function contextifyComponent(component: ComponentTypes): ComponentTypes { let c = contextifiedComponents.get(component); if (!c) { if (typeof component !== "function") { c = Object.assign({}, component); const view = component.view; - c.view = vnode => { + c.view = function(vnode) { const context = vnodeContext.get(vnode) || {}; - const res = view(vnode, M); + const res = Reflect.apply(view, this, [vnode]); applyContext(res, context); return res; }; - } else if (!component.prototype.view) { + } else if (!component.prototype || !component.prototype.view) { c = initialNode => { - const state = component(initialNode); + const state = (component as ClosureComponent)(initialNode); const view = state.view; - state.view = vnode => { + state.view = function(vnode) { const context = vnodeContext.get(vnode) || {}; - const res = view(vnode, M); + const res = Reflect.apply(view, this, [vnode]); applyContext(res, context); return res; }; diff --git a/ui/components/all-parameters.js b/ui/components/all-parameters.ts similarity index 85% rename from ui/components/all-parameters.js rename to ui/components/all-parameters.ts index 8cfa226..ce94781 100644 --- a/ui/components/all-parameters.js +++ b/ui/components/all-parameters.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "../components"; import * as taskQueue from "../task-queue"; import { parse } from "../../lib/common/expression-parser"; @@ -7,30 +6,30 @@ import memoize from "../../lib/common/memoize"; const memoizedParse = memoize(parse); -function escapeRegExp(str) { +function escapeRegExp(str): string { return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"); } -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const device = vnode.attrs.device; + const device = vnode.attrs["device"]; const search = m("input", { type: "text", placeholder: "Search parameters", oninput: e => { - vnode.state.searchString = e.target.value; + vnode.state["searchString"] = e.target.value; e.redraw = false; - clearTimeout(vnode.state.timeout); - vnode.state.timeout = setTimeout(m.redraw, 500); + clearTimeout(vnode.state["timeout"]); + vnode.state["timeout"] = setTimeout(m.redraw, 500); } }); const instanceRegex = /\.[0-9]+$/; let re; - if (vnode.state.searchString) { - const keywords = vnode.state.searchString.split(" ").filter(s => s); + if (vnode.state["searchString"]) { + const keywords = vnode.state["searchString"].split(" ").filter(s => s); if (keywords.length) re = new RegExp(keywords.map(s => escapeRegExp(s)).join(".*"), "i"); } @@ -43,7 +42,7 @@ export default function component() { const attrs = {}; if (re) { const str = p.value && p.value[0] ? `${k} ${p.value[0]}` : k; - if (!re.test(str)) attrs.style = "display: none;"; + if (!re.test(str)) attrs["style"] = "display: none;"; } if (p.object === false) { @@ -132,4 +131,6 @@ export default function component() { ); } }; -} +}; + +export default component; diff --git a/ui/components/container.js b/ui/components/container.js deleted file mode 100644 index 416d7ff..0000000 --- a/ui/components/container.js +++ /dev/null @@ -1,22 +0,0 @@ -"use strict"; - -import { m } from "../components"; -import * as store from "../store"; - -export default function component() { - return { - view: vnode => { - if (vnode.attrs.filter) { - if (!store.evaluateExpression(vnode.attrs.filter, vnode.attrs.device)) - return null; - } - - const children = Object.values(vnode.attrs.components).map(c => { - if (typeof c !== "object") return `${c}`; - return m(c.type, c); - }); - if (vnode.attrs.element) return m(vnode.attrs.element, children); - else return children; - } - }; -} diff --git a/ui/components/container.ts b/ui/components/container.ts new file mode 100644 index 0000000..3ae7a59 --- /dev/null +++ b/ui/components/container.ts @@ -0,0 +1,28 @@ +import { ClosureComponent, Component } from "mithril"; +import { m } from "../components"; +import * as store from "../store"; + +const component: ClosureComponent = (): Component => { + return { + view: vnode => { + if (vnode.attrs["filter"]) { + if ( + !store.evaluateExpression( + vnode.attrs["filter"], + vnode.attrs["device"] + ) + ) + return null; + } + + const children = Object.values(vnode.attrs["components"]).map(c => { + if (typeof c !== "object") return `${c}`; + return m(c["type"], c); + }); + if (vnode.attrs["element"]) return m(vnode.attrs["element"], children); + else return children; + } + }; +}; + +export default component; diff --git a/ui/components/device-actions.js b/ui/components/device-actions.ts similarity index 91% rename from ui/components/device-actions.js rename to ui/components/device-actions.ts index f7d015d..3dda48d 100644 --- a/ui/components/device-actions.js +++ b/ui/components/device-actions.ts @@ -1,14 +1,13 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "../components"; import * as taskQueue from "../task-queue"; import * as notifications from "../notifications"; import * as store from "../store"; -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const device = vnode.attrs.device; + const device = vnode.attrs["device"]; const buttons = []; @@ -87,4 +86,6 @@ export default function component() { return m(".actions-bar", buttons); } }; -} +}; + +export default component; diff --git a/ui/components/device-faults.js b/ui/components/device-faults.ts similarity index 91% rename from ui/components/device-faults.js rename to ui/components/device-faults.ts index 0a31c0c..85c0179 100644 --- a/ui/components/device-faults.js +++ b/ui/components/device-faults.ts @@ -1,13 +1,12 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "../components"; import * as store from "../store"; import * as notifications from "../notifications"; -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const device = vnode.attrs.device; + const device = vnode.attrs["device"]; const deviceId = device["DeviceID.ID"].value[0]; const faults = store.fetch("faults", [ "AND", @@ -72,4 +71,6 @@ export default function component() { return m("table.table", thead, tbody); } }; -} +}; + +export default component; diff --git a/ui/components/device-link.js b/ui/components/device-link.ts similarity index 54% rename from ui/components/device-link.js rename to ui/components/device-link.ts index 404d83c..12508e0 100644 --- a/ui/components/device-link.js +++ b/ui/components/device-link.ts @@ -1,18 +1,17 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "../components"; -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { let deviceId; - if (vnode.attrs.device) - deviceId = vnode.attrs.device["DeviceID.ID"].value[0]; + if (vnode.attrs["device"]) + deviceId = vnode.attrs["device"]["DeviceID.ID"].value[0]; - const children = Object.values(vnode.attrs.components).map(c => { + const children = Object.values(vnode.attrs["components"]).map(c => { if (typeof c !== "object") return `${c}`; const attrs = Object.assign({}, vnode.attrs, c); - return m(attrs.type, attrs); + return m(attrs["type"], attrs); }); if (deviceId) { return m( @@ -25,4 +24,6 @@ export default function component() { } } }; -} +}; + +export default component; diff --git a/ui/components/overview-dot.js b/ui/components/overview-dot.ts similarity index 65% rename from ui/components/overview-dot.js rename to ui/components/overview-dot.ts index 1f54d08..4353d31 100644 --- a/ui/components/overview-dot.js +++ b/ui/components/overview-dot.ts @@ -1,18 +1,17 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "../components"; import config from "../config"; import * as store from "../store"; const CHARTS = config.ui.overview.charts; -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const device = vnode.attrs.device; - const chart = CHARTS[vnode.attrs.chart]; + const device = vnode.attrs["device"]; + const chart = CHARTS[vnode.attrs["chart"]]; for (const slice of Object.values(chart.slices)) { - const filter = slice.filter; + const filter = slice["filter"]; if (store.evaluateExpression(filter, device)) { const dot = m( "svg", @@ -26,13 +25,15 @@ export default function component() { cx: "0.5em", cy: "0.5em", r: "0.4em", - fill: slice.color + fill: slice["color"] }) ); - return m("span.overview-dot", dot, `${slice.label}`); + return m("span.overview-dot", dot, `${slice["label"]}`); } } return null; } }; -} +}; + +export default component; diff --git a/ui/components/parameter-list.js b/ui/components/parameter-list.js deleted file mode 100644 index fe21dd6..0000000 --- a/ui/components/parameter-list.js +++ /dev/null @@ -1,35 +0,0 @@ -"use strict"; - -import { m } from "../components"; - -export default function component() { - return { - view: vnode => { - const device = vnode.attrs.device; - - const rows = Object.values(vnode.attrs.parameters).map(parameter => { - const p = m.context( - { - device: device, - parameter: parameter.parameter - }, - parameter.type || "parameter", - parameter - ); - - return m( - "tr", - { - onupdate: vn => { - vn.dom.style.display = p.dom ? "" : "none"; - } - }, - m("th", parameter.label), - m("td", p) - ); - }); - - return m("table.parameter-list", rows); - } - }; -} diff --git a/ui/components/parameter-list.ts b/ui/components/parameter-list.ts new file mode 100644 index 0000000..72eb002 --- /dev/null +++ b/ui/components/parameter-list.ts @@ -0,0 +1,38 @@ +import { ClosureComponent, Component, VnodeDOM } from "mithril"; +import { m } from "../components"; + +const component: ClosureComponent = (): Component => { + return { + view: vnode => { + const device = vnode.attrs["device"]; + + const rows = Object.values(vnode.attrs["parameters"]).map(parameter => { + const p = m.context( + { + device: device, + parameter: parameter["parameter"] + }, + parameter["type"] || "parameter", + parameter + ); + + return m( + "tr", + { + onupdate: vn => { + (vn.dom as HTMLElement).style.display = (p as VnodeDOM).dom + ? "" + : "none"; + } + }, + m("th", parameter["label"]), + m("td", p) + ); + }); + + return m("table.parameter-list", rows); + } + }; +}; + +export default component; diff --git a/ui/components/parameter-table.js b/ui/components/parameter-table.ts similarity index 81% rename from ui/components/parameter-table.js rename to ui/components/parameter-table.ts index 741fb5f..41e6332 100644 --- a/ui/components/parameter-table.js +++ b/ui/components/parameter-table.ts @@ -1,23 +1,22 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "../components"; import * as taskQueue from "../task-queue"; import * as store from "../store"; import * as expressionParser from "../../lib/common/expression-parser"; -export default function component() { +const component: ClosureComponent = (): Component => { return { oninit: vnode => { - const obj = vnode.attrs.parameter; - if (!Array.isArray(obj) || !obj[0] === "PARAM") + const obj = vnode.attrs["parameter"]; + if (!Array.isArray(obj) || obj[0] !== "PARAM") throw new Error("Object must be a parameter path"); - vnode.state.object = obj[1]; - vnode.state.parameters = Object.values(vnode.attrs.childParameters); + vnode.state["object"] = obj[1]; + vnode.state["parameters"] = Object.values(vnode.attrs["childParameters"]); }, view: vnode => { - const device = vnode.attrs.device; - const object = store.evaluateExpression(vnode.state.object, device); - const parameters = vnode.state.parameters; + const device = vnode.attrs["device"]; + const object = store.evaluateExpression(vnode.state["object"], device); + const parameters = vnode.state["parameters"]; if (!device[object]) return null; @@ -31,13 +30,14 @@ export default function component() { } } - const headers = Object.values(parameters).map(p => m("th", p.label)); + const headers = Object.values(parameters).map(p => m("th", p["label"])); const thead = m("thead", m("tr", headers)); const rows = []; for (const i of instances) { - let filter = vnode.attrs.filter != null ? vnode.attrs.filter : true; + let filter = + vnode.attrs["filter"] != null ? vnode.attrs["filter"] : true; filter = expressionParser.map(filter, e => { if (Array.isArray(e) && e[0] === "PARAM") @@ -126,9 +126,11 @@ export default function component() { } let label; - if (vnode.attrs.label) label = m("h2", vnode.attrs.label); + if (vnode.attrs["label"]) label = m("h2", vnode.attrs["label"]); return [label, m("table.table", thead, m("tbody", rows))]; } }; -} +}; + +export default component; diff --git a/ui/components/parameter.js b/ui/components/parameter.ts similarity index 88% rename from ui/components/parameter.js rename to ui/components/parameter.ts index c4cb1e2..eb25121 100644 --- a/ui/components/parameter.js +++ b/ui/components/parameter.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { ClosureComponent, Component, VnodeDOM } from "mithril"; import { m } from "../components"; import * as taskQueue from "../task-queue"; import * as store from "../store"; @@ -31,14 +30,14 @@ const evaluateParam = memoize((exp, obj, now) => { return { value, timestamp, parameter }; }); -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const device = vnode.attrs.device; + const device = vnode.attrs["device"]; const { value, timestamp, parameter } = evaluateParam( - vnode.attrs.parameter, - vnode.attrs.device, + vnode.attrs["parameter"], + vnode.attrs["device"], store.getTimestamp() ); @@ -77,7 +76,7 @@ export default function component() { onmouseover: e => { e.redraw = false; // Don't update any child element - if (e.target === el.dom) { + if (e.target === (el as VnodeDOM).dom) { const now = Date.now(); const localeString = new Date(timestamp).toLocaleString(); e.target.title = `${localeString} (${timeAgo(now - timestamp)})`; @@ -89,4 +88,6 @@ export default function component() { ); } }; -} +}; + +export default component; diff --git a/ui/components/ping.js b/ui/components/ping.js deleted file mode 100644 index 1bf98ee..0000000 --- a/ui/components/ping.js +++ /dev/null @@ -1,56 +0,0 @@ -"use strict"; - -import { m } from "../components"; -import * as store from "../store"; - -const REFRESH_INTERVAL = 3000; - -export default function component() { - return { - oninit: vnode => { - vnode.state.timestamp = 0; - vnode.state.ping = null; - vnode.state.host = null; - vnode.state.timeout = null; - }, - view: vnode => { - const refresh = () => { - const device = vnode.attrs.device; - let param = - device["InternetGatewayDevice.ManagementServer.ConnectionRequestURL"]; - if (!param) - param = device["Device.ManagementServer.ConnectionRequestURL"]; - if (!param || !param.value) return; - - const url = new URL(param.value[0]); - vnode.state.host = url.hostname; - vnode.state.timestamp = Date.now(); - store - .ping(vnode.state.host) - .then(res => { - vnode.state.ping = res; - }) - .catch(() => { - // Do nothing - }); - }; - - const t = vnode.state.timestamp + REFRESH_INTERVAL - Date.now(); - clearTimeout(vnode.state.timeout); - if (t <= 0) refresh(); - else vnode.state.timeout = setTimeout(refresh, t); - - if (vnode.state.host) { - let status = ""; - if (vnode.state.ping) { - if (vnode.state.ping.avg != null) - status = `${Math.trunc(vnode.state.ping.avg)} ms`; - else status = "Unreachable"; - } - - return m("div", `Pinging ${vnode.state.host}: ${status}`); - } - return null; - } - }; -} diff --git a/ui/components/ping.ts b/ui/components/ping.ts new file mode 100644 index 0000000..3c98e13 --- /dev/null +++ b/ui/components/ping.ts @@ -0,0 +1,57 @@ +import { ClosureComponent, Component } from "mithril"; +import { m } from "../components"; +import * as store from "../store"; + +const REFRESH_INTERVAL = 3000; + +const component: ClosureComponent = (): Component => { + return { + oninit: vnode => { + vnode.state["timestamp"] = 0; + vnode.state["ping"] = null; + vnode.state["host"] = null; + vnode.state["timeout"] = null; + }, + view: vnode => { + const refresh = (): void => { + const device = vnode.attrs["device"]; + let param = + device["InternetGatewayDevice.ManagementServer.ConnectionRequestURL"]; + if (!param) + param = device["Device.ManagementServer.ConnectionRequestURL"]; + if (!param || !param.value) return; + + const url = new URL(param.value[0]); + vnode.state["host"] = url.hostname; + vnode.state["timestamp"] = Date.now(); + store + .ping(vnode.state["host"]) + .then(res => { + vnode.state["ping"] = res; + }) + .catch(() => { + // Do nothing + }); + }; + + const t = vnode.state["timestamp"] + REFRESH_INTERVAL - Date.now(); + clearTimeout(vnode.state["timeout"]); + if (t <= 0) refresh(); + else vnode.state["timeout"] = setTimeout(refresh, t); + + if (vnode.state["host"]) { + let status = ""; + if (vnode.state["ping"]) { + if (vnode.state["ping"].avg != null) + status = `${Math.trunc(vnode.state["ping"].avg)} ms`; + else status = "Unreachable"; + } + + return m("div", `Pinging ${vnode.state["host"]}: ${status}`); + } + return null; + } + }; +}; + +export default component; diff --git a/ui/components/summon-button.js b/ui/components/summon-button.ts similarity index 86% rename from ui/components/summon-button.js rename to ui/components/summon-button.ts index 10b6304..5c2b3f5 100644 --- a/ui/components/summon-button.js +++ b/ui/components/summon-button.ts @@ -1,14 +1,13 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "../components"; import * as taskQueue from "../task-queue"; import * as store from "../store"; import * as notifications from "../notifications"; -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const device = vnode.attrs.device; + const device = vnode.attrs["device"]; return m( "button.primary", @@ -16,9 +15,9 @@ export default function component() { title: "Initiate session and refresh basic parameters", onclick: e => { e.target.disabled = true; - const params = Object.values(vnode.attrs.parameters) + const params = Object.values(vnode.attrs["parameters"]) .map(exp => { - if (!Array.isArray(exp) || !exp[0] === "PARAM") return null; + if (!Array.isArray(exp) || exp[0] !== "PARAM") return null; return store.evaluateExpression(exp[1], device); }) .filter(exp => !!exp); @@ -68,4 +67,6 @@ export default function component() { ); } }; -} +}; + +export default component; diff --git a/ui/components/tags.js b/ui/components/tags.ts similarity index 90% rename from ui/components/tags.js rename to ui/components/tags.ts index 5ff72e8..39e2467 100644 --- a/ui/components/tags.js +++ b/ui/components/tags.ts @@ -1,15 +1,14 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "../components"; import * as notifications from "../notifications"; import * as store from "../store"; -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const device = vnode.attrs.device; + const device = vnode.attrs["device"]; let writable = true; - if (vnode.attrs.writable != null) writable = vnode.attrs.writable; + if (vnode.attrs["writable"] != null) writable = vnode.attrs["writable"]; const tags = []; for (const p of Object.keys(device)) @@ -87,4 +86,6 @@ export default function component() { ); } }; -} +}; + +export default component; diff --git a/ui/config-page.js b/ui/config-page.ts similarity index 84% rename from ui/config-page.js rename to ui/config-page.ts index 49e4b73..1c2e466 100644 --- a/ui/config-page.js +++ b/ui/config-page.ts @@ -1,5 +1,3 @@ -"use strict"; - import { m } from "./components"; import * as store from "./store"; import * as notifications from "./notifications"; @@ -7,13 +5,18 @@ import putFormComponent from "./put-form-component"; import * as overlay from "./overlay"; import * as expressionParser from "../lib/common/expression-parser"; import { loadCodeMirror } from "./dynamic-loader"; +import { ClosureComponent, Component, Children } from "mithril"; const attributes = [ { id: "_id", label: "Key" }, { id: "value", label: "Value" } ]; -function putActionHandler(action, _object, isNew) { +interface ValidationErrors { + [prop: string]: string; +} + +function putActionHandler(action, _object, isNew?): Promise { return new Promise((resolve, reject) => { const object = Object.assign({}, _object); if (action === "save") { @@ -78,11 +81,11 @@ const formData = { attributes: attributes }; -function escapeRegExp(str) { +function escapeRegExp(str): string { return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"); } -export function init() { +export function init(): Promise<{}> { if (!window.authorizer.hasAccess("config", 2)) { return Promise.reject( new Error("You are not authorized to view this page") @@ -97,7 +100,7 @@ export function init() { }); } -function renderTable(confsResponse, searchString) { +function renderTable(confsResponse, searchString): Children { const confs = confsResponse.value.sort((a, b) => { return a._id < b._id ? -1 : 1; }); @@ -113,14 +116,14 @@ function renderTable(confsResponse, searchString) { for (const conf of confs) { const attrs = {}; if (regex && !regex.test(conf._id) && !regex.test(conf.value)) - attrs.style = "display: none;"; + attrs["style"] = "display: none;"; const edit = m( "button", { title: "Edit config value", onclick: () => { - const cb = () => { + const cb = (): Children => { return m( putFormComponent, Object.assign( @@ -130,9 +133,9 @@ function renderTable(confsResponse, searchString) { return new Promise(resolve => { putActionHandler(action, object, false) .then(errors => { - errors = errors ? Object.values(errors) : []; - if (errors.length) { - for (const err of errors) + const ErrorList = errors ? Object.values(errors) : []; + if (ErrorList.length) { + for (const err of ErrorList) notifications.push("error", err); } else { overlay.close(cb); @@ -190,7 +193,7 @@ function renderTable(confsResponse, searchString) { return m("table", m("tbody", rows)); } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { document.title = "Config - GenieACS"; @@ -199,10 +202,10 @@ export function component() { type: "text", placeholder: "Search config", oninput: e => { - vnode.state.searchString = e.target.value; + vnode.state["searchString"] = e.target.value; e.redraw = false; - clearTimeout(vnode.state.timeout); - vnode.state.timeout = setTimeout(m.redraw, 250); + clearTimeout(vnode.state["timeout"]); + vnode.state["timeout"] = setTimeout(m.redraw, 250); } }); @@ -213,7 +216,7 @@ export function component() { { title: "Create new config", onclick: () => { - const cb = () => { + const cb = (): Children => { return m( putFormComponent, Object.assign( @@ -222,9 +225,11 @@ export function component() { return new Promise(resolve => { putActionHandler(action, object, true) .then(errors => { - errors = errors ? Object.values(errors) : []; - if (errors.length) { - for (const err of errors) + const errorList = errors + ? Object.values(errors) + : []; + if (errorList.length) { + for (const err of errorList) notifications.push("error", err); } else { overlay.close(cb); @@ -259,11 +264,11 @@ export function component() { m( ".parameter-list", { style: "height: 400px" }, - renderTable(confs, vnode.state.searchString) + renderTable(confs, vnode.state["searchString"]) ), m(".actions-bar", newConfig) ) ]; } }; -} +}; diff --git a/ui/config.js b/ui/config.ts similarity index 70% rename from ui/config.js rename to ui/config.ts index 8a1dfcf..7d4591f 100644 --- a/ui/config.js +++ b/ui/config.ts @@ -1,3 +1 @@ -"use strict"; - export default window.clientConfig; diff --git a/ui/device-page.js b/ui/device-page.ts similarity index 62% rename from ui/device-page.js rename to ui/device-page.ts index 63b2ffd..5ebf571 100644 --- a/ui/device-page.js +++ b/ui/device-page.ts @@ -1,10 +1,9 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "./components"; import config from "./config"; import * as store from "./store"; -export function init(args) { +export function init(args): Promise<{}> { if (!window.authorizer.hasAccess("devices", 2)) { return Promise.reject( new Error("You are not authorized to view this page") @@ -17,12 +16,12 @@ export function init(args) { }); } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { - document.title = `${vnode.attrs.deviceId} - Devices - GenieACS`; + document.title = `${vnode.attrs["deviceId"]} - Devices - GenieACS`; - const dev = store.fetch("devices", vnode.attrs.deviceFilter).value; + const dev = store.fetch("devices", vnode.attrs["deviceFilter"]).value; if (!dev.length) return "Loading"; const conf = config.ui.device; const cmps = []; @@ -30,7 +29,7 @@ export function component() { for (const c of Object.values(conf)) cmps.push(m.context({ device: dev[0] }, c["type"], c)); - return [m("h1", vnode.attrs.deviceId), cmps]; + return [m("h1", vnode.attrs["deviceId"]), cmps]; } }; -} +}; diff --git a/ui/devices-page.js b/ui/devices-page.ts similarity index 88% rename from ui/devices-page.js rename to ui/devices-page.ts index 14743c9..d4315f1 100644 --- a/ui/devices-page.js +++ b/ui/devices-page.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { ClosureComponent, Component, Children } from "mithril"; import { m } from "./components"; import config from "./config"; import filterComponent from "./filter-component"; @@ -42,7 +41,7 @@ const unpackSmartQuery = memoize(query => { }); }); -export function init(args) { +export function init(args): Promise<{}> { return new Promise((resolve, reject) => { if (!window.authorizer.hasAccess("devices", 2)) return void reject(new Error("You are not authorized to view this page")); @@ -63,7 +62,7 @@ function renderTable( downloadUrl, sort, onSortChange -) { +): Children { const devices = devicesResponse.value; const selectAll = m("input", { type: "checkbox", @@ -195,7 +194,7 @@ function renderTable( ]); } -function renderActions(selected) { +function renderActions(selected): Children { const buttons = []; buttons.push( @@ -336,65 +335,68 @@ function renderActions(selected) { return m(".actions-bar", buttons); } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { document.title = "Devices - GenieACS"; - function showMore() { - vnode.state.showCount = - (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE; + function showMore(): void { + vnode.state["showCount"] = + (vnode.state["showCount"] || PAGE_SIZE) + PAGE_SIZE; m.redraw(); } - function onFilterChanged(filter) { + function onFilterChanged(filter): void { const ops = { filter }; - if (vnode.attrs.sort) ops.sort = vnode.attrs.sort; + if (vnode.attrs["sort"]) ops["sort"] = vnode.attrs["sort"]; m.route.set("/devices", ops); } - function onSortChange(sort) { + function onSortChange(sort): void { const ops = { sort }; - if (vnode.attrs.filter) ops.filter = vnode.attrs.filter; + if (vnode.attrs["filter"]) ops["filter"] = vnode.attrs["filter"]; m.route.set("/devices", ops); } - const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {}; - let filter = vnode.attrs.filter - ? memoizedParse(vnode.attrs.filter) + const sort = vnode.attrs["sort"] + ? memoizedJsonParse(vnode.attrs["sort"]) + : {}; + let filter = vnode.attrs["filter"] + ? memoizedParse(vnode.attrs["filter"]) : true; filter = unpackSmartQuery(filter); const devs = store.fetch("devices", filter, { - limit: vnode.state.showCount || PAGE_SIZE, + limit: vnode.state["showCount"] || PAGE_SIZE, sort: sort }); const count = store.count("devices", filter); const selected = new Set(); - if (vnode.state.selected) { + if (vnode.state["selected"]) { for (const d of devs.value) { - if (vnode.state.selected.has(d["DeviceID.ID"].value[0])) + if (vnode.state["selected"].has(d["DeviceID.ID"].value[0])) selected.add(d["DeviceID.ID"].value[0]); } } - vnode.state.selected = selected; + vnode.state["selected"] = selected; const downloadUrl = getDownloadUrl( - vnode.attrs.filter, - vnode.attrs.indexParameters + vnode.attrs["filter"], + vnode.attrs["indexParameters"] ); + const attrs = {}; + attrs["resource"] = "devices"; + attrs["filter"] = vnode.attrs["filter"]; + attrs["onChange"] = onFilterChanged; + return [ m("h1", "Listing devices"), - m(filterComponent, { - resource: "devices", - filter: vnode.attrs.filter, - onChange: onFilterChanged - }), + m(filterComponent, attrs), renderTable( devs, - vnode.attrs.indexParameters, + vnode.attrs["indexParameters"], count.value, selected, showMore, @@ -406,4 +408,4 @@ export function component() { ]; } }; -} +}; diff --git a/ui/drawer-component.js b/ui/drawer-component.ts similarity index 83% rename from ui/drawer-component.js rename to ui/drawer-component.ts index 661516e..3ab3889 100644 --- a/ui/drawer-component.js +++ b/ui/drawer-component.ts @@ -1,21 +1,24 @@ -"use strict"; - -import m from "mithril"; - +import m, { + Children, + Child, + ClosureComponent, + Component, + VnodeDOM +} from "mithril"; import * as taskQueue from "./task-queue"; import * as store from "./store"; import * as notifications from "./notifications"; -function mparam(param) { +function mparam(param): Children { return m("span.parameter", { title: param }, `${param}`); } -function mval(val) { +function mval(val): Children { return m("span.value", { title: val }, `${val}`); } -function renderStagingSpv(task, queueFunc, cancelFunc) { - function keydown(e) { +function renderStagingSpv(task, queueFunc, cancelFunc): Children { + function keydown(e): void { if (e.keyCode === 13) queueFunc(); else if (e.keyCode === 27) cancelFunc(); else e.redraw = false; @@ -33,7 +36,7 @@ function renderStagingSpv(task, queueFunc, cancelFunc) { }, onkeydown: keydown, oncreate: vnode => { - vnode.dom.focus(); + (vnode.dom as HTMLSelectElement).focus(); } }, [ @@ -55,11 +58,11 @@ function renderStagingSpv(task, queueFunc, cancelFunc) { }, onkeydown: keydown, oncreate: vnode => { - vnode.dom.focus(); - vnode.dom.select(); + (vnode.dom as HTMLInputElement).focus(); + (vnode.dom as HTMLInputElement).select(); // Need to prevent scrolling on focus because // we're animating height and using overflow: hidden - vnode.dom.parentNode.parentNode.scrollTop = 0; + (vnode.dom.parentNode.parentNode as Element).scrollTop = 0; } }); } @@ -67,7 +70,7 @@ function renderStagingSpv(task, queueFunc, cancelFunc) { return [m("span", "Editing ", mparam(task.parameterValues[0][0])), input]; } -function renderStagingDownload(task) { +function renderStagingDownload(task): Children { task.invalid = !task.fileName || !task.fileType; const files = store.fetch("files", true); const idParts = task.device.split("-"); @@ -138,22 +141,22 @@ function renderStagingDownload(task) { ]; } -function renderStaging(staging) { - const elements = []; +function renderStaging(staging): Child[] { + const elements: Child[] = []; + for (const s of staging) { - const queueFunc = () => { + const queueFunc = (): void => { staging.delete(s); taskQueue.queueTask(s); }; - const cancelFunc = () => { + const cancelFunc = (): void => { staging.delete(s); }; let elms; if (s.name === "setParameterValues") elms = renderStagingSpv(s, queueFunc, cancelFunc); - else if (s.name === "download") - elms = renderStagingDownload(s, queueFunc, cancelFunc); + else if (s.name === "download") elms = renderStagingDownload(s); const queue = m( "button.primary", @@ -171,9 +174,9 @@ function renderStaging(staging) { return elements; } -function renderQueue(queue) { - const details = []; - const devices = {}; +function renderQueue(queue): Child[] { + const details: Child[] = []; + const devices: { [deviceId: string]: any[] } = {}; for (const t of queue) { devices[t.device] = devices[t.device] || []; devices[t.device].push(t); @@ -282,8 +285,8 @@ function renderQueue(queue) { return details; } -function renderNotifications(notifs) { - const notificationElements = []; +function renderNotifications(notifs): Child[] { + const notificationElements: Child[] = []; for (const n of notifs) { notificationElements.push( @@ -293,10 +296,10 @@ function renderNotifications(notifs) { class: n.type, style: "position: absolute;opacity: 0", oncreate: vnode => { - vnode.dom.style.opacity = 1; + (vnode.dom as HTMLDivElement).style.opacity = "1"; }, onbeforeremove: vnode => { - vnode.dom.style.opacity = 0; + (vnode.dom as HTMLDivElement).style.opacity = "0"; return new Promise(resolve => { setTimeout(() => { resolve(); @@ -312,7 +315,7 @@ function renderNotifications(notifs) { return notificationElements; } -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { const queue = taskQueue.getQueue(); @@ -324,21 +327,26 @@ export default function component() { const stagingElements = renderStaging(staging); const queueElements = renderQueue(queue); - function repositionNotifications() { + function repositionNotifications(): void { let top = 10; - for (const c of notificationElements) { - c.dom.style.top = top; - top += c.dom.offsetHeight + 10; + for (const c of notificationElements as VnodeDOM[]) { + (c.dom as HTMLDivElement).style.top = `${top}`; + top += (c.dom as HTMLDivElement).offsetHeight + 10; } } - function resizeDrawer() { + function resizeDrawer(): void { let height = statusElement.dom.offsetTop + statusElement.dom.offsetHeight; if (stagingElements.length) { - for (const s of stagingElements) - height = Math.max(height, s.dom.offsetTop + s.dom.offsetHeight); - } else if (vnode.state.mouseIn) { + for (const s of stagingElements as VnodeDOM[]) { + height = Math.max( + height, + (s.dom as HTMLDivElement).offsetTop + + (s.dom as HTMLDivElement).offsetHeight + ); + } + } else if (vnode.state["mouseIn"]) { for (const c of drawerElement.children) height = Math.max(height, c.dom.offsetTop + c.dom.offsetHeight); } @@ -347,7 +355,7 @@ export default function component() { if (stagingElements.length + queueElements.length) { const statusCount = { queued: 0, pending: 0, fault: 0, stale: 0 }; - for (const t of queue) statusCount[t.status] += 1; + for (const t of queue) statusCount[t["status"]] += 1; const actions = m( ".actions", @@ -358,7 +366,7 @@ export default function component() { disabled: !statusCount.queued, onclick: () => { const tasks = Array.from(taskQueue.getQueue()).filter( - t => t.status === "queued" + t => t["status"] === "queued" ); taskQueue .commit( @@ -451,25 +459,26 @@ export default function component() { key: "drawer", style: "opacity: 0;height: 0;", oncreate: vnode2 => { - vnode.state.mouseIn = false; - vnode2.dom.style.opacity = 1; + vnode.state["mouseIn"] = false; + (vnode2.dom as HTMLDivElement).style.opacity = "1"; resizeDrawer(); }, onmouseover: e => { - vnode.state.mouseIn = true; + vnode.state["mouseIn"] = true; resizeDrawer(); e.redraw = false; }, onmouseleave: e => { - vnode.state.mouseIn = false; + vnode.state["mouseIn"] = false; resizeDrawer(); e.redraw = false; }, onupdate: resizeDrawer, onbeforeremove: vnode2 => { - vnode2.dom.onmouseover = vnode2.dom.onmouseleave = null; - vnode2.dom.style.opacity = 0; - vnode2.dom.style.height = 0; + (vnode2.dom as HTMLDivElement).onmouseover = null; + (vnode2.dom as HTMLDivElement).onmouseleave = null; + (vnode2.dom as HTMLDivElement).style.opacity = "0"; + (vnode2.dom as HTMLDivElement).style.height = "0"; return new Promise(resolve => { setTimeout(resolve, 500); }); @@ -496,4 +505,6 @@ export default function component() { ); } }; -} +}; + +export default component; diff --git a/ui/dynamic-loader.js b/ui/dynamic-loader.ts similarity index 81% rename from ui/dynamic-loader.js rename to ui/dynamic-loader.ts index baf7fed..5fb0db3 100644 --- a/ui/dynamic-loader.js +++ b/ui/dynamic-loader.ts @@ -1,9 +1,7 @@ -"use strict"; +export let codeMirror; +export let yaml; -let codeMirror; -let yaml; - -function loadCodeMirror() { +export function loadCodeMirror(): Promise { if (codeMirror) return Promise.resolve(); return new Promise((resolve, reject) => { @@ -20,7 +18,7 @@ function loadCodeMirror() { }); } -function loadYaml() { +export function loadYaml(): Promise { if (yaml) return Promise.resolve(); return new Promise((resolve, reject) => { @@ -32,5 +30,3 @@ function loadYaml() { .catch(reject); }); } - -export { loadCodeMirror, codeMirror, loadYaml, yaml }; diff --git a/ui/error-page.js b/ui/error-page.js deleted file mode 100644 index 63ee67b..0000000 --- a/ui/error-page.js +++ /dev/null @@ -1,12 +0,0 @@ -"use strict"; - -import { m } from "./components"; - -export function component() { - return { - view: function(vnode) { - document.title = "Error! - GenieACS"; - return m("p.error", vnode.attrs.error); - } - }; -} diff --git a/ui/error-page.ts b/ui/error-page.ts new file mode 100644 index 0000000..0475378 --- /dev/null +++ b/ui/error-page.ts @@ -0,0 +1,11 @@ +import { ClosureComponent, Component } from "mithril"; +import { m } from "./components"; + +export const component: ClosureComponent = (): Component => { + return { + view: function(vnode) { + document.title = "Error! - GenieACS"; + return m("p.error", vnode.attrs["error"]); + } + }; +}; diff --git a/ui/faults-page.js b/ui/faults-page.ts similarity index 84% rename from ui/faults-page.js rename to ui/faults-page.ts index ad0d047..c221d5b 100644 --- a/ui/faults-page.js +++ b/ui/faults-page.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { ClosureComponent, Component, Children } from "mithril"; import { m } from "./components"; import config from "./config"; import filterComponent from "./filter-component"; @@ -46,7 +45,7 @@ const unpackSmartQuery = memoize(query => { }); }); -export function init(args) { +export function init(args): Promise<{}> { if (!window.authorizer.hasAccess("faults", 2)) { return Promise.reject( new Error("You are not authorized to view this page") @@ -72,7 +71,7 @@ function renderTable( downloadUrl, sort, onSortChange -) { +): Children { const faults = faultsResponse.value; const selectAll = m("input", { type: "checkbox", @@ -229,57 +228,60 @@ function renderTable( ]; } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { document.title = "Faults - GenieACS"; - function showMore() { - vnode.state.showCount = - (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE; + function showMore(): void { + vnode.state["showCount"] = + (vnode.state["showCount"] || PAGE_SIZE) + PAGE_SIZE; m.redraw(); } - function onFilterChanged(filter) { + function onFilterChanged(filter): void { const ops = { filter }; - if (vnode.attrs.sort) ops.sort = vnode.attrs.sort; + if (vnode.attrs["sort"]) ops["sort"] = vnode.attrs["sort"]; m.route.set("/faults", ops); } - function onSortChange(sort) { + function onSortChange(sort): void { const ops = { sort }; - if (vnode.attrs.filter) ops.filter = vnode.attrs.filter; + if (vnode.attrs["filter"]) ops["filter"] = vnode.attrs["filter"]; m.route.set("/faults", ops); } - const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {}; - let filter = vnode.attrs.filter - ? memoizedParse(vnode.attrs.filter) + const sort = vnode.attrs["sort"] + ? memoizedJsonParse(vnode.attrs["sort"]) + : {}; + let filter = vnode.attrs["filter"] + ? memoizedParse(vnode.attrs["filter"]) : true; filter = unpackSmartQuery(filter); const faults = store.fetch("faults", filter, { - limit: vnode.state.showCount || PAGE_SIZE, + limit: vnode.state["showCount"] || PAGE_SIZE, sort: sort }); const count = store.count("faults", filter); const selected = new Set(); - if (vnode.state.selected) { + if (vnode.state["selected"]) { for (const f of faults.value) - if (vnode.state.selected.has(f["_id"])) selected.add(f["_id"]); + if (vnode.state["selected"].has(f["_id"])) selected.add(f["_id"]); } - vnode.state.selected = selected; + vnode.state["selected"] = selected; - const downloadUrl = getDownloadUrl(vnode.attrs.filter); + const downloadUrl = getDownloadUrl(vnode.attrs["filter"]); + + const attrs = {}; + attrs["resource"] = "faults"; + attrs["filter"] = vnode.attrs["filter"]; + attrs["onChange"] = onFilterChanged; return [ m("h1", "Listing faults"), - m(filterComponent, { - resource: "faults", - filter: vnode.attrs.filter, - onChange: onFilterChanged - }), + m(filterComponent, attrs), renderTable( faults, count.value, @@ -292,4 +294,4 @@ export function component() { ]; } }; -} +}; diff --git a/ui/files-page.js b/ui/files-page.ts similarity index 82% rename from ui/files-page.js rename to ui/files-page.ts index ac47ab6..e0e910a 100644 --- a/ui/files-page.js +++ b/ui/files-page.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { ClosureComponent, Component, Children } from "mithril"; import { m } from "./components"; import config from "./config"; import filterComponent from "./filter-component"; @@ -16,7 +15,12 @@ const PAGE_SIZE = config.ui.pageSize || 10; const memoizedParse = memoize(parse); const memoizedJsonParse = memoize(JSON.parse); -const attributes = [ +const attributes: { + id: string; + label: string; + type?: string; + options?: any; +}[] = [ { id: "_id", label: "Name" }, { id: "metadata.fileType", @@ -50,7 +54,11 @@ const unpackSmartQuery = memoize(query => { }); }); -function putActionHandler(action, _object) { +interface ValidationErrors { + [prop: string]: string; +} + +function putActionHandler(action, _object): Promise { return new Promise((resolve, reject) => { const object = Object.assign({}, _object); if (action === "save") { @@ -109,7 +117,7 @@ const getDownloadUrl = memoize(filter => { })}`; }); -export function init(args) { +export function init(args): Promise<{}> { if (!window.authorizer.hasAccess("files", 2)) { return Promise.reject( new Error("You are not authorized to view this page") @@ -129,7 +137,7 @@ function renderTable( downloadUrl, sort, onSortChange -) { +): Children { const files = filesResponse.value; const selectAll = m("input", { type: "checkbox", @@ -270,7 +278,7 @@ function renderTable( { title: "Create new file", onclick: () => { - const cb = () => { + const cb = (): Children => { return m( putFormComponent, Object.assign( @@ -279,9 +287,11 @@ function renderTable( return new Promise(resolve => { putActionHandler(action, object) .then(errors => { - errors = errors ? Object.values(errors) : []; - if (errors.length) { - for (const err of errors) + const errorList = errors + ? Object.values(errors) + : []; + if (errorList.length) { + for (const err of errorList) notifications.push("error", err); } else { overlay.close(cb); @@ -318,58 +328,63 @@ function renderTable( ]; } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { document.title = "Files - GenieACS"; - function showMore() { - vnode.state.showCount = - (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE; + function showMore(): void { + vnode.state["showCount"] = + (vnode.state["showCount"] || PAGE_SIZE) + PAGE_SIZE; m.redraw(); } - function onFilterChanged(filter) { + function onFilterChanged(filter): void { const ops = { filter }; - if (vnode.attrs.sort) ops.sort = vnode.attrs.sort; + if (vnode.attrs["sort"]) ops["sort"] = vnode.attrs["sort"]; m.route.set(m.route.get(), ops); } - function onSortChange(sort) { + function onSortChange(sort): void { const ops = { sort }; - if (vnode.attrs.filter) ops.filter = vnode.attrs.filter; + if (vnode.attrs["filter"]) ops["filter"] = vnode.attrs["filter"]; m.route.set(m.route.get(), ops); } - const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {}; - let filter = vnode.attrs.filter - ? memoizedParse(vnode.attrs.filter) + const sort = vnode.attrs["sort"] + ? memoizedJsonParse(vnode.attrs["sort"]) + : {}; + let filter = vnode.attrs["filter"] + ? memoizedParse(vnode.attrs["filter"]) : true; filter = unpackSmartQuery(filter); const files = store.fetch("files", filter, { - limit: vnode.state.showCount || PAGE_SIZE, + limit: vnode.state["showCount"] || PAGE_SIZE, sort: sort }); const count = store.count("files", filter); const selected = new Set(); - if (vnode.state.selected) { - for (const file of files.value) - if (vnode.state.selected.has(file["_id"])) selected.add(file["_id"]); + if (vnode.state["selected"]) { + for (const file of files.value) { + if (vnode.state["selected"].has(file["_id"])) + selected.add(file["_id"]); + } } - vnode.state.selected = selected; + vnode.state["selected"] = selected; - const downloadUrl = getDownloadUrl(vnode.attrs.filter); + const downloadUrl = getDownloadUrl(vnode.attrs["filter"]); + + const attrs = {}; + attrs["resource"] = "files"; + attrs["filter"] = vnode.attrs["filter"]; + attrs["onChange"] = onFilterChanged; return [ m("h1", "Listing files"), - m(filterComponent, { - resource: "files", - filter: vnode.attrs.filter, - onChange: onFilterChanged - }), + m(filterComponent, attrs), renderTable( files, count.value, @@ -382,4 +397,4 @@ export function component() { ]; } }; -} +}; diff --git a/ui/filter-component.js b/ui/filter-component.ts similarity index 58% rename from ui/filter-component.js rename to ui/filter-component.ts index e0211fe..1ec989f 100644 --- a/ui/filter-component.js +++ b/ui/filter-component.ts @@ -1,11 +1,10 @@ -"use strict"; - -import m from "mithril"; +import m, { ClosureComponent, Component } from "mithril"; import { parse, stringify, map } from "../lib/common/expression-parser"; import memoize from "../lib/common/memoize"; import Autocomplete from "./autocomplete-compnent"; import * as smartQuery from "./smart-query"; import { filterToMongoQuery } from "../lib/ui/mongodb-functions"; +import { Expression } from "../lib/types"; const getAutocomplete = memoize(resource => { const labels = smartQuery.getLabels(resource); @@ -16,7 +15,7 @@ const getAutocomplete = memoize(resource => { return autocomplete; }); -function parseFilter(resource, f) { +function parseFilter(resource, f): Expression { let exp; if (/^[\s0-9a-zA-Z]+:/.test(f)) { const k = f.split(":", 1)[0]; @@ -38,7 +37,7 @@ function parseFilter(resource, f) { return exp; } -function stringifyFilter(f) { +function stringifyFilter(f: Expression): string { if (Array.isArray(f) && f[0] === "FUNC" && f[1] === "Q") return `${f[2]}: ${f[3]}`; return stringify(f); @@ -56,39 +55,39 @@ const splitFilter = memoize(filter => { return list; }); -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { if ( - !vnode.state.filterList || - vnode.attrs.filter !== vnode.state.filter + !vnode.state["filterList"] || + vnode.attrs["filter"] !== vnode.state["filter"] ) { - vnode.state.filterInvalid = 0; - vnode.state.filter = vnode.attrs.filter; - vnode.state.filterList = splitFilter(vnode.attrs.filter); + vnode.state["filterInvalid"] = 0; + vnode.state["filter"] = vnode.attrs["filter"]; + vnode.state["filterList"] = splitFilter(vnode.attrs["filter"]); } - function onChange() { - vnode.state.filterInvalid = 0; - vnode.state.filterList = vnode.state.filterList.filter(f => f); - let filter = vnode.state.filterList.map((f, idx) => { + function onChange(): void { + vnode.state["filterInvalid"] = 0; + vnode.state["filterList"] = vnode.state["filterList"].filter(f => f); + let filter = vnode.state["filterList"].map((f, idx) => { try { - return parseFilter(vnode.attrs.resource, f); + return parseFilter(vnode.attrs["resource"], f); } catch (err) { - vnode.state.filterInvalid |= 1 << idx; + vnode.state["filterInvalid"] |= 1 << idx; } return null; }); - vnode.state.filterList.push(""); + vnode.state["filterList"].push(""); - if (!vnode.state.filterInvalid) { - delete vnode.state.filter; + if (!vnode.state["filterInvalid"]) { + delete vnode.state["filter"]; if (filter.length === 0) { - vnode.attrs.onChange(""); + vnode.attrs["onChange"](""); } else { if (filter.length > 1) filter = ["AND"].concat(filter); else filter = filter[0]; - vnode.attrs.onChange(stringify(filter)); + vnode.attrs["onChange"](stringify(filter)); } } } @@ -96,18 +95,20 @@ export default function component() { return m( "div.filter", [m("b", "Filter")].concat( - vnode.state.filterList.map((fltr, idx) => { + vnode.state["filterList"].map((fltr, idx) => { return m("input", { type: "text", - class: `${(vnode.state.filterInvalid >> idx) & 1 ? "error" : ""}`, + class: `${ + (vnode.state["filterInvalid"] >> idx) & 1 ? "error" : "" + }`, value: fltr, onchange: e => { - vnode.state.filterList = vnode.state.filterList.slice(); - vnode.state.filterList[idx] = e.target.value.trim(); + vnode.state["filterList"] = vnode.state["filterList"].slice(); + vnode.state["filterList"][idx] = e.target.value.trim(); onChange(); }, oncreate: vn => { - getAutocomplete(vnode.attrs.resource).attach(vn.dom); + getAutocomplete(vnode.attrs["resource"]).attach(vn.dom); } }); }) @@ -115,4 +116,6 @@ export default function component() { ); } }; -} +}; + +export default component; diff --git a/ui/layout.js b/ui/layout.ts similarity index 55% rename from ui/layout.js rename to ui/layout.ts index 9162980..8b52edb 100644 --- a/ui/layout.js +++ b/ui/layout.ts @@ -1,6 +1,4 @@ -"use strict"; - -import m from "mithril"; +import m, { ClosureComponent, Component } from "mithril"; import menu from "./menu"; import drawerComponent from "./drawer-component"; import userMenu from "./user-menu"; @@ -15,29 +13,39 @@ const adminPages = [ "config" ]; -export default function layout() { +const component: ClosureComponent = (): Component => { return { view: vnode => { let sideMenu, group; - if (adminPages.includes(vnode.attrs.page)) { + + if (adminPages.includes(vnode.attrs["page"])) { group = "admin"; - sideMenu = m(adminMenu, { page: vnode.attrs.page }); + const attrs = {}; + attrs["page"] = vnode.attrs["page"]; + sideMenu = m(adminMenu, attrs); } + const attrs = {}; + attrs["page"] = group || vnode.attrs["page"]; + return [ m("#header", [ m("img.logo", { src: "logo.svg" }), m(userMenu), - m(menu, { page: group || vnode.attrs.page }), + m(menu, attrs), m(drawerComponent) ]), m( "#content-wrapper", sideMenu, - m("#content", { class: `page-${vnode.attrs.page}` }, [vnode.children]) + m("#content", { class: `page-${vnode.attrs["page"]}` }, [ + vnode.children + ]) ), overlay.render() ]; } }; -} +}; + +export default component; diff --git a/ui/login-page.js b/ui/login-page.ts similarity index 69% rename from ui/login-page.js rename to ui/login-page.ts index 9306ca3..e0c7201 100644 --- a/ui/login-page.js +++ b/ui/login-page.ts @@ -1,17 +1,16 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "./components"; import * as store from "./store"; import * as notifications from "./notifications"; -export function init(args) { +export function init(args): Promise<{}> { return Promise.resolve(args); } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { - if (window.username) m.route.set(vnode.attrs.continue || "/"); + if (window.username) m.route.set(vnode.attrs["continue"] || "/"); document.title = "Login - GenieACS"; return [ @@ -24,11 +23,11 @@ export function component() { m("input", { name: "username", type: "text", - value: vnode.state.username, + value: vnode.state["username"], oncreate: vnode2 => { - vnode2.dom.focus(); + (vnode2.dom as HTMLInputElement).focus(); }, - oninput: m.withAttr("value", v => (vnode.state.username = v)) + oninput: m.withAttr("value", v => (vnode.state["username"] = v)) }) ), m( @@ -37,8 +36,8 @@ export function component() { m("input", { name: "password", type: "password", - value: vnode.state.password, - oninput: m.withAttr("value", v => (vnode.state.password = v)) + value: vnode.state["password"], + oninput: m.withAttr("value", v => (vnode.state["password"] = v)) }) ), m( @@ -50,7 +49,7 @@ export function component() { onclick: e => { e.target.disabled = true; store - .logIn(vnode.state.username, vnode.state.password) + .logIn(vnode.state["username"], vnode.state["password"]) .then(() => { location.reload(); }) @@ -68,4 +67,4 @@ export function component() { ]; } }; -} +}; diff --git a/ui/long-text-component.js b/ui/long-text-component.ts similarity index 65% rename from ui/long-text-component.js rename to ui/long-text-component.ts index 451ad33..8d6f0b3 100644 --- a/ui/long-text-component.js +++ b/ui/long-text-component.ts @@ -1,15 +1,13 @@ -"use strict"; - -import m from "mithril"; +import m, { ClosureComponent, Component } from "mithril"; import * as overlay from "./overlay"; -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const text = vnode.attrs.text; - const element = vnode.attrs.element || "span"; + const text = vnode.attrs["text"]; + const element = vnode.attrs["element"] || "span"; - function overflowed(_vnode) { + function overflowed(_vnode): void { if (_vnode.dom.classList.contains("long-text-overflowed")) return; _vnode.dom.classList.add("long-text-overflowed"); _vnode.dom.onclick = e => { @@ -20,8 +18,8 @@ export default function component() { rows: 24, readonly: "", oncreate: vnode2 => { - vnode2.dom.focus(); - vnode2.dom.select(); + (vnode2.dom as HTMLTextAreaElement).focus(); + (vnode2.dom as HTMLTextAreaElement).select(); } }); }); @@ -40,8 +38,10 @@ export default function component() { }, onupdate: vnode2 => { if (vnode2.dom.clientWidth === vnode2.dom.scrollWidth) { - vnode2.dom.classList.remove("long-text-overflowed"); - vnode2.dom.onclick = null; + (vnode2.dom as HTMLElement).classList.remove( + "long-text-overflowed" + ); + (vnode2.dom as HTMLElement).onclick = null; } else { overflowed(vnode2); } @@ -53,4 +53,6 @@ export default function component() { ); } }; -} +}; + +export default component; diff --git a/ui/menu.js b/ui/menu.ts similarity index 86% rename from ui/menu.js rename to ui/menu.ts index 2963477..a5a94b0 100644 --- a/ui/menu.js +++ b/ui/menu.ts @@ -1,11 +1,9 @@ -"use strict"; +import m, { ClosureComponent, Component } from "mithril"; -import m from "mithril"; - -export default function menu() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const active = { [vnode.attrs.page]: "active" }; + const active = { [vnode.attrs["page"]]: "active" }; const tabs = []; if (window.authorizer.hasAccess("devices", 1)) { @@ -60,4 +58,6 @@ export default function menu() { return m("nav", m("ul", tabs)); } }; -} +}; + +export default component; diff --git a/ui/notifications.js b/ui/notifications.ts similarity index 51% rename from ui/notifications.js rename to ui/notifications.ts index d05e7f1..06dc2d5 100644 --- a/ui/notifications.js +++ b/ui/notifications.ts @@ -1,10 +1,14 @@ -"use strict"; - import m from "mithril"; -const notifications = new Set(); +interface Notification { + type: string; + message: string; + timestamp: number; +} -export function push(type, message) { +const notifications = new Set(); + +export function push(type, message): void { const n = { type: type, message: message, timestamp: Date.now() }; notifications.add(n); m.redraw(); @@ -14,6 +18,6 @@ export function push(type, message) { }, 4000); } -export function getNotifications() { +export function getNotifications(): Set { return notifications; } diff --git a/ui/overlay.js b/ui/overlay.ts similarity index 68% rename from ui/overlay.js rename to ui/overlay.ts index 59f0331..eab65ba 100644 --- a/ui/overlay.js +++ b/ui/overlay.ts @@ -1,14 +1,14 @@ -"use strict"; +import m, { Children } from "mithril"; -import m from "mithril"; +type OverlayCallback = () => Children; -let overlayCallback = null; +let overlayCallback: OverlayCallback = null; -function open(callback) { +export function open(callback: OverlayCallback): void { overlayCallback = callback; } -function close(callback) { +export function close(callback: OverlayCallback): boolean { if (callback === overlayCallback) { overlayCallback = null; return true; @@ -17,7 +17,7 @@ function close(callback) { return false; } -function render() { +export function render(): Children { if (overlayCallback) { return m( ".overlay-wrapper", @@ -28,11 +28,11 @@ function render() { }, style: "opacity: 0", oncreate: vnode => { - vnode.dom.focus(); - vnode.dom.style.opacity = 1; + (vnode.dom as HTMLDivElement).focus(); + (vnode.dom as HTMLDivElement).style.opacity = "1"; }, onbeforeremove: vnode => { - vnode.dom.style.opacity = 0; + (vnode.dom as HTMLDivElement).style.opacity = "0"; return new Promise(resolve => { setTimeout(() => { resolve(); @@ -62,5 +62,3 @@ document.addEventListener("keydown", e => { window.addEventListener("popstate", () => { if (close(overlayCallback)) m.redraw(); }); - -export { open, close, render }; diff --git a/ui/overview-page.js b/ui/overview-page.ts similarity index 57% rename from ui/overview-page.js rename to ui/overview-page.ts index b8fddb2..7cfa6fb 100644 --- a/ui/overview-page.js +++ b/ui/overview-page.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { ClosureComponent, Component } from "mithril"; import { m } from "./components"; import config from "./config"; import * as store from "./store"; @@ -8,25 +7,25 @@ import pieChartComponent from "./pie-chart-component"; const GROUPS = config.ui.overview.groups; const CHARTS = {}; for (const group of Object.values(GROUPS)) { - for (const chartName of Object.values(group["charts"])) + for (const chartName of Object.values(group["charts"]) as string[]) CHARTS[chartName] = config.ui.overview.charts[chartName]; } -function queryCharts(charts) { +function queryCharts(charts): {} { charts = Object.assign({}, charts); for (let [chartName, chart] of Object.entries(charts)) { charts[chartName] = chart = Object.assign({}, chart); - chart.slices = Object.assign({}, chart.slices); - for (let [sliceName, slice] of Object.entries(chart.slices)) { - const filter = slice.filter; - chart.slices[sliceName] = slice = Object.assign({}, slice); - slice.count = store.count("devices", filter); + chart["slices"] = Object.assign({}, chart["slices"]); + for (let [sliceName, slice] of Object.entries(chart["slices"])) { + const filter = slice["filter"]; + chart["slices"][sliceName] = slice = Object.assign({}, slice); + slice["count"] = store.count("devices", filter); } } return charts; } -export function init() { +export function init(): Promise<{}> { if (!window.authorizer.hasAccess("devices", 1)) { return Promise.reject( new Error("You are not authorized to view this page") @@ -36,21 +35,23 @@ export function init() { return Promise.resolve({ charts: queryCharts(CHARTS) }); } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { document.title = "Overview - GenieACS"; const children = []; for (const group of Object.values(GROUPS)) { - if (group.label) children.push(m("h1", group.label)); + if (group["label"]) children.push(m("h1", group["label"])); const groupChildren = []; - for (const chartName of Object.values(group.charts)) { - const chart = vnode.attrs.charts[chartName]; + for (const chartName of Object.values(group["charts"]) as string[]) { + const chart = vnode.attrs["charts"][chartName]; const chartChildren = []; if (chart.label) chartChildren.push(m("h2", chart.label)); - chartChildren.push(m(pieChartComponent, { chart: chart })); + const attrs = {}; + attrs["chart"] = chart; + chartChildren.push(m(pieChartComponent, attrs)); groupChildren.push(m(".overview-chart", chartChildren)); } @@ -61,4 +62,4 @@ export function component() { return children; } }; -} +}; diff --git a/ui/pie-chart-component.js b/ui/pie-chart-component.ts similarity index 79% rename from ui/pie-chart-component.js rename to ui/pie-chart-component.ts index 1b99065..7fc91a9 100644 --- a/ui/pie-chart-component.js +++ b/ui/pie-chart-component.ts @@ -1,15 +1,14 @@ -"use strict"; - +import { ClosureComponent, Component, Children } from "mithril"; import { m } from "./components"; import { stringify } from "../lib/common/expression-parser"; import memoize from "../lib/common/memoize"; const memoizedStringify = memoize(stringify); -const drawChart = function(chartData) { +function drawChart(chartData): Children { const slices = chartData.slices; - const total = Array.from(Object.values(chartData.slices)).reduce( - (a, s) => a + (s.count.value || 0), + const total: number = Array.from(Object.values(chartData.slices)).reduce( + (a: number, s) => a + (s["count"]["value"] || 0), 0 ); const legend = []; @@ -21,21 +20,21 @@ const drawChart = function(chartData) { let endX, endY; for (const slice of Object.values(slices)) { - const percent = total > 0 ? (slice.count.value || 0) / total : 0; + const percent = total > 0 ? (slice["count"]["value"] || 0) / total : 0; legend.push( m(".legend-line", [ m("span.color", { - style: `background-color: ${slice.color} !important;` + style: `background-color: ${slice["color"]} !important;` }), - `${slice.label}: `, + `${slice["label"]}: `, m( "a", { href: `/#!/devices/?${m.buildQueryString({ - filter: memoizedStringify(slice.filter) + filter: memoizedStringify(slice["filter"]) })}` }, - slice.count.value || 0 + slice["count"]["value"] || 0 ), ` (${(percent * 100).toFixed(2)}%)` ]) @@ -58,7 +57,7 @@ const drawChart = function(chartData) { paths.push( m("path", { d: sketch, - fill: slice.color + fill: slice["color"] }) ); @@ -72,7 +71,7 @@ const drawChart = function(chartData) { "a", { "xlink:href": `/#!/devices/?${m.buildQueryString({ - filter: memoizedStringify(slice.filter) + filter: memoizedStringify(slice["filter"]) })}` }, [ @@ -113,12 +112,14 @@ const drawChart = function(chartData) { ), m(".legend", legend) ]); -}; +} -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - return drawChart(vnode.attrs.chart); + return drawChart(vnode.attrs["chart"]); } }; -} +}; + +export default component; diff --git a/ui/presets-page.js b/ui/presets-page.ts similarity index 84% rename from ui/presets-page.js rename to ui/presets-page.ts index f2c8581..6842050 100644 --- a/ui/presets-page.js +++ b/ui/presets-page.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { ClosureComponent, Component, Children } from "mithril"; import { m } from "./components"; import config from "./config"; import filterComponent from "./filter-component"; @@ -35,7 +34,11 @@ const unpackSmartQuery = memoize(query => { }); }); -function putActionHandler(action, _object, isNew) { +interface ValidationErrors { + [prop: string]: string; +} + +function putActionHandler(action, _object, isNew): Promise { return new Promise((resolve, reject) => { const object = Object.assign({}, _object); if (action === "save") { @@ -45,7 +48,7 @@ function putActionHandler(action, _object, isNew) { const errors = {}; if (!id) errors["_id"] = "ID can not be empty"; - if (!object.provision) errors.provision = "Provision not selected"; + if (!object.provision) errors["provision"] = "Provision not selected"; if (Object.keys(errors).length) return void resolve(errors); @@ -107,7 +110,7 @@ const getDownloadUrl = memoize(filter => { })}`; }); -export function init(args) { +export function init(args): Promise<{}> { if (!window.authorizer.hasAccess("presets", 2)) { return Promise.reject( new Error("You are not authorized to view this page") @@ -127,7 +130,7 @@ function renderTable( downloadUrl, sort, onSortChange -) { +): Children { const presets = presetsResponse.value; const selectAll = m("input", { type: "checkbox", @@ -215,7 +218,7 @@ function renderTable( "a", { onclick: () => { - const cb = () => { + const cb = (): Children => { return m( putFormComponent, Object.assign( @@ -225,9 +228,11 @@ function renderTable( return new Promise(resolve => { putActionHandler(action, object, false) .then(errors => { - errors = errors ? Object.values(errors) : []; - if (errors.length) { - for (const err of errors) + const errorList = errors + ? Object.values(errors) + : []; + if (errorList.length) { + for (const err of errorList) notifications.push("error", err); } else { overlay.close(cb); @@ -334,7 +339,7 @@ function renderTable( { title: "Create new preset", onclick: () => { - const cb = () => { + const cb = (): Children => { return m( putFormComponent, Object.assign( @@ -343,9 +348,11 @@ function renderTable( return new Promise(resolve => { putActionHandler(action, object, true) .then(errors => { - errors = errors ? Object.values(errors) : []; - if (errors.length) { - for (const err of errors) + const errorList = errors + ? Object.values(errors) + : []; + if (errorList.length) { + for (const err of errorList) notifications.push("error", err); } else { overlay.close(cb); @@ -382,37 +389,39 @@ function renderTable( ]; } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { document.title = "Presets - GenieACS"; - function showMore() { - vnode.state.showCount = - (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE; + function showMore(): void { + vnode.state["showCount"] = + (vnode.state["showCount"] || PAGE_SIZE) + PAGE_SIZE; m.redraw(); } - function onFilterChanged(filter) { + function onFilterChanged(filter): void { const ops = { filter }; - if (vnode.attrs.sort) ops.sort = vnode.attrs.sort; + if (vnode.attrs["sort"]) ops["sort"] = vnode.attrs["sort"]; m.route.set(m.route.get(), ops); } - function onSortChange(sort) { + function onSortChange(sort): void { const ops = { sort }; - if (vnode.attrs.filter) ops.filter = vnode.attrs.filter; + if (vnode.attrs["filter"]) ops["filter"] = vnode.attrs["filter"]; m.route.set(m.route.get(), ops); } - const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {}; - let filter = vnode.attrs.filter - ? memoizedParse(vnode.attrs.filter) + const sort = vnode.attrs["sort"] + ? memoizedJsonParse(vnode.attrs["sort"]) + : {}; + let filter = vnode.attrs["filter"] + ? memoizedParse(vnode.attrs["filter"]) : true; filter = unpackSmartQuery(filter); const presets = store.fetch("presets", filter, { - limit: vnode.state.showCount || PAGE_SIZE, + limit: vnode.state["showCount"] || PAGE_SIZE, sort: sort }); const count = store.count("presets", filter); @@ -435,27 +444,28 @@ export function component() { for (const p of provisions.value) provisionIds.add(p["_id"]); - provisionAttr.options = Array.from(provisionIds); + provisionAttr["options"] = Array.from(provisionIds); } const selected = new Set(); - if (vnode.state.selected) { + if (vnode.state["selected"]) { for (const preset of presets.value) { - if (vnode.state.selected.has(preset["_id"])) + if (vnode.state["selected"].has(preset["_id"])) selected.add(preset["_id"]); } } - vnode.state.selected = selected; + vnode.state["selected"] = selected; - const downloadUrl = getDownloadUrl(vnode.attrs.filter); + const downloadUrl = getDownloadUrl(vnode.attrs["filter"]); + + const attrs = {}; + attrs["resource"] = "presets"; + attrs["filter"] = vnode.attrs["filter"]; + attrs["onChange"] = onFilterChanged; return [ m("h1", "Listing presets"), - m(filterComponent, { - resource: "presets", - filter: vnode.attrs.filter, - onChange: onFilterChanged - }), + m(filterComponent, attrs), renderTable( presets, count.value, @@ -468,4 +478,4 @@ export function component() { ]; } }; -} +}; diff --git a/ui/provisions-page.js b/ui/provisions-page.ts similarity index 84% rename from ui/provisions-page.js rename to ui/provisions-page.ts index 1ad52d3..7ef1eda 100644 --- a/ui/provisions-page.js +++ b/ui/provisions-page.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { ClosureComponent, Component, Children } from "mithril"; import { m } from "./components"; import config from "./config"; import filterComponent from "./filter-component"; @@ -30,7 +29,11 @@ const unpackSmartQuery = memoize(query => { }); }); -function putActionHandler(action, _object, isNew) { +interface ValidationErrors { + [prop: string]: string; +} + +function putActionHandler(action, _object, isNew): Promise { return new Promise((resolve, reject) => { const object = Object.assign({}, _object); if (action === "save") { @@ -97,7 +100,7 @@ const getDownloadUrl = memoize(filter => { })}`; }); -export function init(args) { +export function init(args): Promise<{}> { if (!window.authorizer.hasAccess("provisions", 2)) { return Promise.reject( new Error("You are not authorized to view this page") @@ -124,7 +127,7 @@ function renderTable( downloadUrl, sort, onSortChange -) { +): Children { const provisions = provisionsResponse.value; const selectAll = m("input", { type: "checkbox", @@ -197,7 +200,7 @@ function renderTable( "a", { onclick: () => { - const cb = () => { + const cb = (): Children => { return m( putFormComponent, Object.assign( @@ -207,9 +210,11 @@ function renderTable( return new Promise(resolve => { putActionHandler(action, object, false) .then(errors => { - errors = errors ? Object.values(errors) : []; - if (errors.length) { - for (const err of errors) + const errorList = errors + ? Object.values(errors) + : []; + if (errorList.length) { + for (const err of errorList) notifications.push("error", err); } else { overlay.close(cb); @@ -322,7 +327,7 @@ function renderTable( { title: "Create new provision", onclick: () => { - const cb = () => { + const cb = (): Children => { return m( putFormComponent, Object.assign( @@ -331,9 +336,11 @@ function renderTable( return new Promise(resolve => { putActionHandler(action, object, true) .then(errors => { - errors = errors ? Object.values(errors) : []; - if (errors.length) { - for (const err of errors) + const errorList = errors + ? Object.values(errors) + : []; + if (errorList.length) { + for (const err of errorList) notifications.push("error", err); } else { overlay.close(cb); @@ -370,60 +377,63 @@ function renderTable( ]; } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { document.title = "Provisions - GenieACS"; - function showMore() { - vnode.state.showCount = - (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE; + function showMore(): void { + vnode.state["showCount"] = + (vnode.state["showCount"] || PAGE_SIZE) + PAGE_SIZE; m.redraw(); } - function onFilterChanged(filter) { + function onFilterChanged(filter): void { const ops = { filter }; - if (vnode.attrs.sort) ops.sort = vnode.attrs.sort; + if (vnode.attrs["sort"]) ops["sort"] = vnode.attrs["sort"]; m.route.set(m.route.get(), ops); } - function onSortChange(sort) { + function onSortChange(sort): void { const ops = { sort }; - if (vnode.attrs.filter) ops.filter = vnode.attrs.filter; + if (vnode.attrs["filter"]) ops["filter"] = vnode.attrs["filter"]; m.route.set(m.route.get(), ops); } - const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {}; - let filter = vnode.attrs.filter - ? memoizedParse(vnode.attrs.filter) + const sort = vnode.attrs["sort"] + ? memoizedJsonParse(vnode.attrs["sort"]) + : {}; + let filter = vnode.attrs["filter"] + ? memoizedParse(vnode.attrs["filter"]) : true; filter = unpackSmartQuery(filter); const provisions = store.fetch("provisions", filter, { - limit: vnode.state.showCount || PAGE_SIZE, + limit: vnode.state["showCount"] || PAGE_SIZE, sort: sort }); const count = store.count("provisions", filter); const selected = new Set(); - if (vnode.state.selected) { + if (vnode.state["selected"]) { for (const provision of provisions.value) { - if (vnode.state.selected.has(provision["_id"])) + if (vnode.state["selected"].has(provision["_id"])) selected.add(provision["_id"]); } } - vnode.state.selected = selected; + vnode.state["selected"] = selected; - const downloadUrl = getDownloadUrl(vnode.attrs.filter); + const downloadUrl = getDownloadUrl(vnode.attrs["filter"]); + + const attrs = {}; + attrs["resource"] = "provisions"; + attrs["filter"] = vnode.attrs["filter"]; + attrs["onChange"] = onFilterChanged; return [ m("h1", "Listing provisions"), - m(filterComponent, { - resource: "provisions", - filter: vnode.attrs.filter, - onChange: onFilterChanged - }), + m(filterComponent, attrs), renderTable( provisions, count.value, @@ -436,4 +446,4 @@ export function component() { ]; } }; -} +}; diff --git a/ui/put-form-component.js b/ui/put-form-component.ts similarity index 66% rename from ui/put-form-component.js rename to ui/put-form-component.ts index 02997db..6e00f5a 100644 --- a/ui/put-form-component.js +++ b/ui/put-form-component.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { VnodeDOM, ClosureComponent, Component, Children } from "mithril"; import { m } from "./components"; import { codeMirror } from "./dynamic-loader"; @@ -10,7 +9,7 @@ const singular = { files: "file" }; -function createField(current, attr, focus) { +function createField(current, attr, focus): Children { if (attr.type === "combo") { const options = [m("option", { value: "" }, "--Please choose--")]; for (const op of attr.options) options.push(m("option", { value: op }, op)); @@ -25,7 +24,7 @@ function createField(current, attr, focus) { value: selected, oncreate: focus ? _vnode => { - _vnode.dom.focus(); + (_vnode.dom as HTMLSelectElement).focus(); } : null, onchange: e => { @@ -45,10 +44,14 @@ function createField(current, attr, focus) { lineNumbers: true, extraKeys: { "Ctrl-Enter": () => { - _vnode.dom.form.querySelector("button[type=submit]").click(); + ((_vnode.dom as HTMLTextAreaElement).form.querySelector( + "button[type=submit]" + ) as HTMLButtonElement).click(); }, "Cmd-Enter": () => { - _vnode.dom.form.querySelector("button[type=submit]").click(); + ((_vnode.dom as HTMLTextAreaElement).form.querySelector( + "button[type=submit]" + ) as HTMLButtonElement).click(); } } }); @@ -66,7 +69,7 @@ function createField(current, attr, focus) { name: attr.id, oncreate: focus ? _vnode => { - _vnode.dom.focus(); + (_vnode.dom as HTMLInputElement).focus(); } : null, onchange: e => { @@ -83,7 +86,7 @@ function createField(current, attr, focus) { value: current.object[attr.id], oncreate: focus ? _vnode => { - _vnode.dom.focus(); + (_vnode.dom as HTMLInputElement).focus(); } : null, oninput: e => { @@ -93,21 +96,21 @@ function createField(current, attr, focus) { }); } -export default function component() { +const component: ClosureComponent = (): Component => { return { view: vnode => { - const actionHandler = vnode.attrs.actionHandler; - const attributes = vnode.attrs.attributes; - const resource = vnode.attrs.resource; - const base = vnode.attrs.base || {}; - if (!vnode.state.current) { - vnode.state.current = { + const actionHandler = vnode.attrs["actionHandler"]; + const attributes = vnode.attrs["attributes"]; + const resource = vnode.attrs["resource"]; + const base = vnode.attrs["base"] || {}; + if (!vnode.state["current"]) { + vnode.state["current"] = { isNew: !base["_id"], object: Object.assign({}, base) }; } - const current = vnode.state.current; + const current = vnode.state["current"]; const form = []; let focused = false; @@ -126,27 +129,29 @@ export default function component() { ); } - const submit = m("button.primary", { type: "submit" }, "Save"); + const submit = m( + "button.primary", + { type: "submit" }, + "Save" + ) as VnodeDOM; const buttons = [submit]; if (!current.isNew) { - buttons.push( - m( - "button.primary", - { - type: "button", - title: `Delete ${singular[resource] || resource}`, - onclick: e => { - e.redraw = false; - e.target.disabled = true; - actionHandler("delete", current.object).then(() => { - e.target.disabled = false; - }); - } - }, - "Delete" - ) - ); + buttons.push(m( + "button.primary", + { + type: "button", + title: `Delete ${singular[resource] || resource}`, + onclick: e => { + e.redraw = false; + e.target.disabled = true; + actionHandler("delete", current.object).then(() => { + e.target.disabled = false; + }); + } + }, + "Delete" + ) as VnodeDOM); } form.push(m(".actions-bar", buttons)); @@ -165,12 +170,12 @@ export default function component() { // const onsubmit = e.target.onsubmit; e.preventDefault(); // e.target.onsubmit = null; - submit.dom.disabled = true; + (submit.dom as HTMLFormElement).disabled = true; // submit.dom.textContent = "Loading ..."; actionHandler("save", current.object).then(() => { // submit.dom.textContent = "Save"; // e.target.onsubmit = onsubmit; - submit.dom.disabled = false; + (submit.dom as HTMLFormElement).disabled = false; }); } }, @@ -181,4 +186,6 @@ export default function component() { return m("div.put-form", children); } }; -} +}; + +export default component; diff --git a/ui/smart-query.js b/ui/smart-query.ts similarity index 86% rename from ui/smart-query.js rename to ui/smart-query.ts index 16c2414..69c9b02 100644 --- a/ui/smart-query.js +++ b/ui/smart-query.ts @@ -1,6 +1,5 @@ -"use strict"; - import config from "./config"; +import { Expression } from "../lib/types"; const resources = { devices: {}, @@ -34,19 +33,23 @@ const resources = { } }; -for (const v of Object.values(config.ui.filters)) { +for (const v of Object.values(config.ui.filters as { + label: string; + parameter: string; + type: string; +}[])) { resources.devices[v.label] = { parameter: v.parameter, type: (v.type || "").split(",").map(s => s.trim()) }; } -function getLabels(resource) { +export function getLabels(resource): string[] { if (!resources[resource]) return []; return Object.keys(resources[resource]); } -function queryNumber(param, value) { +function queryNumber(param, value): Expression { let op = "="; for (const o of ["<>", "=", "<=", "<", ">=", ">"]) { if (value.startsWith(o)) { @@ -62,7 +65,7 @@ function queryNumber(param, value) { return [op, param, v]; } -function queryTimestamp(param, value) { +function queryTimestamp(param, value): Expression { let op = "="; for (const o of ["<>", "=", "<=", "<", ">=", ">"]) { if (value.startsWith(o)) { @@ -78,11 +81,11 @@ function queryTimestamp(param, value) { return [op, param, v]; } -function queryString(param, value) { +function queryString(param, value): Expression { return ["LIKE", ["FUNC", "LOWER", param], value.toLowerCase()]; } -function queryMac(param, value) { +function queryMac(param, value): Expression { value = value.replace(/[^a-f0-9]/gi, "").toLowerCase(); if (!value) return null; if (value.length === 12) { @@ -104,11 +107,11 @@ function queryMac(param, value) { ]; } -function unpack(resource, label, value) { +export function unpack(resource, label, value): Expression { if (!resources[resource]) return null; const type = resources[resource][label].type; value = value.trim(); - const res = ["OR"]; + const res: Expression = ["OR"]; if (type.length === 0 || type.includes("number")) { const q = queryNumber(resources[resource][label].parameter, value); @@ -134,5 +137,3 @@ function unpack(resource, label, value) { else if (res.length === 2) return res[1]; else return res; } - -export { getLabels, unpack }; diff --git a/ui/store.js b/ui/store.ts similarity index 83% rename from ui/store.js rename to ui/store.ts index 8e722f4..2fbae2e 100644 --- a/ui/store.js +++ b/ui/store.ts @@ -1,9 +1,8 @@ -"use strict"; - import m from "mithril"; import { map, stringify } from "../lib/common/expression-parser"; import { or, and, not, evaluate, subset } from "../lib/common/expression"; import memoize from "../lib/common/memoize"; +import { QueryOptions, Expression } from "../lib/types"; const memoizedStringify = memoize(stringify); const memoizedEvaluate = memoize(evaluate); @@ -21,7 +20,16 @@ const queries = { value: new WeakMap() }; -const resources = {}; +interface Resources { + [resource: string]: { + objects: Map; + count: Map; + fetch: Map; + combinedFilter: Expression; + }; +} + +const resources: Resources = {}; for (const r of [ "devices", "faults", @@ -41,24 +49,29 @@ for (const r of [ } class QueryResponse { - get fulfilled() { + public get fulfilled(): boolean { queries.accessed.set(this, Date.now()); return !!queries.fulfilled.get(this); } - get value() { + public get fulfilling(): boolean { + queries.accessed.set(this, Date.now()); + return queries.fulfilling.has(this); + } + + public get value(): any { queries.accessed.set(this, Date.now()); return queries.value.get(this); } } -function unpackExpression(exp) { +export function unpackExpression(exp): Expression { if (!Array.isArray(exp)) return exp; const e = memoizedEvaluate(exp, null, fulfillTimestamp); return e; } -function count(resourceType, filter) { +export function count(resourceType, filter): QueryResponse { const filterStr = memoizedStringify(filter); let queryResponse = resources[resourceType].count.get(filterStr); if (queryResponse) return queryResponse; @@ -70,48 +83,53 @@ function count(resourceType, filter) { return queryResponse; } -function limitFilter(filter, sort, bookmark) { - const sortSort = (a, b) => Math.abs(b[1]) - Math.abs(a[1]); +function limitFilter(filter, sort, bookmark): Expression { + const sortSort = (a, b): number => Math.abs(b[1]) - Math.abs(a[1]); const arr = Object.entries(sort) .sort(sortSort) .reverse(); return and( filter, - arr.reduce((cur, kv) => { - const [param, asc] = kv; - if (asc <= 0) { - if (bookmark[param] == null) { - return or( - ["IS NOT NULL", ["PARAM", param]], - and(["IS NULL", ["PARAM", param]], cur) - ); + arr.reduce( + (cur, kv) => { + const [param, asc] = kv; + if (asc <= 0) { + if (bookmark[param] == null) { + return or( + ["IS NOT NULL", ["PARAM", param]], + and(["IS NULL", ["PARAM", param]], cur) + ); + } + + let f = null; + + if (typeof bookmark[param] !== "string") + f = or(f, [">=", ["PARAM", param], ""]); + + f = or(f, [">", ["PARAM", param], bookmark[param]]); + return or(f, and(["=", ["PARAM", param], bookmark[param]], cur)); + } else { + let f: Expression = ["IS NULL", ["PARAM", param]]; + if (bookmark[param] == null) return and(f, cur); + + if (typeof bookmark[param] !== "number") { + f = or(f, [">=", ["PARAM", param], 0]); + f = or(f, ["<", ["PARAM", param], 0]); + } + + f = or(f, ["<", ["PARAM", param], bookmark[param]]); + + return or(f, and(["=", ["PARAM", param], bookmark[param]], cur)); } - - let f = null; - - if (typeof bookmark[param] !== "string") - f = or(f, [">=", ["PARAM", param], ""]); - - f = or(f, [">", ["PARAM", param], bookmark[param]]); - return or(f, and(["=", ["PARAM", param], bookmark[param]], cur)); - } else { - let f = ["IS NULL", ["PARAM", param]]; - if (bookmark[param] == null) return and(f, cur); - - if (typeof bookmark[param] !== "number") { - f = or(f, [">=", ["PARAM", param], 0]); - f = or(f, ["<", ["PARAM", param], 0]); - } - - f = or(f, ["<", ["PARAM", param], bookmark[param]]); - - return or(f, and(["=", ["PARAM", param], bookmark[param]], cur)); - } - }, true) + }, + true as Expression + ) ); } -function compareFunction(sort) { +function compareFunction(sort: { + [param: string]: number; +}): (a: any, b: any) => number { const sortEntries = Object.entries(sort).sort( (a, b) => Math.abs(b[1]) - Math.abs(a[1]) ); @@ -149,7 +167,7 @@ function compareFunction(sort) { }; } -function findMatches(resourceType, filter, sort, limit) { +function findMatches(resourceType, filter, sort, limit): any[] { // Handle "tag =" and "tag <>" special cases if (resourceType === "devices") { filter = map(filter, e => { @@ -176,7 +194,7 @@ function findMatches(resourceType, filter, sort, limit) { return value; } -function inferQuery(resourceType, queryResponse) { +function inferQuery(resourceType, queryResponse): void { const limit = queries.limit.get(queryResponse); let filter = queries.filter.get(queryResponse); filter = unpackExpression(filter); @@ -197,7 +215,11 @@ function inferQuery(resourceType, queryResponse) { ); } -function fetch(resourceType, filter, options = {}) { +export function fetch( + resourceType, + filter, + options: QueryOptions = {} +): QueryResponse { const filterStr = memoizedStringify(filter); const sort = Object.assign({}, options.sort); for (const [k, v] of Object.entries(sort)) sort[k] += Math.sign(v); @@ -220,7 +242,7 @@ function fetch(resourceType, filter, options = {}) { return queryResponse; } -function fulfill(accessTimestamp, _fulfillTimestamp) { +export function fulfill(accessTimestamp, _fulfillTimestamp): Promise { let updated = false; if (_fulfillTimestamp > fulfillTimestamp) { @@ -270,7 +292,7 @@ function fulfill(accessTimestamp, _fulfillTimestamp) { } } - const toFetchAll = {}; + const toFetchAll: { [resourceType: string]: QueryResponse[] } = {}; for (const [resourceType, resource] of Object.entries(resources)) { for (const [queryResponseKey, queryResponse] of resource.fetch) { @@ -306,7 +328,7 @@ function fulfill(accessTimestamp, _fulfillTimestamp) { }) }) .then(res => { - if (res.length) { + if ((res as {}[]).length) { // Generate bookmark object const bm = Object.keys(sort).reduce((b, k) => { if (res[0][k] != null) { @@ -395,7 +417,7 @@ function fulfill(accessTimestamp, _fulfillTimestamp) { }) }) .then(res => { - for (const r of res) { + for (const r of res as {}[]) { const id = resourceType === "devices" ? r["DeviceID.ID"].value[0] @@ -439,11 +461,11 @@ function fulfill(accessTimestamp, _fulfillTimestamp) { }); } -function getTimestamp() { +export function getTimestamp(): number { return fulfillTimestamp; } -function postTasks(deviceId, tasks) { +export function postTasks(deviceId, tasks): Promise { for (const t of tasks) { t.status = "pending"; t.device = deviceId; @@ -471,7 +493,7 @@ function postTasks(deviceId, tasks) { }); } -function updateTags(deviceId, tags) { +export function updateTags(deviceId, tags): Promise { return m.request({ method: "POST", url: `/api/devices/${encodeURIComponent(deviceId)}/tags`, @@ -479,14 +501,14 @@ function updateTags(deviceId, tags) { }); } -function deleteResource(resourceType, id) { +export function deleteResource(resourceType, id): Promise { return m.request({ method: "DELETE", url: `/api/${resourceType}/${encodeURIComponent(id)}` }); } -function putResource(resourceType, id, object) { +export function putResource(resourceType, id, object): Promise { for (const k in object) if (object[k] === undefined) object[k] = null; return m.request({ @@ -496,7 +518,7 @@ function putResource(resourceType, id, object) { }); } -function resourceExists(resource, id) { +export function resourceExists(resource, id): Promise { const param = resource === "devices" ? "DeviceID.ID" : "_id"; const filter = ["=", ["PARAM", param], id]; return m.request({ @@ -511,12 +533,12 @@ function resourceExists(resource, id) { }); } -function evaluateExpression(exp, obj) { +export function evaluateExpression(exp, obj): Expression { if (!Array.isArray(exp)) return exp; return memoizedEvaluate(exp, obj, fulfillTimestamp); } -function logIn(username, password) { +export function logIn(username, password): Promise { return m.request({ method: "POST", url: "/login", @@ -525,32 +547,15 @@ function logIn(username, password) { }); } -function logOut() { +export function logOut(): Promise { return m.request({ method: "POST", url: "/logout" }); } -function ping(host) { +export function ping(host): Promise<{}> { return m.request({ url: `/api/ping/${encodeURIComponent(host)}` }); } - -export { - count, - fetch, - fulfill, - unpackExpression, - getTimestamp, - postTasks, - updateTags, - deleteResource, - putResource, - resourceExists, - evaluateExpression, - logIn, - logOut, - ping -}; diff --git a/ui/task-queue.js b/ui/task-queue.ts similarity index 74% rename from ui/task-queue.js rename to ui/task-queue.ts index b24244d..25d6aae 100644 --- a/ui/task-queue.js +++ b/ui/task-queue.ts @@ -1,47 +1,45 @@ -"use strict"; - import * as store from "./store"; const queue = new Set(); const staging = new Set(); -function queueTask(task) { +export function queueTask(task): void { staging.delete(task); task.status = "queued"; queue.add(task); } -function deleteTask(task) { +export function deleteTask(task): void { staging.delete(task); queue.delete(task); } -function getQueue() { +export function getQueue(): Set<{}> { return queue; } -function clear() { +export function clear(): void { queue.clear(); } -function getStaging() { +export function getStaging(): Set<{}> { return staging; } -function clearStaging() { +export function clearStaging(): void { staging.clear(); } -function stageSpv(task) { +export function stageSpv(task): void { staging.add(task); } -function stageDownload(task) { +export function stageDownload(task): void { staging.add(task); } -function commit(tasks, callback) { - const devices = {}; +export function commit(tasks, callback): Promise { + const devices: { [deviceId: string]: any[] } = {}; for (const t of tasks) { devices[t.device] = devices[t.device] || []; devices[t.device].push(t); @@ -72,15 +70,3 @@ function commit(tasks, callback) { if (--counter === 0) resolve(); }); } - -export { - queueTask, - deleteTask, - clear, - getQueue, - getStaging, - clearStaging, - stageSpv, - stageDownload, - commit -}; diff --git a/ui/timeago.js b/ui/timeago.ts similarity index 89% rename from ui/timeago.js rename to ui/timeago.ts index c0143ab..e03d23d 100644 --- a/ui/timeago.js +++ b/ui/timeago.ts @@ -1,5 +1,3 @@ -"use strict"; - const UNITS = { year: 12 * 30 * 24 * 60 * 60 * 1000, month: 30 * 24 * 60 * 60 * 1000, @@ -9,7 +7,7 @@ const UNITS = { second: 1000 }; -function timeAgo(dtime) { +export default function timeAgo(dtime): string { let res = ""; let level = 2; @@ -30,5 +28,3 @@ function timeAgo(dtime) { return res + "ago"; } - -export default timeAgo; diff --git a/ui/user-menu.js b/ui/user-menu.ts similarity index 88% rename from ui/user-menu.js rename to ui/user-menu.ts index 7eb1c31..3e4da8a 100644 --- a/ui/user-menu.js +++ b/ui/user-menu.ts @@ -1,11 +1,8 @@ -"use strict"; - -import m from "mithril"; - +import m, { ClosureComponent, Component } from "mithril"; import * as store from "./store"; import * as notifications from "./notifications"; -export default function userMenu() { +const component: ClosureComponent = (): Component => { return { view: () => { if (window.username) { @@ -48,4 +45,6 @@ export default function userMenu() { } } }; -} +}; + +export default component; diff --git a/ui/virtual-parameters-page.js b/ui/virtual-parameters-page.ts similarity index 84% rename from ui/virtual-parameters-page.js rename to ui/virtual-parameters-page.ts index 20354d8..aa694f7 100644 --- a/ui/virtual-parameters-page.js +++ b/ui/virtual-parameters-page.ts @@ -1,5 +1,4 @@ -"use strict"; - +import { ClosureComponent, Component, Children } from "mithril"; import { m } from "./components"; import config from "./config"; import filterComponent from "./filter-component"; @@ -30,7 +29,11 @@ const unpackSmartQuery = memoize(query => { }); }); -function putActionHandler(action, _object, isNew) { +interface ValidationErrors { + [prop: string]: string; +} + +function putActionHandler(action, _object, isNew): Promise { return new Promise((resolve, reject) => { const object = Object.assign({}, _object); if (action === "save") { @@ -97,7 +100,7 @@ const getDownloadUrl = memoize(filter => { })}`; }); -export function init(args) { +export function init(args): Promise<{}> { if (!window.authorizer.hasAccess("virtualParameters", 2)) { return Promise.reject( new Error("You are not authorized to view this page") @@ -124,7 +127,7 @@ function renderTable( downloadUrl, sort, onSortChange -) { +): Children { const virtualParameters = virtualParametersResponse.value; const selectAll = m("input", { type: "checkbox", @@ -198,7 +201,7 @@ function renderTable( "a", { onclick: () => { - const cb = () => { + const cb = (): Children => { return m( putFormComponent, Object.assign( @@ -208,9 +211,11 @@ function renderTable( return new Promise(resolve => { putActionHandler(action, object, false) .then(errors => { - errors = errors ? Object.values(errors) : []; - if (errors.length) { - for (const err of errors) + const errorList = errors + ? Object.values(errors) + : []; + if (errorList.length) { + for (const err of errorList) notifications.push("error", err); } else { overlay.close(cb); @@ -332,7 +337,7 @@ function renderTable( { title: "Create new virtual parameter", onclick: () => { - const cb = () => { + const cb = (): Children => { return m( putFormComponent, Object.assign( @@ -341,9 +346,11 @@ function renderTable( return new Promise(resolve => { putActionHandler(action, object, true) .then(errors => { - errors = errors ? Object.values(errors) : []; - if (errors.length) { - for (const err of errors) + const errorList = errors + ? Object.values(errors) + : []; + if (errorList.length) { + for (const err of errorList) notifications.push("error", err); } else { overlay.close(cb); @@ -380,60 +387,63 @@ function renderTable( ]; } -export function component() { +export const component: ClosureComponent = (): Component => { return { view: vnode => { document.title = "Virtual Parameters - GenieACS"; - function showMore() { - vnode.state.showCount = - (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE; + function showMore(): void { + vnode.state["showCount"] = + (vnode.state["showCount"] || PAGE_SIZE) + PAGE_SIZE; m.redraw(); } - function onFilterChanged(filter) { + function onFilterChanged(filter): void { const ops = { filter }; - if (vnode.attrs.sort) ops.sort = vnode.attrs.sort; + if (vnode.attrs["sort"]) ops["sort"] = vnode.attrs["sort"]; m.route.set(m.route.get(), ops); } - function onSortChange(sort) { + function onSortChange(sort): void { const ops = { sort }; - if (vnode.attrs.filter) ops.filter = vnode.attrs.filter; + if (vnode.attrs["filter"]) ops["filter"] = vnode.attrs["filter"]; m.route.set(m.route.get(), ops); } - const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {}; - let filter = vnode.attrs.filter - ? memoizedParse(vnode.attrs.filter) + const sort = vnode.attrs["sort"] + ? memoizedJsonParse(vnode.attrs["sort"]) + : {}; + let filter = vnode.attrs["filter"] + ? memoizedParse(vnode.attrs["filter"]) : true; filter = unpackSmartQuery(filter); const virtualParameters = store.fetch("virtualParameters", filter, { - limit: vnode.state.showCount || PAGE_SIZE, + limit: vnode.state["showCount"] || PAGE_SIZE, sort: sort }); const count = store.count("virtualParameters", filter); const selected = new Set(); - if (vnode.state.selected) { + if (vnode.state["selected"]) { for (const virtualParameter of virtualParameters.value) { - if (vnode.state.selected.has(virtualParameter["_id"])) + if (vnode.state["selected"].has(virtualParameter["_id"])) selected.add(virtualParameter["_id"]); } } - vnode.state.selected = selected; + vnode.state["selected"] = selected; - const downloadUrl = getDownloadUrl(vnode.attrs.filter); + const downloadUrl = getDownloadUrl(vnode.attrs["filter"]); + + const attrs = {}; + attrs["resource"] = "virtualParameters"; + attrs["filter"] = vnode.attrs["filter"]; + attrs["onChange"] = onFilterChanged; return [ m("h1", "Listing virtual parameters"), - m(filterComponent, { - resource: "virtualParameters", - filter: vnode.attrs.filter, - onChange: onFilterChanged - }), + m(filterComponent, attrs), renderTable( virtualParameters, count.value, @@ -446,4 +456,4 @@ export function component() { ]; } }; -} +};