From 8757a46b91055384d7943b61af04ea2595ea58ea Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Mon, 13 Jul 2020 11:29:16 +0200 Subject: [PATCH] Updated the new loader (Images still missing since they're not yet finished) --- .gitignore | 3 +- ChangeLog.md | 4 + babel.config.js | 27 + file.ts | 2 +- loader/IndexGenerator.ts | 31 + loader/app/animation.ts | 128 +++ loader/app/index.ts | 17 +- loader/app/loader/loader.ts | 136 ++- loader/app/loader/script_loader.ts | 7 +- loader/app/loader/style_loader.ts | 6 +- loader/app/loader/template_loader.ts | 6 +- loader/app/loader/utils.ts | 41 +- loader/app/polifill.ts | 57 ++ loader/app/targets/app.ts | 93 +- loader/app/targets/certaccept.ts | 6 - loader/app/targets/empty.ts | 27 + loader/app/targets/shared.ts | 38 + loader/css/index.scss | 7 + loader/css/loader.scss | 456 +++------ loader/css/overlay.scss | 58 ++ loader/html/index.html.ejs | 111 +++ package-lock.json | 1340 ++++++++++++++++++++++++++ package.json | 5 + shared/html/index.html.ejs | 220 ----- shared/js/main.tsx | 2 - tsbaseconfig.json | 4 +- webpack.config.ts | 50 +- webpack/EJSGenerator.ts | 53 +- 28 files changed, 2216 insertions(+), 719 deletions(-) create mode 100644 babel.config.js create mode 100644 loader/IndexGenerator.ts create mode 100644 loader/app/animation.ts create mode 100644 loader/app/polifill.ts create mode 100644 loader/app/targets/empty.ts create mode 100644 loader/app/targets/shared.ts create mode 100644 loader/css/index.scss create mode 100644 loader/css/overlay.scss create mode 100644 loader/html/index.html.ejs delete mode 100644 shared/html/index.html.ejs diff --git a/.gitignore b/.gitignore index dd6b5dcd..e8d198e4 100644 --- a/.gitignore +++ b/.gitignore @@ -25,9 +25,10 @@ node_modules/ /todo.txt /tmp/ -# All out config files are .ts files +# All our config files are .ts files /*.js /*.js.map +!babel.config.js /webpack/*.js /webpack/*.js.map diff --git a/ChangeLog.md b/ChangeLog.md index ea0c03b0..dbc8115a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,4 +1,8 @@ # Changelog: +* **12.07.20** + - Made the loader compatible with ES5 to support older browsers + - Updated the loader animation + * **15.06.20** - Recoded the permission editor with react - Fixed sever permission editor display bugs diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 00000000..15e4dde8 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,27 @@ +module.exports = function (api) { + api.cache(false); + const presets = [ + [ + "@babel/preset-env", + { + "corejs": { "version":3 }, + "useBuiltIns": "usage", + "targets": { + "edge": "17", + "firefox": "60", + "chrome": "67", + "safari": "11.1", + "ie": "11" + } + } + ] + ]; + const plugins = [ + ["@babel/transform-runtime"], + ["@babel/plugin-transform-modules-commonjs"] + ]; + return { + presets, + plugins + }; +}; \ No newline at end of file diff --git a/file.ts b/file.ts index 3675dbdc..d0cf2e10 100644 --- a/file.ts +++ b/file.ts @@ -121,7 +121,7 @@ const APP_FILE_LIST_SHARED_SOURCE: ProjectResource[] = [ }, { /* shared image files */ "type": "img", - "search-pattern": /.*\.(svg|png)/, + "search-pattern": /.*\.(svg|png|gif)/, "build-target": "dev|rel", "path": "img/", diff --git a/loader/IndexGenerator.ts b/loader/IndexGenerator.ts new file mode 100644 index 00000000..6b049ca8 --- /dev/null +++ b/loader/IndexGenerator.ts @@ -0,0 +1,31 @@ +import * as path from "path"; +import EJSGenerator = require("../webpack/EJSGenerator"); + +class IndexGenerator extends EJSGenerator { + constructor(options: { + buildTarget: string; + output: string, + isDevelopment: boolean + }) { + super({ + variables: { + build_target: options.buildTarget + }, + output: options.output, + initialJSEntryChunk: "loader", + input: path.join(__dirname, "html/index.html.ejs"), + minify: !options.isDevelopment, + + embedInitialJSEntryChunk: !options.isDevelopment, + embedInitialCSSFile: !options.isDevelopment, + + initialCSSFile: { + localFile: path.join(__dirname, "css/index.css"), + publicFile: "css/index.css" + } + }); + } + +} + +export = IndexGenerator; \ No newline at end of file diff --git a/loader/app/animation.ts b/loader/app/animation.ts new file mode 100644 index 00000000..d14f616e --- /dev/null +++ b/loader/app/animation.ts @@ -0,0 +1,128 @@ +import * as loader from "./loader/loader"; +import {Stage} from "./loader/loader"; + +let overlay: HTMLDivElement; +let setupContainer: HTMLDivElement; +let idleContainer: HTMLDivElement; +let idleSteamContainer: HTMLDivElement; +let loaderStageContainer: HTMLDivElement; + +let finalizing = false; +let initializeTimestamp; + +let verbose = false; +let apngSupport = undefined; + +async function detectAPNGSupport() { + const image = new Image(); + const ctx = document.createElement("canvas").getContext("2d"); + + // frame 1 (skipped on apng-supporting browsers): [0, 0, 0, 255] + // frame 2: [0, 0, 0, 0] + image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACGFjVEwAAAABAAAAAcMq2TYAAAANSURBVAiZY2BgYPgPAAEEAQB9ssjfAAAAGmZjVEwAAAAAAAAAAQAAAAEAAAAAAAAAAAD6A+gBAbNU+2sAAAARZmRBVAAAAAEImWNgYGBgAAAABQAB6MzFdgAAAABJRU5ErkJggg=="; + await new Promise(resolve => image.onload = resolve); + + ctx.drawImage(image, 0, 0); + apngSupport = ctx.getImageData(0, 0, 1, 1).data[3] === 0; + console.log("Browser APNG support: %o", apngSupport); +} + +function initializeElements() { + overlay = document.getElementById("loader-overlay") as HTMLDivElement; + if(!overlay) + throw "missing loader overlay"; + + for(const lazyImage of [...overlay.getElementsByTagName("lazy-img")]) { + const image = document.createElement("img"); + image.alt = lazyImage.getAttribute("alt"); + image.src = lazyImage.getAttribute(apngSupport ? "src-apng" : "src-gif") || lazyImage.getAttribute("src"); + image.className = lazyImage.className; + lazyImage.replaceWith(image); + } + + setupContainer = overlay.getElementsByClassName("setup")[0] as HTMLDivElement; + if(!setupContainer) + throw "missing setup container"; + + idleContainer = overlay.getElementsByClassName("idle")[0] as HTMLDivElement; + if(!idleContainer) + throw "missing idle container"; + + idleSteamContainer = idleContainer.getElementsByClassName("steam")[0] as HTMLDivElement; + if(!idleSteamContainer) + throw "missing idle steam container"; + + loaderStageContainer = overlay.getElementsByClassName("loader-stage")[0] as HTMLDivElement; + if(!loaderStageContainer) + throw "missing loader stage container"; + + setupContainer.onanimationend = setupAnimationFinished; + idleSteamContainer.onanimationiteration = idleSteamAnimationLooped; + overlay.onanimationend = overlayAnimationFinished; +} + +export async function initialize() { + await detectAPNGSupport(); + try { + initializeElements(); + } catch (error) { + console.error("Failed to setup animations: %o", error); + loader.critical_error("Animation setup failed", error); + return false; + } + + StageNames[Stage.SETUP] = "starting app"; + StageNames[Stage.TEMPLATES] = "loading templates"; + StageNames[Stage.STYLE] = "loading styles"; + StageNames[Stage.JAVASCRIPT] = "loading app"; + StageNames[Stage.JAVASCRIPT_INITIALIZING] = "initializing"; + StageNames[Stage.FINALIZING] = "rounding up"; + StageNames[Stage.LOADED] = "starting app"; + + overlay.classList.add("initialized"); + setupContainer.classList.add("visible"); + + initializeTimestamp = Date.now(); + return true; +} + +export function abort() { + overlay?.remove(); +} + +export function finalize() { + finalizing = true; + + if(loaderStageContainer) + loaderStageContainer.innerText = "app loaded successfully (" + (Date.now() - initializeTimestamp) + "ms)"; +} + +const StageNames = {}; +export function updateState(state: Stage, tasks: string[]) { + if(loaderStageContainer) + loaderStageContainer.innerText = StageNames[state] + (tasks.length === 1 ? " (task: " + tasks[0] + ")" : " (tasks: " + tasks.join(",") + ")"); +} + +function setupAnimationFinished() { + verbose && console.log("Entering idle animation"); + + setupContainer.classList.remove("visible"); + idleContainer.classList.add("visible"); +} + +function idleSteamAnimationLooped() { + verbose && console.log("Idle animation looped. Should finalize: %o", finalizing); + if(!finalizing) + return; + + overlay.classList.add("finishing"); +} + +function overlayAnimationFinished(event: AnimationEvent) { + /* the text animation is the last one */ + if(event.animationName !== "swipe-out-text") + return; + + verbose && console.log("Animation finished"); + overlay.remove(); +} \ No newline at end of file diff --git a/loader/app/index.ts b/loader/app/index.ts index 0f9091a9..8276a1f4 100644 --- a/loader/app/index.ts +++ b/loader/app/index.ts @@ -1,8 +1,15 @@ -import * as loader from "./targets/app"; -import * as loader_base from "./loader/loader"; -window["loader"] = loader_base; - /* let the loader register himself at the window first */ -setTimeout(loader.run, 0); +import "core-js/stable"; +import "./polifill"; + +import * as loader from "./loader/loader"; +window["loader"] = loader; +/* let the loader register himself at the window first */ + +import * as AppLoader from "./targets/app"; +setTimeout(AppLoader.run, 0); + +import * as EmptyLoader from "./targets/empty"; +//setTimeout(EmptyLoader.run, 0); export {}; diff --git a/loader/app/loader/loader.ts b/loader/app/loader/loader.ts index cf725c82..865064fa 100644 --- a/loader/app/loader/loader.ts +++ b/loader/app/loader/loader.ts @@ -1,6 +1,7 @@ import * as script_loader from "./script_loader"; import * as style_loader from "./style_loader"; import * as template_loader from "./template_loader"; +import * as Animation from "../animation"; declare global { interface Window { @@ -31,7 +32,7 @@ export let config: Config = { export type Task = { name: string, priority: number, /* tasks with the same priority will be executed in sync */ - function: () => Promise + function: (taskId?: number) => Promise }; export enum Stage { @@ -39,30 +40,37 @@ export enum Stage { loading loader required files (incl this) */ INITIALIZING, + /* setting up the loading process */ SETUP, + /* loading all style sheet files */ STYLE, + /* loading all javascript files */ JAVASCRIPT, + /* loading all template files */ TEMPLATES, + /* initializing static/global stuff */ JAVASCRIPT_INITIALIZING, + /* finalizing load process */ FINALIZING, + /* invoking main task */ @@ -72,7 +80,7 @@ export enum Stage { } let cache_tag: string | undefined; -let current_stage: Stage = undefined; +let currentStage: Stage = undefined; const tasks: {[key:number]:Task[]} = {}; /* test if all files shall be load from cache or fetch again */ @@ -109,12 +117,12 @@ export function module_mapping() : ModuleMapping[] { return module_mapping_; } export function get_cache_version() { return cache_tag; } export function finished() { - return current_stage == Stage.DONE; + return currentStage == Stage.DONE; } -export function running() { return typeof(current_stage) !== "undefined"; } +export function running() { return typeof(currentStage) !== "undefined"; } export function register_task(stage: Stage, task: Task) { - if(current_stage > stage) { + if(currentStage > stage) { if(config.error) console.warn("Register loading task, but it had already been finished. Executing task anyways!"); @@ -139,20 +147,41 @@ export function register_task(stage: Stage, task: Task) { tasks[stage] = task_array.sort((a, b) => a.priority - b.priority); } +type RunningTask = { + taskId: number, + name: string, + promise: Promise | undefined +}; +let runningTasks: RunningTask[] = []; +let runningTaskIdIndex = 1; + +export function setCurrentTaskName(taskId: number, name: string) { + const task = runningTasks.find(e => e.taskId === taskId); + if(!task) { + console.warn("Tried to set task name of unknown task %d", taskId); + return; + } + + task.name = name; + Animation.updateState(currentStage, runningTasks.map(e => e.name)); +} + export async function execute() { - document.getElementById("loader-overlay").classList.add("started"); + if(!await Animation.initialize()) + return; + loader_cache_tag(); const load_begin = Date.now(); let begin: number = 0; let end: number = Date.now(); - while(current_stage <= Stage.LOADED || typeof(current_stage) === "undefined") { + while(currentStage <= Stage.LOADED || typeof(currentStage) === "undefined") { - let current_tasks: Task[] = []; - while((tasks[current_stage] || []).length > 0) { - if(current_tasks.length == 0 || current_tasks[0].priority == tasks[current_stage][0].priority) { - current_tasks.push(tasks[current_stage].pop()); + let pendingTasks: Task[] = []; + while((tasks[currentStage] || []).length > 0) { + if(pendingTasks.length == 0 || pendingTasks[0].priority == tasks[currentStage][0].priority) { + pendingTasks.push(tasks[currentStage].pop()); } else break; } @@ -161,23 +190,45 @@ export async function execute() { task: Task }[] = []; - const promises: Promise[] = []; - for(const task of current_tasks) { + for(const task of pendingTasks) { + const rTask = { + taskId: ++runningTaskIdIndex, + name: task.name, + promise: undefined + } as RunningTask; + try { - if(config.verbose) console.debug("Executing loader %s (%d)", task.name, task.priority); - const promise = task.function(); + if(config.verbose) + console.debug("Executing loader %s (%d)", task.name, task.priority); + + runningTasks.push(rTask); + const promise = task.function(rTask.taskId); if(!promise) { + runningTasks.splice(runningTasks.indexOf(rTask), 1); console.error("Loading task %s hasn't returned a promise!", task.name); continue; } - promises.push(promise.catch(error => { + + rTask.promise = promise.catch(error => { errors.push({ task: task, error: error }); + return Promise.resolve(); - })); + }).then(() => { + const index = runningTasks.indexOf(rTask); + if(index === -1) { + console.warn("Running task (%s) finished, but it has been unregistered already!", task.name); + return; + } + runningTasks.splice(index, 1); + }); } catch(error) { + const index = runningTasks.indexOf(rTask); + if(index !== -1) + runningTasks.splice(index, 1); + errors.push({ task: task, error: error @@ -185,41 +236,47 @@ export async function execute() { } } - if(promises.length > 0) { - await Promise.all([...promises]); + if(runningTasks.length > 0) { + Animation.updateState(currentStage, runningTasks.map(e => e.name)); + await Promise.all(runningTasks.map(e => e.promise)); } if(errors.length > 0) { - if(config.loader_groups) console.groupEnd(); + if(config.loader_groups) + console.groupEnd(); console.error("Failed to execute loader. The following tasks failed (%d):", errors.length); for(const error of errors) console.error(" - %s: %o", error.task.name, error.error); - throw "failed to process step " + Stage[current_stage]; + throw "failed to process step " + Stage[currentStage]; } - if(current_tasks.length == 0) { - if(typeof(current_stage) === "undefined") { - current_stage = -1; + if(pendingTasks.length == 0) { + if(typeof(currentStage) === "undefined") { + currentStage = -1; if(config.verbose) console.debug("[loader] Booting app"); - } else if(current_stage < Stage.INITIALIZING) { + } else if(currentStage < Stage.INITIALIZING) { if(config.loader_groups) console.groupEnd(); - if(config.verbose) console.debug("[loader] Entering next state (%s). Last state took %dms", Stage[current_stage + 1], (end = Date.now()) - begin); + if(config.verbose) console.debug("[loader] Entering next state (%s). Last state took %dms", Stage[currentStage + 1], (end = Date.now()) - begin); } else { if(config.loader_groups) console.groupEnd(); if(config.verbose) console.debug("[loader] Finish invoke took %dms", (end = Date.now()) - begin); } begin = end; - current_stage += 1; + currentStage += 1; - if(current_stage != Stage.DONE && config.loader_groups) - console.groupCollapsed("Executing loading stage %s", Stage[current_stage]); + if(currentStage != Stage.DONE && config.loader_groups) + console.groupCollapsed("Executing loading stage %s", Stage[currentStage]); } } - if(config.verbose) console.debug("[loader] finished loader. (Total time: %dms)", Date.now() - load_begin); + if(config.verbose) + console.debug("[loader] finished loader. (Total time: %dms)", Date.now() - load_begin); + + Animation.finalize(); } + export function execute_managed() { execute().then(() => { if(config.verbose) { @@ -242,28 +299,12 @@ export function execute_managed() { }); } -let _fadeout_warned; -export function hide_overlay() { - if(typeof($) === "undefined") { - if(!_fadeout_warned) - console.warn("Could not fadeout loader screen. Missing jquery functions."); - _fadeout_warned = true; - return; - } - const animation_duration = 750; - - $(".loader .bookshelf_wrapper").animate({top: 0, opacity: 0}, animation_duration); - $(".loader .half").animate({width: 0}, animation_duration, () => { - $(".loader").detach(); - }); -} - /* critical error handler */ export type ErrorHandler = (message: string, detail: string) => void; let _callback_critical_error: ErrorHandler; let _callback_critical_called: boolean = false; export function critical_error(message: string, detail?: string) { - document.getElementById("loader-overlay").classList.add("started"); + Animation.abort(); if(_callback_critical_called) { console.warn("[CRITICAL] %s", message); @@ -312,7 +353,6 @@ export const templates = template_loader; /* Hello World message */ { - const clog = console.log; const print_security = () => { { diff --git a/loader/app/loader/script_loader.ts b/loader/app/loader/script_loader.ts index 80a3622f..8a7a10a9 100644 --- a/loader/app/loader/script_loader.ts +++ b/loader/app/loader/script_loader.ts @@ -1,5 +1,5 @@ import {config, critical_error, SourcePath} from "./loader"; -import {load_parallel, LoadSyntaxError, ParallelOptions, script_name} from "./utils"; +import {load_parallel, LoadCallback, LoadSyntaxError, ParallelOptions, script_name} from "./utils"; let _script_promises: {[key: string]: Promise} = {}; @@ -88,13 +88,14 @@ export async function load(path: SourcePath, options: Options) : Promise { throw "Missing dependency " + depend; await _script_promises[depend]; } + await load_script_url(source.url + (options.cache_tag || "")); } } type MultipleOptions = Options | ParallelOptions; -export async function load_multiple(paths: SourcePath[], options: MultipleOptions) : Promise { - const result = await load_parallel(paths, e => load(e, options), e => script_name(e, false), options); +export async function load_multiple(paths: SourcePath[], options: MultipleOptions, callback?: LoadCallback) : Promise { + const result = await load_parallel(paths, e => load(e, options), e => script_name(e, false), options, callback); if(result.failed.length > 0) { if(config.error) { console.error("Failed to load the following scripts:"); diff --git a/loader/app/loader/style_loader.ts b/loader/app/loader/style_loader.ts index f23ec3e2..b3ea670e 100644 --- a/loader/app/loader/style_loader.ts +++ b/loader/app/loader/style_loader.ts @@ -1,5 +1,5 @@ import {config, critical_error, SourcePath} from "./loader"; -import {load_parallel, LoadSyntaxError, ParallelOptions, script_name} from "./utils"; +import {load_parallel, LoadCallback, LoadSyntaxError, ParallelOptions, script_name} from "./utils"; let _style_promises: {[key: string]: Promise} = {}; @@ -121,8 +121,8 @@ export async function load(path: SourcePath, options: Options) : Promise { } export type MultipleOptions = Options | ParallelOptions; -export async function load_multiple(paths: SourcePath[], options: MultipleOptions) : Promise { - const result = await load_parallel(paths, e => load(e, options), e => script_name(e, false), options); +export async function load_multiple(paths: SourcePath[], options: MultipleOptions, callback?: LoadCallback) : Promise { + const result = await load_parallel(paths, e => load(e, options), e => script_name(e, false), options, callback); if(result.failed.length > 0) { if(config.error) { console.error("Failed to load the following style sheets:"); diff --git a/loader/app/loader/template_loader.ts b/loader/app/loader/template_loader.ts index cfe51660..6bf25e93 100644 --- a/loader/app/loader/template_loader.ts +++ b/loader/app/loader/template_loader.ts @@ -1,5 +1,5 @@ import {config, critical_error, SourcePath} from "./loader"; -import {load_parallel, LoadSyntaxError, ParallelOptions, script_name} from "./utils"; +import {load_parallel, LoadCallback, LoadSyntaxError, ParallelOptions, script_name} from "./utils"; let _template_promises: {[key: string]: Promise} = {}; @@ -69,8 +69,8 @@ export async function load(path: SourcePath, options: Options) : Promise { } export type MultipleOptions = Options | ParallelOptions; -export async function load_multiple(paths: SourcePath[], options: MultipleOptions) : Promise { - const result = await load_parallel(paths, e => load(e, options), e => script_name(e, false), options); +export async function load_multiple(paths: SourcePath[], options: MultipleOptions, callback?: LoadCallback) : Promise { + const result = await load_parallel(paths, e => load(e, options), e => script_name(e, false), options, callback); if(result.failed.length > 0) { if(config.error) { console.error("Failed to load the following template files:"); diff --git a/loader/app/loader/utils.ts b/loader/app/loader/utils.ts index fdab50f2..8dfc717d 100644 --- a/loader/app/loader/utils.ts +++ b/loader/app/loader/utils.ts @@ -10,11 +10,7 @@ export class LoadSyntaxError { export function script_name(path: SourcePath, html: boolean) { if(Array.isArray(path)) { - let buffer = ""; - let _or = " or "; - for(let entry of path) - buffer += _or + script_name(entry, html); - return buffer.slice(_or.length); + return path.filter(e => !!e).map(e => script_name(e, html)).join(" or "); } else if(typeof(path) === "string") return html ? "" + path + "" : path; else @@ -35,31 +31,40 @@ export interface ParallelResult { skipped: T[]; } -export async function load_parallel(requests: T[], executor: (_: T) => Promise, stringify: (_: T) => string, options: ParallelOptions) : Promise> { +export type LoadCallback = (entry: T, state: "loading" | "loaded") => void; + +export async function load_parallel(requests: T[], executor: (_: T) => Promise, stringify: (_: T) => string, options: ParallelOptions, callback?: LoadCallback) : Promise> { const result: ParallelResult = { failed: [], succeeded: [], skipped: [] }; - const pending_requests = requests.slice(0).reverse(); /* we're only able to pop from the back */ - const current_requests = {}; + const pendingRequests = requests.slice(0).reverse(); /* we're only able to pop from the back */ + const currentRequests = {}; - while (pending_requests.length > 0) { - while(typeof options.max_parallel_requests !== "number" || options.max_parallel_requests <= 0 || Object.keys(current_requests).length < options.max_parallel_requests) { - const script = pending_requests.pop(); - const name = stringify(script); + if(typeof callback === "undefined") + callback = () => {}; - current_requests[name] = executor(script).catch(e => result.failed.push({ request: script, error: e })).then(() => { - delete current_requests[name]; + options.max_parallel_requests = 1; + while (pendingRequests.length > 0) { + while(typeof options.max_parallel_requests !== "number" || options.max_parallel_requests <= 0 || Object.keys(currentRequests).length < options.max_parallel_requests) { + const element = pendingRequests.pop(); + const name = stringify(element); + + callback(element, "loading"); + currentRequests[name] = executor(element).catch(e => result.failed.push({ request: element, error: e })).then(() => { + delete currentRequests[name]; + callback(element, "loaded"); }); - if(pending_requests.length == 0) break; + if(pendingRequests.length == 0) + break; } /* * Wait 'till a new "slot" for downloading is free. * This should also not throw because any errors will be caught before. */ - await Promise.race(Object.keys(current_requests).map(e => current_requests[e])); + await Promise.race(Object.keys(currentRequests).map(e => currentRequests[e])); if(result.failed.length > 0) break; /* finish loading the other requests and than show the error */ } - await Promise.all(Object.keys(current_requests).map(e => current_requests[e])); - result.skipped.push(...pending_requests); + await Promise.all(Object.keys(currentRequests).map(e => currentRequests[e])); + result.skipped.push(...pendingRequests); return result; } \ No newline at end of file diff --git a/loader/app/polifill.ts b/loader/app/polifill.ts new file mode 100644 index 00000000..3acd59a0 --- /dev/null +++ b/loader/app/polifill.ts @@ -0,0 +1,57 @@ +/* IE11 */ +if(!Element.prototype.remove) + Element.prototype.remove = function() { + this.parentElement?.removeChild(this); + }; + +function ReplaceWithPolyfill() { + let parent = this.parentNode, i = arguments.length, currentNode; + if (!parent) return; + if (!i) { parent.removeChild(this); } + while (i--) { // i-- decrements i and returns the value of i before the decrement + currentNode = arguments[i]; + if (typeof currentNode !== 'object'){ + currentNode = this.ownerDocument.createTextNode(currentNode); + } else if (currentNode.parentNode){ + currentNode.parentNode.removeChild(currentNode); + } + // the value of "i" below is after the decrement + if (!i) // if currentNode is the first argument (currentNode === arguments[0]) + parent.replaceChild(currentNode, this); + else // if currentNode isn't the first + parent.insertBefore(currentNode, this.nextSibling); + } +} +if (!Element.prototype.replaceWith) + Element.prototype.replaceWith = ReplaceWithPolyfill; + +if (!CharacterData.prototype.replaceWith) + CharacterData.prototype.replaceWith = ReplaceWithPolyfill; + +if (!DocumentType.prototype.replaceWith) + DocumentType.prototype.replaceWith = ReplaceWithPolyfill; + +// Source: https://github.com/jserz/js_piece/blob/master/DOM/ParentNode/append()/append().md +(function (arr) { + arr.forEach(function (item) { + if (item.hasOwnProperty('append')) { + return; + } + Object.defineProperty(item, 'append', { + configurable: true, + enumerable: true, + writable: true, + value: function append() { + var argArr = Array.prototype.slice.call(arguments), + docFrag = document.createDocumentFragment(); + + argArr.forEach(function (argItem) { + var isNode = argItem instanceof Node; + docFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem))); + }); + + this.appendChild(docFrag); + } + }); + }); +})([Element.prototype, Document.prototype, DocumentFragment.prototype]); \ No newline at end of file diff --git a/loader/app/targets/app.ts b/loader/app/targets/app.ts index d50cbee8..118c119b 100644 --- a/loader/app/targets/app.ts +++ b/loader/app/targets/app.ts @@ -1,5 +1,8 @@ +import "./shared"; import * as loader from "../loader/loader"; -import {config} from "../loader/loader"; +import {config, SourcePath} from "../loader/loader"; +import {script_name} from "../loader/utils"; +import { detect as detectBrowser } from "detect-browser"; declare global { interface Window { @@ -44,21 +47,18 @@ interface Manifest { }}; } +const LoaderTaskCallback = taskId => (script: SourcePath, state) => { + if(state !== "loading") + return; + + loader.setCurrentTaskName(taskId, script_name(script, false)); +}; + /* all javascript loaders */ const loader_javascript = { - load_scripts: async () => { + load_scripts: async taskId => { if(!window.require) { - await loader.scripts.load(["vendor/jquery/jquery.min.js"], { cache_tag: cache_tag() }); - } else { - /* - loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, { - name: "forum sync", - priority: 10, - function: async () => { - forum.sync_main(); - } - }); - */ + await loader.scripts.load_multiple(["vendor/jquery/jquery.min.js"], { cache_tag: cache_tag() }, LoaderTaskCallback(taskId)); } await loader.scripts.load_multiple([ @@ -71,8 +71,9 @@ const loader_javascript = { ], { cache_tag: cache_tag(), max_parallel_requests: -1 - }); + }, LoaderTaskCallback(taskId)); + loader.setCurrentTaskName(taskId, "manifest"); let manifest: Manifest; try { const response = await fetch(config.baseUrl + "js/manifest.json"); @@ -99,7 +100,7 @@ const loader_javascript = { await loader.scripts.load_multiple(manifest.chunks[chunk_name].files.map(e => "js/" + e.file), { cache_tag: undefined, max_parallel_requests: -1 - }); + }, LoaderTaskCallback(taskId)); } }; @@ -125,7 +126,7 @@ const loader_webassembly = { }; const loader_style = { - load_style: async () => { + load_style: async taskId => { const options = { cache_tag: cache_tag(), max_parallel_requests: -1 @@ -133,22 +134,24 @@ const loader_style = { await loader.style.load_multiple([ "vendor/xbbcode/src/xbbcode.css" - ], options); + ], options, LoaderTaskCallback(taskId)); + await loader.style.load_multiple([ "vendor/emoji-picker/src/jquery.lsxemojipicker.css" - ], options); + ], options, LoaderTaskCallback(taskId)); + await loader.style.load_multiple([ ["vendor/highlight/styles/darcula.css", ""], /* empty string means not required */ - ], options); + ], options, LoaderTaskCallback(taskId)); if(__build.mode === "debug") { - await loader_style.load_style_debug(); + await loader_style.load_style_debug(taskId); } else { - await loader_style.load_style_release(); + await loader_style.load_style_release(taskId); } }, - load_style_debug: async () => { + load_style_debug: async taskId => { await loader.style.load_multiple([ "css/static/main.css", "css/static/main-layout.css", @@ -196,17 +199,17 @@ const loader_style = { ], { cache_tag: cache_tag(), max_parallel_requests: -1 - }); + }, LoaderTaskCallback(taskId)); }, - load_style_release: async () => { + load_style_release: async taskId => { await loader.style.load_multiple([ "css/static/base.css", "css/static/main.css", ], { cache_tag: cache_tag(), max_parallel_requests: -1 - }); + }, LoaderTaskCallback(taskId)); } }; @@ -228,36 +231,12 @@ loader.register_task(loader.Stage.INITIALIZING, { priority: 50 }); -loader.register_task(loader.Stage.INITIALIZING, { - name: "Browser detection", - function: async () => { - navigator.browserSpecs = (function(){ - let ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; - if(/trident/i.test(M[1])){ - tem = /\brv[ :]+(\d+)/g.exec(ua) || []; - return {name:'IE',version:(tem[1] || '')}; - } - if(M[1]=== 'Chrome'){ - tem = ua.match(/\b(OPR|Edge)\/(\d+)/); - if(tem != null) return {name:tem[1].replace('OPR', 'Opera'),version:tem[2]}; - } - M = M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?']; - if((tem = ua.match(/version\/(\d+)/i))!= null) - M.splice(1, 1, tem[1]); - return {name:M[0], version:M[1]}; - })(); - - console.log("Resolved browser manufacturer to \"%s\" version \"%s\"", navigator.browserSpecs.name, navigator.browserSpecs.version); - }, - priority: 30 -}); - loader.register_task(loader.Stage.INITIALIZING, { name: "secure tester", function: async () => { /* we need https or localhost to use some things like the storage API */ if(typeof isSecureContext === "undefined") - (window)["isSecureContext"] = location.protocol !== 'https:' && location.hostname !== 'localhost'; + (window)["isSecureContext"] = location.protocol !== 'https:' || location.hostname === 'localhost'; if(!isSecureContext) { loader.critical_error("TeaWeb cant run on unsecured sides.", "App requires to be loaded via HTTPS!"); @@ -274,7 +253,7 @@ loader.register_task(loader.Stage.INITIALIZING, { }); loader.register_task(loader.Stage.JAVASCRIPT, { - name: "javascript", + name: "scripts", function: loader_javascript.load_scripts, priority: 10 }); @@ -287,7 +266,7 @@ loader.register_task(loader.Stage.STYLE, { loader.register_task(loader.Stage.TEMPLATES, { name: "templates", - function: async () => { + function: async taskId => { await loader.templates.load_multiple([ "templates.html", "templates/modal/musicmanage.html", @@ -295,17 +274,11 @@ loader.register_task(loader.Stage.TEMPLATES, { ], { cache_tag: cache_tag(), max_parallel_requests: -1 - }); + }, LoaderTaskCallback(taskId)); }, priority: 10 }); -loader.register_task(loader.Stage.LOADED, { - name: "loaded handler", - function: async () => loader.hide_overlay(), - priority: 5 -}); - loader.register_task(loader.Stage.JAVASCRIPT_INITIALIZING, { name: "lsx emoji picker setup", function: async () => await (window as any).setup_lsx_emoji_picker({twemoji: typeof(window.twemoji) !== "undefined"}), @@ -368,8 +341,6 @@ loader.register_task(loader.Stage.SETUP, { }); export function run() { - window["Module"] = (window["Module"] || {}) as any; /* Why? */ - /* TeaClient */ if(node_require) { if(__build.target !== "client") { diff --git a/loader/app/targets/certaccept.ts b/loader/app/targets/certaccept.ts index 794240c6..21a7e20d 100644 --- a/loader/app/targets/certaccept.ts +++ b/loader/app/targets/certaccept.ts @@ -71,12 +71,6 @@ loader.register_task(loader.Stage.STYLE, { priority: 10 }); -loader.register_task(loader.Stage.LOADED, { - name: "loaded handler", - function: async () => loader.hide_overlay(), - priority: 0 -}); - /* register tasks */ loader.register_task(loader.Stage.INITIALIZING, { name: "safari fix", diff --git a/loader/app/targets/empty.ts b/loader/app/targets/empty.ts new file mode 100644 index 00000000..45172a62 --- /dev/null +++ b/loader/app/targets/empty.ts @@ -0,0 +1,27 @@ +import "./shared"; +import * as loader from "../loader/loader"; +import {Stage} from "../loader/loader"; + +export function run() { + loader.register_task(Stage.JAVASCRIPT_INITIALIZING, { + name: "doing nothing", + priority: 1, + function: async taskId => { + console.log("Doing nothing"); + + for(let index of [1, 2, 3]) { + await new Promise(resolve => { + const callback = () => { + document.removeEventListener("click", resolve); + resolve(); + }; + + document.addEventListener("click", callback); + }); + loader.setCurrentTaskName(taskId, "try again (" + index + ")"); + } + } + }); + + loader.execute_managed(); +} \ No newline at end of file diff --git a/loader/app/targets/shared.ts b/loader/app/targets/shared.ts new file mode 100644 index 00000000..cb5f1ddb --- /dev/null +++ b/loader/app/targets/shared.ts @@ -0,0 +1,38 @@ +import * as loader from "../loader/loader"; +import {Stage} from "../loader/loader"; +import {detect as detectBrowser} from "detect-browser"; + +if(__build.target === "web") { + loader.register_task(Stage.SETUP, { + name: "outdated browser checker", + function: async () => { + const browser = detectBrowser(); + navigator.browserSpecs = browser; + + if(!browser) + return; + + console.log("Resolved browser manufacturer to \"%s\" version \"%s\" on %s", browser.name, browser.version, browser.os); + if(browser.type && browser.type !== "browser") { + loader.critical_error("Your device isn't supported.", "User agent type " + browser.type + " isn't supported."); + throw "unsupported user type"; + } + + switch (browser?.name) { + case "aol": + case "bot": + case "crios": + case "ie": + loader.critical_error("Browser not supported", "We're sorry, but your browser isn't supported."); + throw "unsupported browser"; + + } + }, + priority: 50 + }); +} + +/* directly disable all context menus */ //disableGlobalContextMenu +if(!location.search.match(/(.*[?&]|^)disableGlobalContextMenu=1($|&.*)/)) { + document.addEventListener("contextmenu", event => event.preventDefault()); +} \ No newline at end of file diff --git a/loader/css/index.scss b/loader/css/index.scss new file mode 100644 index 00000000..20a076b6 --- /dev/null +++ b/loader/css/index.scss @@ -0,0 +1,7 @@ +body { + padding: 0; + margin: 0; +} + +@import "loader"; +@import "overlay"; diff --git a/loader/css/loader.scss b/loader/css/loader.scss index f9ec5b67..76d5780a 100644 --- a/loader/css/loader.scss +++ b/loader/css/loader.scss @@ -1,331 +1,186 @@ -$thickness: 5px; -$duration: 2500; -$delay: $duration/6; -$background: #222222; +$setup-time: 80s / 24; /* 24 frames / sec; the initial sequence is 80 seconds */ -@mixin polka($size, $dot, $base, $accent) { - background: $base; - background-image: radial-gradient($accent $dot, transparent 0); - background-size: $size $size; - background-position: 0 -2.5px; -} - -.loader { - margin: 0; - - display: block; - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - - z-index: 900; - text-align: center; -} - -.loader .half { - position: fixed; - background: #222222; - top: 0; - bottom: 0; - width: 50%; - height: 100%; -} - -.loader .half.right { - right: 0; -} - -.loader .half.left { - left: 0; -} - -.bookshelf_wrapper { - position: relative; - top: 40%; - left: 50%; - transform: translate(-50%, -50%); -} - -.books_list { - margin: 0 auto; - width: 300px; - padding: 0; -} - -.book_item { +#loader-overlay { position: absolute; - top: -120px; - box-sizing: border-box; - list-style: none; - width: 40px; - height: 120px; - opacity: 0; - background-color: #1e6cc7; - border: $thickness solid white; - transform-origin: bottom left; - transform: translateX(300px); - animation: travel #{$duration}ms linear infinite; + overflow: hidden; - &.first { - top: -140px; - height: 140px; + top: 0; + left: 0; + right: 0; + bottom: 0; - &:before, - &:after { - content: ''; - position: absolute; - top: 10px; - left: 0; - width: 100%; - height: $thickness; - background-color: white; - } + background: #1e1e1e; - &:after { - top: initial; - bottom: 10px; - } + user-select: none; + + z-index: 10000; + + display: flex; + flex-direction: column; + justify-content: center; + + .container { + flex-shrink: 0; + + display: block; + position: relative; + + width: 1000px; + height: 1000px; + + align-self: center; + margin-bottom: 10vh; + + transition-duration: .5s; } - &.second, - &.fifth { - &:before, - &:after { - box-sizing: border-box; - content: ''; - position: absolute; - top: 10px; - left: 0; - width: 100%; - height: $thickness*3.5; - border-top: $thickness solid white; - border-bottom: $thickness solid white; - } - - &:after { - top: initial; - bottom: 10px; - } - } - - &.third { - &:before, - &:after { - box-sizing: border-box; - content: ''; - position: absolute; - top: 10px; - left: 9px; - width: 12px; - height: 12px; - border-radius: 50%; - border: $thickness solid white; - } - - &:after { - top: initial; - bottom: 10px; - } - } - - &.fourth { - top: -130px; - height: 130px; - - &:before { - box-sizing: border-box; - content: ''; - position: absolute; - top: 46px; - left: 0; - width: 100%; - height: $thickness*3.5; - border-top: $thickness solid white; - border-bottom: $thickness solid white; - } - } - - &.fifth { - top: -100px; - height: 100px; - } - - &.sixth { - top: -140px; - height: 140px; - - &:before { - box-sizing: border-box; - content: ''; - position: absolute; - bottom: 31px; - left: 0px; - width: 100%; - height: $thickness; - background-color: white; - } - - &:after { - box-sizing: border-box; - content: ''; - position: absolute; - bottom: 10px; - left: 9px; - width: 12px; - height: 12px; - border-radius: 50%; - border: $thickness solid white; - } - } - - &:nth-child(2) { - animation-delay: #{$delay*1}ms; - } - - &:nth-child(3) { - animation-delay: #{$delay*2}ms; - } - - &:nth-child(4) { - animation-delay: #{$delay*3}ms; - } - - &:nth-child(5) { - animation-delay: #{$delay*4}ms; - } - - &:nth-child(6) { - animation-delay: #{$delay*5}ms; - } - -} - -.shelf { - width: 300px; - height: $thickness; - margin: 0 auto; - background-color: white; - position: relative; - - &:before, - &:after { - content: ''; + .setup, .idle { position: absolute; - width: 100%; - height: 100%; - @include polka(10px, 30%, $background, rgba(255, 255, 255, 0.5)); - top: 200%; - left: 5%; - animation: move #{$duration/10}ms linear infinite; + + top: 0; + left: 0; + right: 0; + bottom: 0; + + display: none; + + &.visible { + display: block; + } } - &:after { - top: 400%; - left: 7.5%; + .setup.visible { + animation: loader-initial-sequence 0s cubic-bezier(.81,.01,.65,1.16) $setup-time forwards; } + .idle { + img { + position: absolute; + } + + .steam { + position: absolute; + + top: 282px; + left: 380px; + + width: 249px; + height: 125px; + background: url("../img/loader/steam.png") 0 0; + + animation: sprite-steam 2.5s steps(50) forwards infinite; + } + } + + &.finishing { + .idle { + .steam { + display: none; + } + + .bowl { + animation: swipe-out-bowl .5s both; + } + + .text { + animation: swipe-out-text .5s .12s both; + } + } + + pointer-events: none; + animation: overlay-fade .3s .2s both; + } + + .loader-stage { + position: absolute; + + left: 5px; + bottom: 5px; + + font-size: 12px; + font-family: monospace; + + color: #999; + } } -@keyframes move { +@media all and (max-width: 850px) { + #loader-overlay .container { + transform: scale(.5); + } +} +@media all and (max-height: 700px) { + #loader-overlay .container { + transform: scale(.5); + } +} + +@media all and (max-width: 400px) { + #loader-overlay .container { + transform: scale(.3); + } +} + +@keyframes loader-initial-sequence { + to { + display: none; + } +} + +@keyframes sprite-steam { + to { + background-position: 0 -6250px; + } +} + +@keyframes swipe-out-bowl { from { - background-position-x: 0; + transform: translate3d(0, 0, 0); + } + + 40% { + opacity: 1; + transform: translate3d(-60px, 0, 0) skew(-5deg, 0) rotateY(-6deg); } to { - background-position-x: 10px; + opacity: 0; + transform: translate3d(700px, 0, 0) skew(30deg, 0) rotateZ(-6deg); } - } -@keyframes travel { - - 0% { - opacity: 0; - transform: translateX(300px) rotateZ(0deg) scaleY(1); +@keyframes swipe-out-text { + from { + transform: translate3d(0, 0, 0); } - 6.5% { - transform: translateX(279.5px) rotateZ(0deg) scaleY(1.1); - } - - 8.8% { - transform: translateX(273.6px) rotateZ(0deg) scaleY(1); - } - - 10% { + 40% { opacity: 1; - transform: translateX(270px) rotateZ(0deg); + transform: translate3d(-30px, 20px, 0) skew(-5deg, 0); } - 17.6% { - transform: translateX(247.2px) rotateZ(-30deg); + to { + opacity: 0; + transform: translate3d(550px, 0, 0) skew(30deg, 0) scale(.96, 1.25) rotateZ(6deg); } +} - 45% { - transform: translateX(165px) rotateZ(-30deg); - } - - 49.5% { - transform: translateX(151.5px) rotateZ(-45deg); - } - - 61.5% { - transform: translateX(115.5px) rotateZ(-45deg); - } - - 67% { - transform: translateX(99px) rotateZ(-60deg); - } - - 76% { - transform: translateX(72px) rotateZ(-60deg); - } - - 83.5% { - opacity: 1; - transform: translateX(49.5px) rotateZ(-90deg); - } - - 90% { +@keyframes overlay-fade { + to { opacity: 0; } - - 100% { - opacity: 0; - transform: translateX(0px) rotateZ(-90deg); - } - } /* Automated loader timeout */ -$loader_timeout: 2.5s; -.loader:not(.started) { - &, & > .half, & > .bookshelf_wrapper { - -moz-animation: _loader_hide 0s ease-in $loader_timeout forwards; - -webkit-animation: _loader_hide 0s ease-in $loader_timeout forwards; - -o-animation: _loader_hide 0s ease-in $loader_timeout forwards; - animation: _loader_hide 0s ease-in $loader_timeout forwards; - -webkit-animation-fill-mode: forwards; - animation-fill-mode: forwards; - } -} - -.loader:not(.started) + #critical-load { +#loader-overlay:not(.initialized) + #critical-load { display: block !important; opacity: 0; - -moz-animation: _loader_show 0s ease-in $loader_timeout forwards; - -webkit-animation: _loader_show 0s ease-in $loader_timeout forwards; - -o-animation: _loader_show 0s ease-in $loader_timeout forwards; - animation: _loader_show 0s ease-in $loader_timeout forwards; - -webkit-animation-fill-mode: forwards; - animation-fill-mode: forwards; + animation: loader-setup-timeout 0s ease-in $setup-time forwards; .error::before { - content: 'Failed to startup app loader!'; + content: 'Failed to startup loader!'; } .detail::before { @@ -333,29 +188,8 @@ $loader_timeout: 2.5s; } } -@keyframes _loader_hide { - to { - width: 0; - height: 0; - overflow: hidden; - } -} -@-webkit-keyframes _loader_hide { - to { - width: 0; - height: 0; - visibility: hidden; - } -} - -@keyframes _loader_show { - to { - opacity: 1; - } -} - -@-webkit-keyframes _loader_show { +@keyframes loader-setup-timeout { to { opacity: 1; } diff --git a/loader/css/overlay.scss b/loader/css/overlay.scss new file mode 100644 index 00000000..f348ba1a --- /dev/null +++ b/loader/css/overlay.scss @@ -0,0 +1,58 @@ +#overlay-no-js, #critical-load { + z-index: 10000; + display: none; + position: fixed; + + top: 0; + bottom: 0; + left: 0; + right: 0; + + background: #1e1e1e; + text-align: center; + + .container { + position: relative; + display: inline-block; + + top: 20%; + } + + &.shown { + display: block; + } +} + +#critical-load { + img { + height: 12em + } + + .error { + color: #bd1515; + margin-bottom: 0 + } + + .detail { + color: #696363; + margin-top: .5em + } +} + + +@media (max-height: 750px) { + #critical-load .container { + top: unset; + } + + #critical-load { + font-size: .8rem; + + flex-direction: column; + justify-content: center; + } + + #critical-load.shown { + display: flex; + } +} \ No newline at end of file diff --git a/loader/html/index.html.ejs b/loader/html/index.html.ejs new file mode 100644 index 00000000..81b33761 --- /dev/null +++ b/loader/html/index.html.ejs @@ -0,0 +1,111 @@ +<% +/* given on compile time */ +var build_target; +var initial_script; +var initial_css; +%> + + + + + + + + + + + + + <%# TODO: Put in an appropirate image %> + + <%# Using an absolute path here since the manifest.json works only with such. %> + + + <% if(build_target === "client") { %> + TeaClient + + <% } else { %> + TeaSpeak-Web + + + <%# %> + <% } %> + + + + + + + + + + + <%# We're preloading the PNG file by default since most browser have APNG support %> + + + <%# We don't preload the bowl since it's only a div background %> + + + <%- initial_css %> + + + + + + +
+
+ + +
+
+
+ +
+
+ + +
+
+
+ +
+
+ + +
+
+ load error + +

+

+
+
+ + <%- initial_script %> + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index dbe8dfc8..404f2eab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,1072 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/compat-data": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.4.tgz", + "integrity": "sha512-t+rjExOrSVvjQQXNp5zAIYDp00KjdvGl/TpDX5REPr0S9IAIPQMTilcfG6q8c0QFmj9lSTVySV2VTsyggvtNIw==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "@babel/core": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.4.tgz", + "integrity": "sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "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" + } + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "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 + } + } + }, + "@babel/generator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", + "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", + "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz", + "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", + "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.10.4", + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.4.tgz", + "integrity": "sha512-9raUiOsXPxzzLjCXeosApJItoMnX3uyT4QdM2UldffuGApNrF8e938MwNpDCK9CPoyxrEoCgT+hObJc3mZa6lQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz", + "integrity": "sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-regex": "^7.10.4", + "regexpu-core": "^4.7.0" + } + }, + "@babel/helper-define-map": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.4.tgz", + "integrity": "sha512-nIij0oKErfCnLUCWaCaHW0Bmtl2RO9cN7+u2QT8yqTywgALKlyUVOvHDElh+b5DwVC6YB1FOYFOTWcN/+41EDA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/types": "^7.10.4", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz", + "integrity": "sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A==", + "dev": true, + "requires": { + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", + "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", + "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz", + "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", + "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", + "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", + "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz", + "integrity": "sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.4.tgz", + "integrity": "sha512-inWpnHGgtg5NOF0eyHlC0/74/VkdRITY9dtTpB2PrxKKn+AkVMRiZz/Adrx+Ssg+MLDesi2zohBW6MVq6b4pOQ==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz", + "integrity": "sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-wrap-function": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz", + "integrity": "sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz", + "integrity": "sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz", + "integrity": "sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", + "integrity": "sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/helpers": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.4.tgz", + "integrity": "sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "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" + } + }, + "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" + } + } + } + }, + "@babel/parser": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", + "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.4.tgz", + "integrity": "sha512-MJbxGSmejEFVOANAezdO39SObkURO5o/8b6fSH6D1pi9RZQt+ldppKPXfqgUWpSQ9asM6xaSaSJIaeWMDRP0Zg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.10.4", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", + "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", + "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", + "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", + "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", + "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.4.tgz", + "integrity": "sha512-6vh4SqRuLLarjgeOf4EaROJAHjvu9Gl+/346PbDH9yWbJyfnJ/ah3jmYKYtswEyCoWZiidvVHjHshd4WgjB9BA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.10.4" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", + "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.4.tgz", + "integrity": "sha512-ZIhQIEeavTgouyMSdZRap4VPPHqJJ3NEs2cuHs5p0erH+iz6khB0qfgU8g7UuJkG88+fBMy23ZiU+nuHvekJeQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz", + "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz", + "integrity": "sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz", + "integrity": "sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz", + "integrity": "sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", + "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", + "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.10.4" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", + "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.4.tgz", + "integrity": "sha512-J3b5CluMg3hPUii2onJDRiaVbPtKFPLEaV5dOPY5OeAbDi1iU/UbbFFTgwb7WnanaDy7bjU35kc26W3eM5Qa0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", + "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-define-map": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", + "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", + "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz", + "integrity": "sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", + "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", + "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", + "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", + "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", + "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", + "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.4.tgz", + "integrity": "sha512-3Fw+H3WLUrTlzi3zMiZWp3AR4xadAEMv6XRCYnd5jAlLM61Rn+CRJaZMaNvIpcJpQ3vs1kyifYvEVPFfoSkKOA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", + "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.4.tgz", + "integrity": "sha512-Tb28LlfxrTiOTGtZFsvkjpyjCl9IoaRI52AEU/VIwOwvDQWtbNJsAqTXzh+5R7i74e/OZHH2c2w2fsOqAfnQYQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.10.4", + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", + "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", + "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", + "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", + "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.4.tgz", + "integrity": "sha512-RurVtZ/D5nYfEg0iVERXYKEgDFeesHrHfx8RT05Sq57ucj2eOYAP6eu5fynL4Adju4I/mP/I6SO0DqNWAXjfLQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", + "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", + "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", + "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.4.tgz", + "integrity": "sha512-8ULlGv8p+Vuxu+kz2Y1dk6MYS2b/Dki+NO6/0ZlfSj5tMalfDL7jI/o/2a+rrWLqSXvnadEqc2WguB4gdQIxZw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", + "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.4.tgz", + "integrity": "sha512-1e/51G/Ni+7uH5gktbWv+eCED9pP8ZpRhZB3jOaI3mmzfvJTWHkuyYTv0Z5PYtyM+Tr2Ccr9kUdQxn60fI5WuQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", + "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-regex": "^7.10.4" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.4.tgz", + "integrity": "sha512-4NErciJkAYe+xI5cqfS8pV/0ntlY5N5Ske/4ImxAVX7mk9Rxt2bwDTGv1Msc2BRJvWQcmYEC+yoMLdX22aE4VQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", + "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz", + "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", + "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/preset-env": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.4.tgz", + "integrity": "sha512-tcmuQ6vupfMZPrLrc38d0sF2OjLT3/bZ0dry5HchNCQbrokoQi4reXqclvkkAT5b+gWc23meVWpve5P/7+w/zw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.10.4", + "@babel/helper-compilation-targets": "^7.10.4", + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-proposal-async-generator-functions": "^7.10.4", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/plugin-proposal-dynamic-import": "^7.10.4", + "@babel/plugin-proposal-json-strings": "^7.10.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", + "@babel/plugin-proposal-numeric-separator": "^7.10.4", + "@babel/plugin-proposal-object-rest-spread": "^7.10.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", + "@babel/plugin-proposal-optional-chaining": "^7.10.4", + "@babel/plugin-proposal-private-methods": "^7.10.4", + "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-class-properties": "^7.10.4", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.10.4", + "@babel/plugin-transform-arrow-functions": "^7.10.4", + "@babel/plugin-transform-async-to-generator": "^7.10.4", + "@babel/plugin-transform-block-scoped-functions": "^7.10.4", + "@babel/plugin-transform-block-scoping": "^7.10.4", + "@babel/plugin-transform-classes": "^7.10.4", + "@babel/plugin-transform-computed-properties": "^7.10.4", + "@babel/plugin-transform-destructuring": "^7.10.4", + "@babel/plugin-transform-dotall-regex": "^7.10.4", + "@babel/plugin-transform-duplicate-keys": "^7.10.4", + "@babel/plugin-transform-exponentiation-operator": "^7.10.4", + "@babel/plugin-transform-for-of": "^7.10.4", + "@babel/plugin-transform-function-name": "^7.10.4", + "@babel/plugin-transform-literals": "^7.10.4", + "@babel/plugin-transform-member-expression-literals": "^7.10.4", + "@babel/plugin-transform-modules-amd": "^7.10.4", + "@babel/plugin-transform-modules-commonjs": "^7.10.4", + "@babel/plugin-transform-modules-systemjs": "^7.10.4", + "@babel/plugin-transform-modules-umd": "^7.10.4", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", + "@babel/plugin-transform-new-target": "^7.10.4", + "@babel/plugin-transform-object-super": "^7.10.4", + "@babel/plugin-transform-parameters": "^7.10.4", + "@babel/plugin-transform-property-literals": "^7.10.4", + "@babel/plugin-transform-regenerator": "^7.10.4", + "@babel/plugin-transform-reserved-words": "^7.10.4", + "@babel/plugin-transform-shorthand-properties": "^7.10.4", + "@babel/plugin-transform-spread": "^7.10.4", + "@babel/plugin-transform-sticky-regex": "^7.10.4", + "@babel/plugin-transform-template-literals": "^7.10.4", + "@babel/plugin-transform-typeof-symbol": "^7.10.4", + "@babel/plugin-transform-unicode-escapes": "^7.10.4", + "@babel/plugin-transform-unicode-regex": "^7.10.4", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.10.4", + "browserslist": "^4.12.0", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", + "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/runtime": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.4.tgz", + "integrity": "sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", + "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } + }, + "@babel/traverse": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", + "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", + "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, "@google-cloud/common": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.4.0.tgz", @@ -1098,6 +2164,72 @@ "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", "dev": true }, + "babel-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "dev": true, + "requires": { + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.4.0", + "mkdirp": "^0.5.3", + "pify": "^4.0.1", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, "bach": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", @@ -1477,6 +2609,18 @@ "pako": "~1.0.5" } }, + "browserslist": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.13.0.tgz", + "integrity": "sha512-MINatJ5ZNrLnQ6blGvePd/QOz9Xtu+Ne+x29iQSCHfkU5BugKVJwZKn/iiL8UbpIpa3JhviKjz+XxMo0m2caFQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001093", + "electron-to-chromium": "^1.3.488", + "escalade": "^3.0.1", + "node-releases": "^1.1.58" + } + }, "buffer": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", @@ -1646,6 +2790,12 @@ "resolved": "https://registry.npmjs.org/can-use-dom/-/can-use-dom-0.1.0.tgz", "integrity": "sha1-IsxKNKCrxDlQ9CxkEQJKP2NmtFo=" }, + "caniuse-lite": { + "version": "1.0.30001099", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001099.tgz", + "integrity": "sha512-sdS9A+sQTk7wKoeuZBN/YMAHVztUfVnjDi4/UV3sDE8xoh7YR12hKW+pIdB3oqKGwr9XaFL2ovfzt9w8eUI5CA==", + "dev": true + }, "capture-stack-trace": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", @@ -2104,6 +3254,24 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" }, + "core-js-compat": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", + "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -2533,6 +3701,11 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", "dev": true }, + "detect-browser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.1.1.tgz", + "integrity": "sha512-5n2aWI57qC3kZaK4j2zYsG6L1LrxgLptGCNhMQgdKhVn6cSdcq43pp6xHPfTHG3TYM6myF4tIPWiZtfdVDgb9w==" + }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -2716,6 +3889,12 @@ "integrity": "sha512-IncmUpn1yN84hy2shb0POJ80FWrfGNY0cxO9f4v+/sG7qcBvAtVWUA1IdzY/8EYUmOVhoKJVdJjNd3AZcnxOjA==", "dev": true }, + "electron-to-chromium": { + "version": "1.3.496", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.496.tgz", + "integrity": "sha512-TXY4mwoyowwi4Lsrq9vcTUYBThyc1b2hXaTZI13p8/FRhY2CTaq5lK+DVjhYkKiTLsKt569Xes+0J5JsVXFurQ==", + "dev": true + }, "elliptic": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", @@ -2873,6 +4052,12 @@ "es6-symbol": "^3.1.1" } }, + "escalade": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.1.tgz", + "integrity": "sha512-DR6NO3h9niOT+MZs7bjxlj2a1k+POu5RN8CLTPX2+i78bRi9eLe7+0zXgUHMnGXWybYcL61E9hGhPKqedy8tQA==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -2985,6 +4170,12 @@ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -4736,6 +5927,12 @@ "json-bigint": "^0.3.0" } }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -5265,6 +6462,12 @@ "which": "^1.2.14" } }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "globby": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", @@ -6024,6 +7227,15 @@ "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", "dev": true }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -6465,6 +7677,12 @@ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json-bigint": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", @@ -6624,6 +7842,21 @@ "flush-write-stream": "^1.0.2" } }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, "liftoff": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", @@ -7716,6 +8949,12 @@ } } }, + "node-releases": { + "version": "1.1.59", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.59.tgz", + "integrity": "sha512-H3JrdUczbdiwxN5FuJPyCHnGHIFqQ0wWxo+9j1kAXAzqNMAHlo+4I/sYYxpyK0irQ73HgdiyzD32oqQDcU2Osw==", + "dev": true + }, "node-sass": { "version": "4.13.1", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.1.tgz", @@ -9170,6 +10409,36 @@ "strip-indent": "^1.0.1" } }, + "regenerate": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", + "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", + "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", @@ -9189,6 +10458,20 @@ "safe-regex": "^1.1.0" } }, + "regexpu-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, "registry-auth-token": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", @@ -9208,6 +10491,29 @@ "rc": "^1.0.1" } }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -10606,6 +11912,12 @@ "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", @@ -11176,6 +12488,34 @@ "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", "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.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", diff --git a/package.json b/package.json index 510ab91f..f81eb8fd 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,9 @@ "author": "TeaSpeak (WolverinDEV)", "license": "ISC", "devDependencies": { + "@babel/core": "^7.10.4", + "@babel/plugin-transform-runtime": "^7.10.4", + "@babel/preset-env": "^7.10.4", "@google-cloud/translate": "^5.3.0", "@types/dompurify": "^2.0.1", "@types/ejs": "^3.0.2", @@ -38,6 +41,7 @@ "@types/react-dom": "^16.9.5", "@types/sha256": "^0.2.0", "@types/websocket": "0.0.40", + "babel-loader": "^8.1.0", "chunk-manifest-webpack-plugin": "^1.1.2", "circular-dependency-plugin": "^5.2.0", "clean-css": "^4.2.1", @@ -81,6 +85,7 @@ }, "homepage": "https://www.teaspeak.de", "dependencies": { + "detect-browser": "^5.1.1", "dompurify": "^2.0.8", "moment": "^2.24.0", "react": "^16.13.1", diff --git a/shared/html/index.html.ejs b/shared/html/index.html.ejs deleted file mode 100644 index 4095f9f2..00000000 --- a/shared/html/index.html.ejs +++ /dev/null @@ -1,220 +0,0 @@ -<% -/* given build compile */ -var build_target; -var initial_script; -var initial_css; -%> - - - - - - - - - - - - - - - - - - - <% if(build_target === "client") { %> - TeaClient - - <% } else { %> - TeaSpeak-Web - - - - <% } %> - - - - - - - - - - - - - - <%- initial_css %> - - - - - - -
-
- - -
-
-
-
-
    -
  • -
  • -
  • -
  • -
  • -
  • -
-
-
-
- - -
-
- - -

-

-
-
- -<%# - -
- - - - - - - - - - - - - - - - - - - - - - - - -
- - -%> - <%- initial_script %> - - \ No newline at end of file diff --git a/shared/js/main.tsx b/shared/js/main.tsx index 504003a9..f62ef964 100644 --- a/shared/js/main.tsx +++ b/shared/js/main.tsx @@ -34,8 +34,6 @@ import {spawnFileTransferModal} from "tc-shared/ui/modal/transfer/ModalFileTrans import {MenuEntryType, spawn_context_menu} from "tc-shared/ui/elements/ContextMenu"; import {copy_to_clipboard} from "tc-shared/utils/helpers"; import ContextMenuEvent = JQuery.ContextMenuEvent; -import {spawnPermissionEditorModal} from "tc-shared/ui/modal/permission/ModalPermissionEditor"; -import {spawnGroupCreate} from "tc-shared/ui/modal/ModalGroups"; /* required import for init */ require("./proto").initialize(); diff --git a/tsbaseconfig.json b/tsbaseconfig.json index 2d9d3f12..17fc34fd 100644 --- a/tsbaseconfig.json +++ b/tsbaseconfig.json @@ -18,9 +18,11 @@ "webpack/WatLoader.ts", "webpack/DevelBlocks.ts", + "loader/IndexGenerator.ts", + "file.ts" ], "exclude": [ - "node_modules", + "node_modules" ] } \ No newline at end of file diff --git a/webpack.config.ts b/webpack.config.ts index e6029a7b..1fb3e740 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -3,7 +3,7 @@ import * as fs from "fs"; import trtransformer from "./tools/trgen/ts_transformer"; import {exec} from "child_process"; import * as util from "util"; -import EJSGenerator = require("./webpack/EJSGenerator"); +import LoaderIndexGenerator = require("./loader/IndexGenerator"); const path = require('path'); const webpack = require("webpack"); @@ -44,6 +44,16 @@ const generate_definitions = async (target: string) => { } as any; }; +const isLoaderFile = (file: string) => { + if(file.startsWith(__dirname)) { + const path = file.substr(__dirname.length).replace(/\\/g, "/"); + if(path.startsWith("/loader/")) { + return true; + } + } + return false; +}; + export const config = async (target: "web" | "client") => { return { entry: { "loader": "./loader/app/index.ts" @@ -77,21 +87,10 @@ export const config = async (target: "web" | "client") => { return { }), new webpack.DefinePlugin(await generate_definitions(target)), - new EJSGenerator({ - variables: { - build_target: target - }, - input: path.join(__dirname, "shared/html/index.html.ejs"), + new LoaderIndexGenerator({ + buildTarget: target, output: path.join(__dirname, "dist/index.html"), - initialJSEntryChunk: "loader", - minify: !isDevelopment, - embedInitialJSEntryChunk: !isDevelopment, - - embedInitialCSSFile: !isDevelopment, - initialCSSFile: { - localFile: path.join(__dirname, "loader/css/loader.css"), - publicFile: "css/loader.css" - } + isDevelopment: isDevelopment }) ].filter(e => !!e), module: { @@ -127,7 +126,7 @@ export const config = async (target: "web" | "client") => { return { ] }, { - test: /\.tsx?$/, + test: (module: string) => module.match(/\.tsx?$/) && !isLoaderFile(module), exclude: /node_modules/, loader: [ @@ -154,6 +153,25 @@ export const config = async (target: "web" | "client") => { return { } ] }, + { + test: (module: string) => module.match(/\.tsx?$/) && isLoaderFile(module), + exclude: /(node_modules|bower_components)/, + + loader: [ + { + loader: "babel-loader", + options: { + presets: ["@babel/preset-env"] //Preset used for env setup + } + }, + { + loader: "ts-loader", + options: { + transpileOnly: true + } + } + ] + }, { test: /\.was?t$/, loader: [ diff --git a/webpack/EJSGenerator.ts b/webpack/EJSGenerator.ts index 4d20b907..8ebeb8dd 100644 --- a/webpack/EJSGenerator.ts +++ b/webpack/EJSGenerator.ts @@ -31,31 +31,34 @@ class EJSGenerator { this.options = options; } - private async generate_entry_js_tag(compilation: Compilation) { + private async generateEntryJsTag(compilation: Compilation) { const entry_group = compilation.chunkGroups.find(e => e.options.name === this.options.initialJSEntryChunk); if(!entry_group) return; /* not the correct compilation */ - if(entry_group.chunks.length !== 1) throw "Unsupported entry chunk size. We only support one at the moment."; - if(entry_group.chunks[0].files.length !== 1) - throw "Entry chunk has too many files. We only support to inline one!"; - const file = entry_group.chunks[0].files[0]; - if(path.extname(file) !== ".js") - throw "Entry chunk file has unknown extension"; - if(!this.options.embedInitialJSEntryChunk) { - return ''; - } else { - const script = await util.promisify(fs.readFile)(path.join(compilation.compiler.outputPath, file)); - return ``; - } + const tags = entry_group.chunks.map(chunk => { + if(chunk.files.length !== 1) + throw "invalid chunk file count"; + + const file = chunk.files[0]; + if(path.extname(file) !== ".js") + throw "Entry chunk file has unknown extension"; + + if(!this.options.embedInitialJSEntryChunk) { + return ''; + } else { + const script = fs.readFileSync(path.join(compilation.compiler.outputPath, file)); + return ``; + } + }); + return tags.join("\n"); } - private async generate_entry_css_tag() { + private async generateEntryCssTag() { if(this.options.embedInitialCSSFile) { const style = await util.promisify(fs.readFile)(this.options.initialCSSFile.localFile); return `` } else { - // - return `` + return `` } } @@ -64,11 +67,12 @@ class EJSGenerator { const input = await util.promisify(fs.readFile)(this.options.input); const variables = Object.assign({}, this.options.variables); - variables["initial_script"] = await this.generate_entry_js_tag(compilation); - variables["initial_css"] = await this.generate_entry_css_tag(); + variables["initial_script"] = await this.generateEntryJsTag(compilation); + variables["initial_css"] = await this.generateEntryCssTag(); let generated = await ejs.render(input.toString(), variables, { - beautify: false /* uglify is a bit dump and does not understands ES6 */ + beautify: false, /* uglify is a bit dump and does not understands ES6 */ + context: this }); if(this.options.minify) { @@ -82,12 +86,21 @@ class EJSGenerator { removeTagWhitespace: true, minifyCSS: true, minifyJS: true, - minifyURLs: true + minifyURLs: true, }); } await util.promisify(fs.writeFile)(this.options.output, generated); }); + + compiler.hooks.afterCompile.tapPromise(this.constructor.name, async compilation => { + const file = path.resolve(this.options.input); + if(compilation.fileDependencies.has(file)) + return; + + console.log("Adding additional watch to %s", file); + compilation.fileDependencies.add(file); + }); } }