From a785fede52259495887714f972828234e78ffced Mon Sep 17 00:00:00 2001 From: Omar Zapata Date: Tue, 23 Nov 2021 16:17:38 +0100 Subject: [PATCH 1/5] Added SwanFileBrowser extension for jupyterlab 3.0.x --- SwanFileBrowser/MANIFEST.in | 24 + SwanFileBrowser/README.md | 3 + SwanFileBrowser/install.json | 5 + SwanFileBrowser/package.json | 95 + SwanFileBrowser/pyproject.toml | 17 + SwanFileBrowser/schema/browser.json | 28 + SwanFileBrowser/setup.py | 89 + SwanFileBrowser/src/icons.ts | 8 + SwanFileBrowser/src/index.ts | 1181 ++++++ SwanFileBrowser/src/kernelspec/validate.ts | 198 + SwanFileBrowser/src/listing.ts | 2390 +++++++++++ SwanFileBrowser/src/request.ts | 34 + SwanFileBrowser/src/svg.d.ts | 6 + SwanFileBrowser/src/swanfilebrowser.ts | 261 ++ SwanFileBrowser/style/base.css | 0 SwanFileBrowser/style/index.css | 5 + SwanFileBrowser/style/index.js | 1 + SwanFileBrowser/style/project_folder.svg | 54 + SwanFileBrowser/swanfilebrowser/__init__.py | 17 + SwanFileBrowser/swanfilebrowser/_version.py | 18 + SwanFileBrowser/tsconfig.json | 24 + SwanFileBrowser/typedoc.json | 6 + SwanFileBrowser/yarn.lock | 4057 +++++++++++++++++++ 23 files changed, 8521 insertions(+) create mode 100644 SwanFileBrowser/MANIFEST.in create mode 100644 SwanFileBrowser/README.md create mode 100644 SwanFileBrowser/install.json create mode 100644 SwanFileBrowser/package.json create mode 100644 SwanFileBrowser/pyproject.toml create mode 100644 SwanFileBrowser/schema/browser.json create mode 100644 SwanFileBrowser/setup.py create mode 100644 SwanFileBrowser/src/icons.ts create mode 100644 SwanFileBrowser/src/index.ts create mode 100644 SwanFileBrowser/src/kernelspec/validate.ts create mode 100644 SwanFileBrowser/src/listing.ts create mode 100644 SwanFileBrowser/src/request.ts create mode 100644 SwanFileBrowser/src/svg.d.ts create mode 100755 SwanFileBrowser/src/swanfilebrowser.ts create mode 100644 SwanFileBrowser/style/base.css create mode 100644 SwanFileBrowser/style/index.css create mode 100644 SwanFileBrowser/style/index.js create mode 100644 SwanFileBrowser/style/project_folder.svg create mode 100644 SwanFileBrowser/swanfilebrowser/__init__.py create mode 100644 SwanFileBrowser/swanfilebrowser/_version.py create mode 100644 SwanFileBrowser/tsconfig.json create mode 100644 SwanFileBrowser/typedoc.json create mode 100644 SwanFileBrowser/yarn.lock diff --git a/SwanFileBrowser/MANIFEST.in b/SwanFileBrowser/MANIFEST.in new file mode 100644 index 00000000..250ba3b5 --- /dev/null +++ b/SwanFileBrowser/MANIFEST.in @@ -0,0 +1,24 @@ +include README.md +include pyproject.toml + +include package.json +include install.json +include ts*.json +include yarn.lock +include typedoc.json +graft swanfilebrowser/labextension + +# Javascript files +graft src +graft style +graft schema +prune **/node_modules +prune lib +prune binder + +# Patterns to exclude from any directory +global-exclude *~ +global-exclude *.pyc +global-exclude *.pyo +global-exclude .git +global-exclude .ipynb_checkpoints diff --git a/SwanFileBrowser/README.md b/SwanFileBrowser/README.md new file mode 100644 index 00000000..a5b67021 --- /dev/null +++ b/SwanFileBrowser/README.md @@ -0,0 +1,3 @@ +# @swan/filebrowser-extension + +An extension for JupyterLab which provides an entry point, commands, and keyboard shortcuts for the filebrowser. diff --git a/SwanFileBrowser/install.json b/SwanFileBrowser/install.json new file mode 100644 index 00000000..badf093f --- /dev/null +++ b/SwanFileBrowser/install.json @@ -0,0 +1,5 @@ +{ + "packageManager": "python", + "packageName": "swanfilebrowser", + "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package swanfilebrowser" +} diff --git a/SwanFileBrowser/package.json b/SwanFileBrowser/package.json new file mode 100644 index 00000000..cfd8bbed --- /dev/null +++ b/SwanFileBrowser/package.json @@ -0,0 +1,95 @@ +{ + "name": "@swan/filebrowser-extension", + "version": "0.1.0", + "description": "JupyterLab - SWAN Filebrowser Widget Extension", + "homepage": "https://github.com/swan-cern/jupyter-extensions", + "bugs": { + "url": "https://github.com/swan-cern/jupyter-extensions/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/swan-cern/jupyter-extensions.git" + }, + "license": "AGPL-3.0", + "author": "SWAN Team", + "files": [ + "lib/*.d.ts", + "lib/*.js.map", + "lib/*.js", + "src/*.ts", + "schema/*.json", + "style/**/*.css", + "style/index.js" + ], + "sideEffects": [ + "style/**/*.css", + "style/index.js" + ], + "main": "lib/index.js", + "types": "lib/index.d.ts", + "style": "style/index.css", + "directories": { + "lib": "lib/" + }, + "scripts": { + "build": "jlpm run build:lib && jlpm run build:labextension:dev", + "build:labextension": "jupyter labextension build .", + "build:labextension:dev": "jupyter labextension build --development True .", + "build:lib": "tsc", + "build:prod": "jlpm run clean && jlpm run build:lib && jlpm run build:labextension", + "clean": "jlpm run clean:lib", + "clean:all": "jlpm run clean:lib && jlpm run clean:labextension", + "clean:labextension": "rimraf swanfilebrowser/labextension", + "clean:lib": "rimraf lib tsconfig.tsbuildinfo", + "docs": "typedoc src", + "eslint": "eslint . --ext .ts,.tsx --fix", + "eslint:check": "eslint . --ext .ts,.tsx", + "install:extension": "jlpm run build", + "prepublishOnly": "npm run build", + "watch": "run-p watch:src watch:labextension", + "watch:labextension": "jupyter labextension watch .", + "watch:src": "tsc -w" + }, + "dependencies": { + "@jupyterlab/application": "^3.0.11", + "@jupyterlab/apputils": "^3.0.9", + "@jupyterlab/coreutils": "^5.0.6", + "@jupyterlab/docmanager": "^3.0.11", + "@jupyterlab/filebrowser": "^3.0.11", + "@jupyterlab/mainmenu": "^3.0.9", + "@jupyterlab/services": "^6.0.9", + "@jupyterlab/settingregistry": "^3.0.6", + "@jupyterlab/statedb": "^3.0.6", + "@jupyterlab/statusbar": "^3.0.9", + "@jupyterlab/ui-components": "^3.0.7", + "@lumino/algorithm": "^1.3.3", + "@lumino/commands": "^1.12.0", + "@lumino/messaging": "^1.4.3", + "@lumino/widgets": "^1.16.1" + }, + "devDependencies": { + "@jupyterlab/builder": "^3.0.0", + "@typescript-eslint/eslint-plugin": "^4.8.1", + "@typescript-eslint/parser": "^4.8.1", + "eslint": "^7.14.0", + "eslint-config-prettier": "^6.15.0", + "eslint-plugin-prettier": "^3.1.4", + "npm-run-all": "^4.1.5", + "prettier": "^2.1.1", + "rimraf": "^3.0.2", + "typedoc": "^0.15.4", + "typescript": "~4.1.3" + }, + "publishConfig": { + "access": "public" + }, + "jupyterlab": { + "extension": true, + "schemaDir": "schema", + "outputDir": "swanfilebrowser/labextension", + "disabledExtensions": [ + "@jupyterlab/filebrowser-extension" + ] + }, + "styleModule": "style/index.js" +} diff --git a/SwanFileBrowser/pyproject.toml b/SwanFileBrowser/pyproject.toml new file mode 100644 index 00000000..1cb77cb6 --- /dev/null +++ b/SwanFileBrowser/pyproject.toml @@ -0,0 +1,17 @@ +[build-system] +requires = ["jupyter_packaging~=0.10,<2", "jupyterlab~=3.0"] +build-backend = "jupyter_packaging.build_api" + +[tool.jupyter-packaging.options] +skip-if-exists = ["swanfilebrowser/labextension/static/style.js"] +ensured-targets = ["swanfilebrowser/labextension/static/style.js", "swanfilebrowser/labextension/package.json"] + +[tool.jupyter-packaging.builder] +factory = "jupyter_packaging.npm_builder" + +[tool.jupyter-packaging.build-args] +build_cmd = "build:prod" +npm = ["jlpm"] + +[tool.check-manifest] +ignore = ["swanfilebrowser/labextension/**", "yarn.lock", ".*", "package-lock.json"] diff --git a/SwanFileBrowser/schema/browser.json b/SwanFileBrowser/schema/browser.json new file mode 100644 index 00000000..78cf6bea --- /dev/null +++ b/SwanFileBrowser/schema/browser.json @@ -0,0 +1,28 @@ +{ + "jupyter.lab.setting-icon": "ui-components:folder", + "jupyter.lab.setting-icon-label": "File Browser", + "title": "File Browser", + "description": "File Browser settings.", + "jupyter.lab.shortcuts": [ + { + "command": "filebrowser:create-main-launcher", + "keys": ["Accel Shift L"], + "selector": "body" + }, + { + "command": "filebrowser:toggle-main", + "keys": ["Accel Shift F"], + "selector": "body" + } + ], + "properties": { + "navigateToCurrentDirectory": { + "type": "boolean", + "title": "Navigate to current directory", + "description": "Whether to automatically navigate to a document's current directory", + "default": false + } + }, + "additionalProperties": false, + "type": "object" +} diff --git a/SwanFileBrowser/setup.py b/SwanFileBrowser/setup.py new file mode 100644 index 00000000..44b28ffc --- /dev/null +++ b/SwanFileBrowser/setup.py @@ -0,0 +1,89 @@ +""" +swanfilebrowser setup +""" +import site +import json +import sys +from pathlib import Path + +import setuptools + +site.ENABLE_USER_SITE = "--user" in sys.argv[1:] + +HERE = Path(__file__).parent.resolve() + +# The name of the project +name = "swanfilebrowser" + +lab_path = (HERE / name.replace("-", "_") / "labextension") + +# Representative files that should exist after a successful build +ensured_targets = [ + str(lab_path / "package.json"), + str(lab_path / "static/style.js") +] + +labext_name = "@swan/filebrowser-extension" + +data_files_spec = [ + ("share/jupyter/labextensions/%s" % labext_name, str(lab_path.relative_to(HERE)), "**"), + ("share/jupyter/labextensions/%s" % labext_name, str("."), "install.json"), +] + +long_description = (HERE / "README.md").read_text() + +# Get the package info from package.json +pkg_json = json.loads((HERE / "package.json").read_bytes()) + +setup_args = dict( + name=name, + version=pkg_json["version"], + url=pkg_json["homepage"], + author=pkg_json["author"], + description=pkg_json["description"], + license=pkg_json["license"], + long_description=long_description, + long_description_content_type="text/markdown", + packages=setuptools.find_packages(), + install_requires=[], + zip_safe=False, + include_package_data=True, + python_requires=">=3.6", + platforms="Linux, Mac OS X, Windows", + keywords=["Jupyter", "JupyterLab", "JupyterLab3"], + classifiers=[ + "License :: OSI Approved :: GNU Affero General Public License v3", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Framework :: Jupyter", + "Framework :: Jupyter :: JupyterLab", + "Framework :: Jupyter :: JupyterLab :: 3", + "Framework :: Jupyter :: JupyterLab :: Extensions", + "Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt", + ], +) + +try: + from jupyter_packaging import ( + wrap_installers, + npm_builder, + get_data_files + ) + post_develop = npm_builder( + build_cmd="install:extension", source_dir="src", build_dir=lab_path + ) + setup_args["cmdclass"] = wrap_installers(post_develop=post_develop, ensured_targets=ensured_targets) + setup_args["data_files"] = get_data_files(data_files_spec) +except ImportError as e: + import logging + logging.basicConfig(format="%(levelname)s: %(message)s") + logging.warning("Build tool `jupyter-packaging` is missing. Install it with pip or conda.") + if not ("--name" in sys.argv or "--version" in sys.argv): + raise e + +if __name__ == "__main__": + setuptools.setup(**setup_args) diff --git a/SwanFileBrowser/src/icons.ts b/SwanFileBrowser/src/icons.ts new file mode 100644 index 00000000..e05b3e17 --- /dev/null +++ b/SwanFileBrowser/src/icons.ts @@ -0,0 +1,8 @@ +import { LabIcon } from '@jupyterlab/ui-components'; + +import swanProjectIconStr from '../style/project_folder.svg'; + +export const swanProjectIcon = new LabIcon({ + name: 'ui-components:folder-project', + svgstr: swanProjectIconStr +}); diff --git a/SwanFileBrowser/src/index.ts b/SwanFileBrowser/src/index.ts new file mode 100644 index 00000000..318ec5a0 --- /dev/null +++ b/SwanFileBrowser/src/index.ts @@ -0,0 +1,1181 @@ +// Copyright (c) SWAN Development Team. +// Modified from the original JupyterLab extension. +// Author: Omar.Zapata@cern.ch 2021 + +/** + * SwanFileBrowser extension is based on the upstream filebrowser extension 3.0.x. + * + * This file the entry point for the extension where is defined the commands such as + * 'filebrowser:copy', 'filebrowser:cut', 'filebrowser:open' etc.. + * Those commands are reimplemented using our class SwanFileBrowser intead the default Jupyter FileBrowser. + * + * The classes SwanFileBrowser and SwanFileBrowserModel are defined in the file swanfilebrowser.ts + * and the class SwanDirListing in the file listing.ts. Those have the code required to manipulate + * projects and kernel manager. + * + * Alsmot all the documentation for this file is the default one provided by the Jupyter extension. + */ + +import { + ILabShell, + ILayoutRestorer, + IRouter, + JupyterFrontEnd, + JupyterFrontEndPlugin +} from '@jupyterlab/application'; + +import { + Clipboard, + MainAreaWidget, + ToolbarButton, + WidgetTracker, + ICommandPalette, + InputDialog, + showErrorMessage, + DOMUtils +} from '@jupyterlab/apputils'; + +import { PageConfig, PathExt, URLExt } from '@jupyterlab/coreutils'; + +import { IDocumentManager } from '@jupyterlab/docmanager'; + +import { FileUploadStatus, IFileBrowserFactory } from '@jupyterlab/filebrowser'; + +import { IMainMenu } from '@jupyterlab/mainmenu'; + +import { Contents } from '@jupyterlab/services'; + +import { ISettingRegistry } from '@jupyterlab/settingregistry'; + +import { IStateDB } from '@jupyterlab/statedb'; + +import { IStatusBar } from '@jupyterlab/statusbar'; + +import { SwanFileBrowserModel, SwanFileBrowser } from './swanfilebrowser'; +import { + addIcon, + closeIcon, + copyIcon, + cutIcon, + downloadIcon, + editIcon, + fileIcon, + folderIcon, + linkIcon, + markdownIcon, + newFolderIcon, + pasteIcon, + stopIcon, + textEditorIcon +} from '@jupyterlab/ui-components'; + +import { IIterator, map, reduce, toArray, find } from '@lumino/algorithm'; + +import { CommandRegistry } from '@lumino/commands'; + +import { Message } from '@lumino/messaging'; + +import { Menu } from '@lumino/widgets'; + +/** + * The command IDs used by the file browser plugin. + */ +namespace CommandIDs { + export const copy = 'filebrowser:copy'; + + export const copyDownloadLink = 'filebrowser:copy-download-link'; + + // For main browser only. + export const createLauncher = 'filebrowser:create-main-launcher'; + + export const cut = 'filebrowser:cut'; + + export const del = 'filebrowser:delete'; + + export const download = 'filebrowser:download'; + + export const duplicate = 'filebrowser:duplicate'; + + // For main browser only. + export const hideBrowser = 'filebrowser:hide-main'; + + export const goToPath = 'filebrowser:go-to-path'; + + export const openPath = 'filebrowser:open-path'; + + export const open = 'filebrowser:open'; + + export const openBrowserTab = 'filebrowser:open-browser-tab'; + + export const paste = 'filebrowser:paste'; + + export const createNewDirectory = 'filebrowser:create-new-directory'; + + export const createNewFile = 'filebrowser:create-new-file'; + + export const createNewMarkdownFile = 'filebrowser:create-new-markdown-file'; + + export const rename = 'filebrowser:rename'; + + // For main browser only. + export const share = 'filebrowser:share-main'; + + // For main browser only. + export const copyPath = 'filebrowser:copy-path'; + + export const showBrowser = 'filebrowser:activate'; + + export const shutdown = 'filebrowser:shutdown'; + + // For main browser only. + export const toggleBrowser = 'filebrowser:toggle-main'; + + export const toggleNavigateToCurrentDirectory = + 'filebrowser:toggle-navigate-to-current-directory'; + + export const toggleLastModified = 'filebrowser:toggle-last-modified'; +} +/** + * The default file browser extension. + */ +const browser: JupyterFrontEndPlugin = { + activate: activateBrowser, + id: '@swan/filebrowser-extension:browser', + requires: [ + IFileBrowserFactory, + IDocumentManager, + ILabShell, + ILayoutRestorer, + ISettingRegistry + ], + optional: [ICommandPalette, IMainMenu], + autoStart: true +}; + +/** + * The default file browser factory provider. + */ +const factory: JupyterFrontEndPlugin = { + activate: activateFactory, + id: '@swan/filebrowser-extension:factory', + provides: IFileBrowserFactory, + requires: [IDocumentManager], + optional: [IStateDB, IRouter, JupyterFrontEnd.ITreeResolver] +}; + +/** + * The default file browser share-file plugin + * + * This extension adds a "Copy Shareable Link" command that generates a copy- + * pastable URL. This url can be used to open a particular file in JupyterLab, + * handy for emailing links or bookmarking for reference. + * + * If you need to change how this link is generated (for instance, to copy a + * /user-redirect URL for JupyterHub), disable this plugin and replace it + * with another implementation. + */ +const shareFile: JupyterFrontEndPlugin = { + activate: activateShareFile, + id: '@swan/filebrowser-extension:share-file', + requires: [IFileBrowserFactory], + autoStart: true +}; + +/** + * A plugin providing file upload status. + */ +export const fileUploadStatus: JupyterFrontEndPlugin = { + id: '@swan/filebrowser-extension:file-upload-status', + autoStart: true, + requires: [IFileBrowserFactory], + optional: [IStatusBar], + activate: ( + app: JupyterFrontEnd, + browser: IFileBrowserFactory, + statusBar: IStatusBar | null + ) => { + if (!statusBar) { + // Automatically disable if statusbar missing + return; + } + const item = new FileUploadStatus({ + tracker: browser.tracker + }); + + statusBar.registerStatusItem( + '@swan/filebrowser-extension:file-upload-status', + { + item, + align: 'middle', + isActive: () => { + return !!item.model && item.model.items.length > 0; + }, + activeStateChanged: item.model.stateChanged + } + ); + } +}; + +/** + * The file browser namespace token. + */ +const namespace = 'filebrowser'; + +/** + * Export the plugins as default. + */ +const plugins: JupyterFrontEndPlugin[] = [ + factory, + browser, + shareFile, + fileUploadStatus +]; +export default plugins; + +/** + * Activate the file browser factory provider. + */ +async function activateFactory( + app: JupyterFrontEnd, + docManager: IDocumentManager, + state: IStateDB | null, + router: IRouter | null, + tree: JupyterFrontEnd.ITreeResolver | null +): Promise { + console.log('JupyterLab extension swanfilebrowser is activated!'); + const { commands } = app; + const tracker = new WidgetTracker({ namespace }); + const createFileBrowser = ( + id: string, + options: IFileBrowserFactory.IOptions = {} + ) => { + const model = new SwanFileBrowserModel( + { + auto: options.auto ?? true, + manager: docManager, + driveName: options.driveName || '', + refreshInterval: options.refreshInterval, + state: + options.state === null + ? undefined + : options.state || state || undefined + }, + commands + ); + const restore = options.restore; + const widget = new SwanFileBrowser({ id, model, restore }); + + // Add a launcher toolbar item. + const launcher = new ToolbarButton({ + icon: addIcon, + onClick: () => { + return Private.createLauncher(commands, widget); + }, + tooltip: 'New Launcher' + }); + widget.toolbar.insertItem(0, 'launch', launcher); + + // Track the newly created file browser. + void tracker.add(widget); + + return widget; + }; + + // Manually restore and load the default file browser. + const defaultBrowser = createFileBrowser('filebrowser', { + auto: false, + restore: false + }); + void Private.restoreBrowser(defaultBrowser, commands, router, tree); + + return { createFileBrowser, defaultBrowser, tracker }; +} + +/** + * Activate the default file browser in the sidebar. + */ +function activateBrowser( + app: JupyterFrontEnd, + factory: IFileBrowserFactory, + docManager: IDocumentManager, + labShell: ILabShell, + restorer: ILayoutRestorer, + settingRegistry: ISettingRegistry, + commandPalette: ICommandPalette | null, + mainMenu: IMainMenu | null +): void { + const browser = factory.defaultBrowser; + const { commands } = app; + // Let the application restorer track the primary file browser (that is + // automatically created) for restoration of application state (e.g. setting + // the file browser as the current side bar widget). + // + // All other file browsers created by using the factory function are + // responsible for their own restoration behavior, if any. + restorer.add(browser, namespace); + + addCommands( + app, + factory, + labShell, + docManager, + settingRegistry, + commandPalette, + mainMenu + ); + + browser.title.icon = folderIcon; + // Show the current file browser shortcut in its title. + const updateBrowserTitle = () => { + const binding = find( + app.commands.keyBindings, + b => b.command === CommandIDs.toggleBrowser + ); + if (binding) { + const ks = CommandRegistry.formatKeystroke(binding.keys.join(' ')); + browser.title.caption = `SWAN File Browser (${ks})`; + } else { + browser.title.caption = 'SWAN File Browser'; + } + }; + updateBrowserTitle(); + app.commands.keyBindingChanged.connect(() => { + updateBrowserTitle(); + }); + labShell.add(browser, 'left', { rank: 100 }); + + // If the layout is a fresh session without saved data, open file browser. + void labShell.restored.then(layout => { + if (layout.fresh) { + void commands.execute(CommandIDs.showBrowser, void 0); + } + }); + + void Promise.all([app.restored, browser.model.restored]).then(() => { + function maybeCreate() { + // Create a launcher if there are no open items. + if (labShell.isEmpty('main')) { + void Private.createLauncher(commands, browser); + } + } + + // When layout is modified, create a launcher if there are no open items. + labShell.layoutModified.connect(() => { + maybeCreate(); + }); + + let navigateToCurrentDirectory = false; + + void settingRegistry + .load('@swan/filebrowser-extension:browser') + .then(settings => { + settings.changed.connect(settings => { + navigateToCurrentDirectory = settings.get( + 'navigateToCurrentDirectory' + ).composite as boolean; + browser.navigateToCurrentDirectory = navigateToCurrentDirectory; + }); + navigateToCurrentDirectory = settings.get('navigateToCurrentDirectory') + .composite as boolean; + browser.navigateToCurrentDirectory = navigateToCurrentDirectory; + }); + + // Whether to automatically navigate to a document's current directory + labShell.currentChanged.connect(async (_, change) => { + if (navigateToCurrentDirectory && change.newValue) { + const { newValue } = change; + const context = docManager.contextForWidget(newValue); + if (context) { + const { path } = context; + + try { + await Private.navigateToPath(path, factory); + labShell.currentWidget?.activate(); + } catch (reason) { + console.warn( + `${CommandIDs.goToPath} failed to open: ${path}`, + reason + ); + } + } + } + }); + + maybeCreate(); + }); +} + +function activateShareFile( + app: JupyterFrontEnd, + factory: IFileBrowserFactory +): void { + const { commands } = app; + const { tracker } = factory; + + commands.addCommand(CommandIDs.share, { + execute: () => { + const widget = tracker.currentWidget; + const model = widget?.selectedItems().next(); + if (!model) { + return; + } + const path = encodeURI(model.path); + Clipboard.copyToSystem(URLExt.join(PageConfig.getTreeShareUrl(), path)); + }, + isVisible: () => + !!tracker.currentWidget && + toArray(tracker.currentWidget.selectedItems()).length === 1, + icon: linkIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Copy Shareable Link' + }); +} + +/** + * Add the main file browser commands to the application's command registry. + */ +function addCommands( + app: JupyterFrontEnd, + factory: IFileBrowserFactory, + labShell: ILabShell, + docManager: IDocumentManager, + settingRegistry: ISettingRegistry, + commandPalette: ICommandPalette | null, + mainMenu: IMainMenu | null +): void { + const { docRegistry: registry, commands } = app; + let { defaultBrowser: browser } = factory; + const { tracker } = factory; + browser = browser; + + commands.addCommand(CommandIDs.del, { + execute: () => { + const widget = tracker.currentWidget; + + if (widget) { + return widget.delete(); + } + }, + icon: closeIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Delete', + mnemonic: 0 + }); + + commands.addCommand(CommandIDs.copy, { + execute: () => { + const widget = tracker.currentWidget; + + if (widget) { + return widget.copy(); + } + }, + icon: copyIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Copy', + mnemonic: 0 + }); + + commands.addCommand(CommandIDs.cut, { + execute: () => { + const widget = tracker.currentWidget; + + if (widget) { + return widget.cut(); + } + }, + icon: cutIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Cut' + }); + + commands.addCommand(CommandIDs.download, { + execute: () => { + const widget = tracker.currentWidget; + + if (widget) { + return widget.download(); + } + }, + icon: downloadIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Download' + }); + + commands.addCommand(CommandIDs.duplicate, { + execute: () => { + const widget = tracker.currentWidget; + + if (widget) { + return widget.duplicate(); + } + }, + icon: copyIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Duplicate' + }); + + commands.addCommand(CommandIDs.hideBrowser, { + execute: () => { + const widget = tracker.currentWidget; + if (widget && !widget.isHidden) { + labShell.collapseLeft(); + } + } + }); + + commands.addCommand(CommandIDs.goToPath, { + execute: async args => { + const path = (args.path as string) || ''; + try { + const item = await Private.navigateToPath(path, factory); + if (item.type !== 'directory') { + const browserForPath = Private.getBrowserForPath(path, factory); + if (browserForPath) { + browserForPath.clearSelectedItems(); + const parts = path.split('/'); + const name = parts[parts.length - 1]; + if (name) { + await browserForPath.selectItemByName(name); + } + } + } + } catch (reason) { + console.warn(`${CommandIDs.goToPath} failed to go to: ${path}`, reason); + } + return commands.execute(CommandIDs.showBrowser, { path }); + } + }); + + commands.addCommand(CommandIDs.openPath, { + label: args => (args.path ? `Open ${args.path}` : 'Open from Path…'), + caption: args => (args.path ? `Open ${args.path}` : 'Open from path'), + execute: async ({ path }: { path?: string }) => { + if (!path) { + path = + ( + await InputDialog.getText({ + label: 'Path', + placeholder: '/path/relative/to/jlab/root', + title: 'Open Path', + okLabel: 'Open' + }) + ).value ?? undefined; + } + if (!path) { + return; + } + try { + const trailingSlash = path !== '/' && path.endsWith('/'); + if (trailingSlash) { + // The normal contents service errors on paths ending in slash + path = path.slice(0, path.length - 1); + } + const browserForPath = Private.getBrowserForPath(path, factory)!; // eslint-disable-line @typescript-eslint/no-non-null-assertion + const { services } = browserForPath.model.manager; + const item = await services.contents.get(path, { + content: false + }); + if (trailingSlash && item.type !== 'directory') { + throw new Error(`Path ${path}/ is not a directory`); + } + await commands.execute(CommandIDs.goToPath, { path }); + if (item.type === 'directory') { + return; + } + return commands.execute('docmanager:open', { path }); + } catch (reason) { + if (reason.response && reason.response.status === 404) { + reason.message = `Could not find path: ${path}`; + } + return showErrorMessage('Cannot open', reason); + } + } + }); + // Add the openPath command to the command palette + if (commandPalette) { + commandPalette.addItem({ + command: CommandIDs.openPath, + category: 'File Operations' + }); + } + + commands.addCommand(CommandIDs.open, { + execute: args => { + const factory = (args['factory'] as string) || void 0; + const widget = tracker.currentWidget; + + if (!widget) { + return; + } + + const { contents } = widget.model.manager.services; + return Promise.all( + toArray( + map(widget.selectedItems(), item => { + if (item.type === 'directory') { + const localPath = contents.localPath(item.path); + return widget.model.cd(`/${localPath}`); + } + + return commands.execute('docmanager:open', { + factory: factory, + path: item.path + }); + }) + ) + ); + }, + icon: args => { + const factory = (args['factory'] as string) || void 0; + if (factory) { + // if an explicit factory is passed... + const ft = registry.getFileType(factory); + // ...set an icon if the factory name corresponds to a file type name... + // ...or leave the icon blank + return ft?.icon?.bindprops({ stylesheet: 'menuItem' }); + } else { + return folderIcon.bindprops({ stylesheet: 'menuItem' }); + } + }, + label: args => (args['label'] || args['factory'] || 'Open') as string, + mnemonic: 0 + }); + + commands.addCommand(CommandIDs.openBrowserTab, { + execute: () => { + const widget = tracker.currentWidget; + + if (!widget) { + return; + } + + return Promise.all( + toArray( + map(widget.selectedItems(), item => { + return commands.execute('docmanager:open-browser-tab', { + path: item.path + }); + }) + ) + ); + }, + icon: addIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Open in New Browser Tab', + mnemonic: 0 + }); + + commands.addCommand(CommandIDs.copyDownloadLink, { + execute: () => { + const widget = tracker.currentWidget; + if (!widget) { + return; + } + + return widget.model.manager.services.contents + .getDownloadUrl(widget.selectedItems().next()!.path) // eslint-disable-line @typescript-eslint/no-non-null-assertion + .then(url => { + Clipboard.copyToSystem(url); + }); + }, + icon: copyIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Copy Download Link', + mnemonic: 0 + }); + + commands.addCommand(CommandIDs.paste, { + execute: () => { + const widget = tracker.currentWidget; + + if (widget) { + return widget.paste(); + } + }, + icon: pasteIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Paste', + mnemonic: 0 + }); + + commands.addCommand(CommandIDs.createNewDirectory, { + execute: () => { + const widget = tracker.currentWidget; + + if (widget) { + return widget.createNewDirectory(); + } + }, + icon: newFolderIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'New Folder' + }); + + commands.addCommand(CommandIDs.createNewFile, { + execute: () => { + const { + model: { path } + } = browser; + void commands.execute('docmanager:new-untitled', { + path, + type: 'file', + ext: 'txt' + }); + }, + icon: textEditorIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'New File' + }); + + commands.addCommand(CommandIDs.createNewMarkdownFile, { + execute: () => { + const { + model: { path } + } = browser; + void commands.execute('docmanager:new-untitled', { + path, + type: 'file', + ext: 'md' + }); + }, + icon: markdownIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'New Markdown File' + }); + + commands.addCommand(CommandIDs.rename, { + execute: args => { + const widget = tracker.currentWidget; + + if (widget) { + return widget.rename(); + } + }, + icon: editIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Rename', + mnemonic: 0 + }); + + commands.addCommand(CommandIDs.copyPath, { + execute: () => { + const widget = tracker.currentWidget; + if (!widget) { + return; + } + const item = widget.selectedItems().next(); + if (!item) { + return; + } + + Clipboard.copyToSystem(item.path); + }, + isVisible: () => + !!tracker.currentWidget && + tracker.currentWidget.selectedItems().next !== undefined, + icon: fileIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Copy Path' + }); + + commands.addCommand(CommandIDs.showBrowser, { + execute: args => { + const path = (args.path as string) || ''; + const browserForPath = Private.getBrowserForPath(path, factory); + + // Check for browser not found + if (!browserForPath) { + return; + } + // Shortcut if we are using the main file browser + if (browser === browserForPath) { + labShell.activateById(browser.id); + return; + } else { + const areas: ILabShell.Area[] = ['left', 'right']; + for (const area of areas) { + const it = labShell.widgets(area); + let widget = it.next(); + while (widget) { + if (widget.contains(browserForPath)) { + labShell.activateById(widget.id); + return; + } + widget = it.next(); + } + } + } + } + }); + + commands.addCommand(CommandIDs.shutdown, { + execute: () => { + const widget = tracker.currentWidget; + + if (widget) { + return widget.shutdownKernels(); + } + }, + icon: stopIcon.bindprops({ stylesheet: 'menuItem' }), + label: 'Shut Down Kernel' + }); + + commands.addCommand(CommandIDs.toggleBrowser, { + execute: () => { + if (browser.isHidden) { + return commands.execute(CommandIDs.showBrowser, void 0); + } + + return commands.execute(CommandIDs.hideBrowser, void 0); + } + }); + + commands.addCommand(CommandIDs.createLauncher, { + label: 'New Launcher', + execute: () => Private.createLauncher(commands, browser) + }); + + commands.addCommand(CommandIDs.toggleNavigateToCurrentDirectory, { + label: 'Show Active File in File Browser', + isToggled: () => browser.navigateToCurrentDirectory, + execute: () => { + const value = !browser.navigateToCurrentDirectory; + const key = 'navigateToCurrentDirectory'; + return settingRegistry + .set('@swan/filebrowser-extension:browser', key, value) + .catch((reason: Error) => { + console.error('Failed to set navigateToCurrentDirectory setting'); + }); + } + }); + + commands.addCommand(CommandIDs.toggleLastModified, { + label: 'Toggle Last Modified Column', + execute: () => { + const header = DOMUtils.findElement(document.body, 'jp-id-modified'); + const column = DOMUtils.findElements( + document.body, + 'jp-DirListing-itemModified' + ); + if (header.classList.contains('jp-LastModified-hidden')) { + header.classList.remove('jp-LastModified-hidden'); + for (let i = 0; i < column.length; i++) { + column[i].classList.remove('jp-LastModified-hidden'); + } + } else { + header.classList.add('jp-LastModified-hidden'); + for (let i = 0; i < column.length; i++) { + column[i].classList.add('jp-LastModified-hidden'); + } + } + } + }); + + if (mainMenu) { + mainMenu.settingsMenu.addGroup( + [{ command: CommandIDs.toggleNavigateToCurrentDirectory }], + 5 + ); + } + + if (commandPalette) { + commandPalette.addItem({ + command: CommandIDs.toggleNavigateToCurrentDirectory, + category: 'File Operations' + }); + } + + /** + * A menu widget that dynamically populates with different widget factories + * based on current filebrowser selection. + */ + class OpenWithMenu extends Menu { + protected onBeforeAttach(msg: Message): void { + // clear the current menu items + this.clearItems(); + + // get the widget factories that could be used to open all of the items + // in the current filebrowser selection + const factories = tracker.currentWidget + ? OpenWithMenu._intersection( + map(tracker.currentWidget.selectedItems(), i => { + return OpenWithMenu._getFactories(i); + }) + ) + : undefined; + + if (factories) { + // make new menu items from the widget factories + factories.forEach(factory => { + this.addItem({ + args: { factory: factory }, + command: CommandIDs.open + }); + }); + } + + super.onBeforeAttach(msg); + } + + static _getFactories(item: Contents.IModel): Array { + const factories = registry + .preferredWidgetFactories(item.path) + .map(f => f.name); + const notebookFactory = registry.getWidgetFactory('notebook')?.name; + if ( + notebookFactory && + item.type === 'notebook' && + factories.indexOf(notebookFactory) === -1 + ) { + factories.unshift(notebookFactory); + } + + return factories; + } + + static _intersection(iter: IIterator>): Set | void { + // pop the first element of iter + const first = iter.next(); + // first will be undefined if iter is empty + if (!first) { + return; + } + + // "initialize" the intersection from first + const isect = new Set(first); + // reduce over the remaining elements of iter + return reduce( + iter, + (isect, subarr) => { + // filter out all elements not present in both isect and subarr, + // accumulate result in new set + return new Set(subarr.filter(x => isect.has(x))); + }, + isect + ); + } + } + + // matches anywhere on filebrowser + const selectorContent = '.jp-DirListing-content'; + // matches all filebrowser items + const selectorItem = '.jp-DirListing-item[data-isdir]'; + // matches only non-directory items + const selectorNotDir = '.jp-DirListing-item[data-isdir="false"]'; + + // If the user did not click on any file, we still want to show paste and new folder, + // so target the content rather than an item. + app.contextMenu.addItem({ + command: CommandIDs.createNewDirectory, + selector: selectorContent, + rank: 1 + }); + + app.contextMenu.addItem({ + command: CommandIDs.createNewFile, + selector: selectorContent, + rank: 2 + }); + + app.contextMenu.addItem({ + command: CommandIDs.createNewMarkdownFile, + selector: selectorContent, + rank: 3 + }); + + app.contextMenu.addItem({ + command: CommandIDs.paste, + selector: selectorContent, + rank: 4 + }); + + app.contextMenu.addItem({ + command: CommandIDs.open, + selector: selectorItem, + rank: 1 + }); + + const openWith = new OpenWithMenu({ commands }); + openWith.title.label = 'Open With'; + app.contextMenu.addItem({ + type: 'submenu', + submenu: openWith, + selector: selectorNotDir, + rank: 2 + }); + + app.contextMenu.addItem({ + command: CommandIDs.openBrowserTab, + selector: selectorNotDir, + rank: 3 + }); + + app.contextMenu.addItem({ + command: CommandIDs.rename, + selector: selectorItem, + rank: 4 + }); + app.contextMenu.addItem({ + command: CommandIDs.del, + selector: selectorItem, + rank: 5 + }); + app.contextMenu.addItem({ + command: CommandIDs.cut, + selector: selectorItem, + rank: 6 + }); + + app.contextMenu.addItem({ + command: CommandIDs.copy, + selector: selectorNotDir, + rank: 7 + }); + + app.contextMenu.addItem({ + command: CommandIDs.duplicate, + selector: selectorNotDir, + rank: 8 + }); + app.contextMenu.addItem({ + command: CommandIDs.download, + selector: selectorNotDir, + rank: 9 + }); + app.contextMenu.addItem({ + command: CommandIDs.shutdown, + selector: selectorNotDir, + rank: 10 + }); + + app.contextMenu.addItem({ + command: CommandIDs.share, + selector: selectorItem, + rank: 11 + }); + app.contextMenu.addItem({ + command: CommandIDs.copyPath, + selector: selectorItem, + rank: 12 + }); + app.contextMenu.addItem({ + command: CommandIDs.copyDownloadLink, + selector: selectorNotDir, + rank: 13 + }); + app.contextMenu.addItem({ + command: CommandIDs.toggleLastModified, + selector: '.jp-DirListing-header', + rank: 14 + }); +} + +/** + * A namespace for private module data. + */ +namespace Private { + /** + * Create a launcher for a given filebrowser widget. + */ + export function createLauncher( + commands: CommandRegistry, + browser: SwanFileBrowser + ): Promise> { + const { model } = browser; + return commands + .execute('launcher:create', { cwd: model.path }) + .then((launcher: MainAreaWidget) => { + model.pathChanged.connect(() => { + if (launcher.content) { + launcher.content.cwd = model.path; + } + }, launcher); + return launcher; + }); + } + + /** + * Get browser object given file path. + */ + export function getBrowserForPath( + path: string, + factory: IFileBrowserFactory + ): SwanFileBrowser | undefined { + const { defaultBrowser: browser, tracker } = factory; + const driveName = browser.model.manager.services.contents.driveName(path); + + if (driveName) { + const browserForPath = tracker.find( + _path => _path.model.driveName === driveName + ); + + if (!browserForPath) { + // warn that no filebrowser could be found for this driveName + console.warn( + `${CommandIDs.goToPath} failed to find filebrowser for path: ${path}` + ); + return; + } + + return browserForPath; + } + + // if driveName is empty, assume the main filebrowser + return browser; + } + + /** + * Navigate to a path or the path containing a file. + */ + export async function navigateToPath( + path: string, + factory: IFileBrowserFactory + ): Promise { + const browserForPath = Private.getBrowserForPath(path, factory); + if (!browserForPath) { + throw new Error('No browser for path'); + } + const { services } = browserForPath.model.manager; + const localPath = services.contents.localPath(path); + + await services.ready; + const item = await services.contents.get(path, { content: false }); + const { model } = browserForPath; + await model.restored; + if (item.type === 'directory') { + await model.cd(`/${localPath}`); + } else { + await model.cd(`/${PathExt.dirname(localPath)}`); + } + return item; + } + + /** + * Restores file browser state and overrides state if tree resolver resolves. + */ + export async function restoreBrowser( + browser: SwanFileBrowser, + commands: CommandRegistry, + router: IRouter | null, + tree: JupyterFrontEnd.ITreeResolver | null + ): Promise { + const restoring = 'jp-mod-restoring'; + + browser.addClass(restoring); + + if (!router) { + await browser.model.restore(browser.id); + await browser.model.refresh(); + browser.removeClass(restoring); + return; + } + + const listener = async () => { + router.routed.disconnect(listener); + + const paths = await tree?.paths; + if (paths?.file || paths?.browser) { + // Restore the model without populating it. + await browser.model.restore(browser.id, false); + if (paths.file) { + await commands.execute(CommandIDs.openPath, { path: paths.file }); + } + if (paths.browser) { + await commands.execute(CommandIDs.openPath, { path: paths.browser }); + } + } else { + await browser.model.restore(browser.id); + await browser.model.refresh(); + } + browser.removeClass(restoring); + }; + router.routed.connect(listener); + } +} diff --git a/SwanFileBrowser/src/kernelspec/validate.ts b/SwanFileBrowser/src/kernelspec/validate.ts new file mode 100644 index 00000000..0bfe8c86 --- /dev/null +++ b/SwanFileBrowser/src/kernelspec/validate.ts @@ -0,0 +1,198 @@ +/** + * File took from https://github.com/jupyterlab/jupyterlab/blob/master/packages/services/src/kernelspec/validate.ts + * for jupyterlab 3.0.x + * + * This allows to validate the kernels specs and to get the ISpecModel. + * This is required to update the manager.services.kernelspecs.specs object + * in the SwanFileBrowserModel. + */ +import { PartialJSONObject } from '@lumino/coreutils'; + +/** + * Kernel Spec interface. + * + * #### Notes + * See [Kernel specs](https://jupyter-client.readthedocs.io/en/latest/kernels.html#kernelspecs). + */ +export interface ISpecModel extends PartialJSONObject { + /** + * The name of the kernel spec. + */ + readonly name: string; + + /** + * The name of the language of the kernel. + */ + readonly language: string; + + /** + * A list of command line arguments used to start the kernel. + */ + readonly argv: string[]; + + /** + * The kernel’s name as it should be displayed in the UI. + */ + readonly display_name: string; + + /** + * A dictionary of environment variables to set for the kernel. + */ + readonly env?: PartialJSONObject; + + /** + * A mapping of resource file name to download path. + */ + readonly resources: { [key: string]: string }; + + /** + * A dictionary of additional attributes about this kernel; used by clients to aid in kernel selection. + */ + readonly metadata?: PartialJSONObject; +} + +/** + * The available kernelSpec models. + * + * #### Notes + * See the [Jupyter Notebook API](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml#!/kernelspecs). + */ +export interface ISpecModels extends PartialJSONObject { + /** + * The name of the default kernel spec. + */ + default: string; + + /** + * A mapping of kernel spec name to spec. + */ + readonly kernelspecs: { [key: string]: ISpecModel | undefined }; +} + +/** + * Validate a property as being on an object, and optionally + * of a given type and among a given set of values. + */ +export function validateProperty( + object: any, // eslint-disable-line @typescript-eslint/explicit-module-boundary-types + name: string, + typeName?: string, + values: any[] = [] +): void { + if (!object.hasOwnProperty(name)) { // eslint-disable-line + throw Error(`Missing property '${name}'`); + } + const value = object[name]; + + if (typeName !== void 0) { + let valid = true; + switch (typeName) { + case 'array': + valid = Array.isArray(value); + break; + case 'object': + valid = typeof value !== 'undefined'; + break; + default: + valid = typeof value === typeName; + } + if (!valid) { + throw new Error(`Property '${name}' is not of type '${typeName}'`); + } + + if (values.length > 0) { + let valid = true; + switch (typeName) { + case 'string': + case 'number': + case 'boolean': + valid = values.includes(value); + break; + default: + valid = values.findIndex(v => v === value) >= 0; + break; + } + if (!valid) { + throw new Error( + `Property '${name}' is not one of the valid values ${JSON.stringify( + values + )}` + ); + } + } + } +} + +/** + * Validate a server kernelspec model to a client side model. + */ +export function validateSpecModel(data: any): ISpecModel { // eslint-disable-line + const spec = data.spec; + if (!spec) { + throw new Error('Invalid kernel spec'); + } + validateProperty(data, 'name', 'string'); + validateProperty(data, 'resources', 'object'); + validateProperty(spec, 'language', 'string'); + validateProperty(spec, 'display_name', 'string'); + validateProperty(spec, 'argv', 'array'); + + let metadata: any = null; + if (spec.hasOwnProperty('metadata')) { // eslint-disable-line + validateProperty(spec, 'metadata', 'object'); + metadata = spec.metadata; + } + + let env: any = null; + if (spec.hasOwnProperty('env')) { // eslint-disable-line + validateProperty(spec, 'env', 'object'); + env = spec.env; + } + return { + name: data.name, + resources: data.resources, + language: spec.language, + display_name: spec.display_name, + argv: spec.argv, + metadata, + env + }; +} + +/** + * Validate a `Kernel.ISpecModels` object. + */ +export function validateSpecModels(data: any): ISpecModels { // eslint-disable-line + if (!data.hasOwnProperty('kernelspecs')) { // eslint-disable-line + throw new Error('No kernelspecs found'); + } + let keys = Object.keys(data.kernelspecs); + const kernelspecs: { [key: string]: ISpecModel } = Object.create(null); + let defaultSpec = data.default; + + for (let i = 0; i < keys.length; i++) { + const ks = data.kernelspecs[keys[i]]; + try { + kernelspecs[keys[i]] = validateSpecModel(ks); + } catch (err) { + // Remove the errant kernel spec. + console.warn(`Removing errant kernel spec: ${keys[i]}`); + } + } + keys = Object.keys(kernelspecs); + if (!keys.length) { + throw new Error('No valid kernelspecs found'); + } + if ( + !defaultSpec || + typeof defaultSpec !== 'string' || + !(defaultSpec in kernelspecs) + ) { + defaultSpec = keys[0]; + console.warn(`Default kernel not found, using '${keys[0]}'`); + } + return { + default: defaultSpec, + kernelspecs + }; +} diff --git a/SwanFileBrowser/src/listing.ts b/SwanFileBrowser/src/listing.ts new file mode 100644 index 00000000..f40e7746 --- /dev/null +++ b/SwanFileBrowser/src/listing.ts @@ -0,0 +1,2390 @@ +/** + * File took from https://github.com/jupyterlab/jupyterlab/blob/master/packages/filebrowser/src/listing.ts + * for jupytrelab version 3.0.x. + * + * In this file, we reimplement the DirListing class in the SwanDirListing class. + * This allows you to manipulate the low-level entries in the file browser widget, + * allowing us, for example, to change the icon if the folder is a project. + */ +import { + Dialog, + DOMUtils, + showDialog, + showErrorMessage +} from '@jupyterlab/apputils'; +import { PathExt, Time } from '@jupyterlab/coreutils'; +import { + IDocumentManager, + isValidFileName, + renameFile +} from '@jupyterlab/docmanager'; +import { DocumentRegistry } from '@jupyterlab/docregistry'; +import { Contents } from '@jupyterlab/services'; +import { + ITranslator, + nullTranslator, + TranslationBundle +} from '@jupyterlab/translation'; +import { + caretDownIcon, + caretUpIcon, + classes, + LabIcon +} from '@jupyterlab/ui-components'; +import { + ArrayExt, + ArrayIterator, + each, + filter, + find, + IIterator, + StringExt, + toArray +} from '@lumino/algorithm'; +import { MimeData, PromiseDelegate } from '@lumino/coreutils'; +import { ElementExt } from '@lumino/domutils'; +import { Drag, IDragEvent } from '@lumino/dragdrop'; +import { Message, MessageLoop } from '@lumino/messaging'; +import { ISignal, Signal } from '@lumino/signaling'; +import { h, VirtualDOM } from '@lumino/virtualdom'; +import { Widget } from '@lumino/widgets'; +import { swanProjectIcon } from './icons'; +import { SwanFileBrowserModel } from './swanfilebrowser'; + +export interface ISwanModel { + content: any | null; + created: string; + format: string | null; + is_project: boolean; + last_modified: string; + mimetype: string | null; + name: string; + path: string; + size: number; + type: string; + writable: boolean; +} +export interface ISwanFileType { + contentType: any; + displayName: string; + extensions: any; + fileFormat: any; + icon: any; + mimeTypes: any; + name: string; +} + +/** + * The class name added to DirListing widget. + */ +const DIR_LISTING_CLASS = 'jp-DirListing'; + +/** + * The class name added to a dir listing header node. + */ +const HEADER_CLASS = 'jp-DirListing-header'; + +/** + * The class name added to a dir listing list header cell. + */ +const HEADER_ITEM_CLASS = 'jp-DirListing-headerItem'; + +/** + * The class name added to a header cell text node. + */ +const HEADER_ITEM_TEXT_CLASS = 'jp-DirListing-headerItemText'; + +/** + * The class name added to a header cell icon node. + */ +const HEADER_ITEM_ICON_CLASS = 'jp-DirListing-headerItemIcon'; + +/** + * The class name added to the dir listing content node. + */ +const CONTENT_CLASS = 'jp-DirListing-content'; + +/** + * The class name added to dir listing content item. + */ +const ITEM_CLASS = 'jp-DirListing-item'; + +/** + * The class name added to the listing item text cell. + */ +const ITEM_TEXT_CLASS = 'jp-DirListing-itemText'; + +/** + * The class name added to the listing item icon cell. + */ +const ITEM_ICON_CLASS = 'jp-DirListing-itemIcon'; + +/** + * The class name added to the listing item icon cell. + */ +const ITEM_PROJECT_ICON_CLASS = 'jp-DirListing-project-itemIcon'; + +/** + * The class name added to the listing item modified cell. + */ +const ITEM_MODIFIED_CLASS = 'jp-DirListing-itemModified'; + +/** + * The class name added to the dir listing editor node. + */ +const EDITOR_CLASS = 'jp-DirListing-editor'; + +/** + * The class name added to the name column header cell. + */ +const NAME_ID_CLASS = 'jp-id-name'; + +/** + * The class name added to the modified column header cell. + */ +const MODIFIED_ID_CLASS = 'jp-id-modified'; + +/** + * The class name added to the narrow column header cell. + */ +const NARROW_ID_CLASS = 'jp-id-narrow'; + +/** + * The class name added to the modified column header cell and modified item cell when hidden. + */ +const MODIFIED_COLUMN_HIDDEN = 'jp-LastModified-hidden'; + +/** + * The mime type for a contents drag object. + */ +const CONTENTS_MIME = 'application/x-jupyter-icontents'; + +/** + * The mime type for a rich contents drag object. + */ +const CONTENTS_MIME_RICH = 'application/x-jupyter-icontentsrich'; + +/** + * The class name added to drop targets. + */ +const DROP_TARGET_CLASS = 'jp-mod-dropTarget'; + +/** + * The class name added to selected rows. + */ +const SELECTED_CLASS = 'jp-mod-selected'; + +/** + * The class name added to drag state icons to add space between the icon and the file name + */ +const DRAG_ICON_CLASS = 'jp-DragIcon'; + +/** + * The class name added to the widget when there are items on the clipboard. + */ +const CLIPBOARD_CLASS = 'jp-mod-clipboard'; + +/** + * The class name added to cut rows. + */ +const CUT_CLASS = 'jp-mod-cut'; + +/** + * The class name added when there are more than one selected rows. + */ +const MULTI_SELECTED_CLASS = 'jp-mod-multiSelected'; + +/** + * The class name added to indicate running notebook. + */ +const RUNNING_CLASS = 'jp-mod-running'; + +/** + * The class name added for a decending sort. + */ +const DESCENDING_CLASS = 'jp-mod-descending'; + +/** + * The maximum duration between two key presses when selecting files by prefix. + */ +const PREFIX_APPEND_DURATION = 1000; + +/** + * The threshold in pixels to start a drag event. + */ +const DRAG_THRESHOLD = 5; + +/** + * A boolean indicating whether the platform is Mac. + */ +const IS_MAC = !!navigator.platform.match(/Mac/i); + +/** + * The factory MIME type supported by lumino dock panels. + */ +const FACTORY_MIME = 'application/vnd.lumino.widget-factory'; + +/** + * A widget which hosts a file list area. + * + * The main methods modified for SWAN are: + * -> onUpdateRequest + * -> updateItemNode + */ +export class SwanDirListing extends Widget { + /** + * Construct a new file browser directory listing widget. + * + * @param options - The file browser view model. + */ + constructor(options: SwanDirListing.IOptions) { + super({ + node: (options.renderer || SwanDirListing.defaultRenderer).createNode() + }); + this.addClass(DIR_LISTING_CLASS); + this.translator = options.translator || nullTranslator; + this._trans = this.translator.load('jupyterlab'); + this._model = options.model; + this._model.fileChanged.connect(this._onFileChanged, this); + this._model.refreshed.connect(this._onModelRefreshed, this); + this._model.pathChanged.connect(this._onPathChanged, this); + this._editNode = document.createElement('input'); + this._editNode.className = EDITOR_CLASS; + this._manager = this._model.manager; + this._renderer = options.renderer || SwanDirListing.defaultRenderer; + + const headerNode = DOMUtils.findElement(this.node, HEADER_CLASS); + this._renderer.populateHeaderNode( + headerNode, + this.translator, + this._hiddenColumns + ); + this._manager.activateRequested.connect(this._onActivateRequested, this); + } + + /** + * Dispose of the resources held by the directory listing. + */ + dispose(): void { + this._items.length = 0; + this._sortedItems.length = 0; + this._clipboard.length = 0; + super.dispose(); + } + + /** + * Get the model used by the listing. + */ + get model(): SwanFileBrowserModel { + return this._model; + } + + /** + * Get the dir listing header node. + * + * #### Notes + * This is the node which holds the header cells. + * + * Modifying this node directly can lead to undefined behavior. + */ + get headerNode(): HTMLElement { + return DOMUtils.findElement(this.node, HEADER_CLASS); + } + + /** + * Get the dir listing content node. + * + * #### Notes + * This is the node which holds the item nodes. + * + * Modifying this node directly can lead to undefined behavior. + */ + get contentNode(): HTMLElement { + return DOMUtils.findElement(this.node, CONTENT_CLASS); + } + + /** + * The renderer instance used by the directory listing. + */ + get renderer(): SwanDirListing.IRenderer { + return this._renderer; + } + + /** + * The current sort state. + */ + get sortState(): SwanDirListing.ISortState { + return this._sortState; + } + + /** + * A signal fired when an item is opened. + */ + get onItemOpened(): ISignal { + return this._onItemOpened; + } + + /** + * Create an iterator over the listing's selected items. + * + * @returns A new iterator over the listing's selected items. + */ + selectedItems(): IIterator { + const items = this._sortedItems; + return filter(items, item => this.selection[item.path]); + } + + /** + * Create an iterator over the listing's sorted items. + * + * @returns A new iterator over the listing's sorted items. + */ + sortedItems(): IIterator { + return new ArrayIterator(this._sortedItems); + } + + /** + * Sort the items using a sort condition. + */ + sort(state: SwanDirListing.ISortState): void { + this._sortedItems = Private.sort(this.model.items(), state); + this._sortState = state; + this.update(); + } + + /** + * Rename the first currently selected item. + * + * @returns A promise that resolves with the new name of the item. + */ + rename(): Promise { + return this._doRename(); + } + + /** + * Cut the selected items. + */ + cut(): void { + this._isCut = true; + this._copy(); + this.update(); + } + + /** + * Copy the selected items. + */ + copy(): void { + this._copy(); + } + + /** + * Paste the items from the clipboard. + * + * @returns A promise that resolves when the operation is complete. + */ + paste(): Promise { + if (!this._clipboard.length) { + this._isCut = false; + return Promise.resolve(undefined); + } + + const basePath = this._model.path; + const promises: Promise[] = []; + + each(this._clipboard, path => { + if (this._isCut) { + const parts = path.split('/'); + const name = parts[parts.length - 1]; + const newPath = PathExt.join(basePath, name); + promises.push(this._model.manager.rename(path, newPath)); + } else { + promises.push(this._model.manager.copy(path, basePath)); + } + }); + + // Remove any cut modifiers. + each(this._items, item => { + item.classList.remove(CUT_CLASS); + }); + + this._clipboard.length = 0; + this._isCut = false; + this.removeClass(CLIPBOARD_CLASS); + return Promise.all(promises) + .then(() => { + return undefined; + }) + .catch(error => { + void showErrorMessage( + this._trans._p('showErrorMessage', 'Paste Error'), + error + ); + }); + } + + /** + * Delete the currently selected item(s). + * + * @returns A promise that resolves when the operation is complete. + */ + async delete(): Promise { + const items = this._sortedItems.filter(item => this.selection[item.path]); + + if (!items.length) { + return; + } + + const message = + items.length === 1 + ? this._trans.__( + 'Are you sure you want to permanently delete: %1?', + items[0].name + ) + : this._trans._n( + 'Are you sure you want to permanently delete the %1 selected item?', + 'Are you sure you want to permanently delete the %1 selected items?', + items.length + ); + const result = await showDialog({ + title: this._trans.__('Delete'), + body: message, + buttons: [ + Dialog.cancelButton({ label: this._trans.__('Cancel') }), + Dialog.warnButton({ label: this._trans.__('Delete') }) + ], + // By default focus on "Cancel" to protect from accidental deletion + // ("delete" and "Enter" are next to each other on many keyboards). + defaultButton: 0 + }); + + if (!this.isDisposed && result.button.accept) { + await this._delete(items.map(item => item.path)); + } + } + + /** + * Duplicate the currently selected item(s). + * + * @returns A promise that resolves when the operation is complete. + */ + duplicate(): Promise { + const basePath = this._model.path; + const promises: Promise[] = []; + + each(this.selectedItems(), item => { + if (item.type !== 'directory') { + promises.push(this._model.manager.copy(item.path, basePath)); + } + }); + return Promise.all(promises) + .then(() => { + return undefined; + }) + .catch(error => { + void showErrorMessage( + this._trans._p('showErrorMessage', 'Duplicate file'), + error + ); + }); + } + + /** + * Download the currently selected item(s). + */ + async download(): Promise { + await Promise.all( + toArray(this.selectedItems()) + .filter(item => item.type !== 'directory') + .map(item => this._model.download(item.path)) + ); + } + + /** + * Shut down kernels on the applicable currently selected items. + * + * @returns A promise that resolves when the operation is complete. + */ + shutdownKernels(): Promise { + const model = this._model; + const items = this._sortedItems; + const paths = items.map(item => item.path); + + const promises = toArray(this._model.sessions()) + .filter(session => { + const index = ArrayExt.firstIndexOf(paths, session.path); + return this.selection[items[index].path]; + }) + .map(session => model.manager.services.sessions.shutdown(session.id)); + + return Promise.all(promises) + .then(() => { + return undefined; + }) + .catch(error => { + void showErrorMessage( + this._trans._p('showErrorMessage', 'Shut down kernel'), + error + ); + }); + } + + /** + * Select next item. + * + * @param keepExisting - Whether to keep the current selection and add to it. + */ + selectNext(keepExisting = false): void { + let index = -1; + const selected = Object.keys(this.selection); + const items = this._sortedItems; + if (selected.length === 1 || keepExisting) { + // Select the next item. + const path = selected[selected.length - 1]; + index = ArrayExt.findFirstIndex(items, value => value.path === path); + index += 1; + if (index === this._items.length) { + index = 0; + } + } else if (selected.length === 0) { + // Select the first item. + index = 0; + } else { + // Select the last selected item. + const path = selected[selected.length - 1]; + index = ArrayExt.findFirstIndex(items, value => value.path === path); + } + if (index !== -1) { + this._selectItem(index, keepExisting); + ElementExt.scrollIntoViewIfNeeded(this.contentNode, this._items[index]); + } + } + + /** + * Select previous item. + * + * @param keepExisting - Whether to keep the current selection and add to it. + */ + selectPrevious(keepExisting = false): void { + let index = -1; + const selected = Object.keys(this.selection); + const items = this._sortedItems; + if (selected.length === 1 || keepExisting) { + // Select the previous item. + const path = selected[0]; + index = ArrayExt.findFirstIndex(items, value => value.path === path); + index -= 1; + if (index === -1) { + index = this._items.length - 1; + } + } else if (selected.length === 0) { + // Select the last item. + index = this._items.length - 1; + } else { + // Select the first selected item. + const path = selected[0]; + index = ArrayExt.findFirstIndex(items, value => value.path === path); + } + if (index !== -1) { + this._selectItem(index, keepExisting); + ElementExt.scrollIntoViewIfNeeded(this.contentNode, this._items[index]); + } + } + + /** + * Select the first item that starts with prefix being typed. + */ + selectByPrefix(): void { + const prefix = this._searchPrefix.toLowerCase(); + const items = this._sortedItems; + + const index = ArrayExt.findFirstIndex(items, value => { + return value.name.toLowerCase().substr(0, prefix.length) === prefix; + }); + + if (index !== -1) { + this._selectItem(index, false); + ElementExt.scrollIntoViewIfNeeded(this.contentNode, this._items[index]); + } + } + + /** + * Get whether an item is selected by name. + * + * @param name - The name of of the item. + * + * @returns Whether the item is selected. + */ + isSelected(name: string): boolean { + const items = this._sortedItems; + + return ( + toArray( + filter(items, item => item.name === name && this.selection[item.path]) + ).length !== 0 + ); + } + + /** + * Find a model given a click. + * + * @param event - The mouse event. + * + * @returns The model for the selected file. + */ + modelForClick(event: MouseEvent): Contents.IModel | undefined { + const items = this._sortedItems; + const index = Private.hitTestNodes(this._items, event); + if (index !== -1) { + return items[index]; + } + return undefined; + } + + /** + * Clear the selected items. + */ + clearSelectedItems(): void { + this.selection = Object.create(null); + } + + /** + * Select an item by name. + * + * @param name - The name of the item to select. + * @param focus - Whether to move focus the selected item. + * + * @returns A promise that resolves when the name is selected. + */ + async selectItemByName(name: string, focus = false): Promise { + // Make sure the file is available. + await this.model.refresh(); + + if (this.isDisposed) { + throw new Error('File browser is disposed.'); + } + const items = this._sortedItems; + const index = ArrayExt.findFirstIndex(items, value => value.name === name); + if (index === -1) { + throw new Error('Item does not exist.'); + } + this._selectItem(index, false, focus); + MessageLoop.sendMessage(this, Widget.Msg.UpdateRequest); + ElementExt.scrollIntoViewIfNeeded(this.contentNode, this._items[index]); + } + + /** + * Handle the DOM events for the directory listing. + * + * @param event - The DOM event sent to the widget. + * + * #### Notes + * This method implements the DOM `EventListener` interface and is + * called in response to events on the panel's DOM node. It should + * not be called directly by user code. + */ + handleEvent(event: Event): void { + switch (event.type) { + case 'mousedown': + this._evtMousedown(event as MouseEvent); + break; + case 'mouseup': + this._evtMouseup(event as MouseEvent); + break; + case 'mousemove': + this._evtMousemove(event as MouseEvent); + break; + case 'keydown': + this._evtKeydown(event as KeyboardEvent); + break; + case 'click': + this._evtClick(event as MouseEvent); + break; + case 'dblclick': + this._evtDblClick(event as MouseEvent); + break; + case 'dragenter': + case 'dragover': + this.addClass('jp-mod-native-drop'); + event.preventDefault(); + break; + case 'dragleave': + case 'dragend': + this.removeClass('jp-mod-native-drop'); + break; + case 'drop': + this.removeClass('jp-mod-native-drop'); + this._evtNativeDrop(event as DragEvent); + break; + case 'scroll': + this._evtScroll(event as MouseEvent); + break; + case 'lm-dragenter': + this._evtDragEnter(event as IDragEvent); + break; + case 'lm-dragleave': + this._evtDragLeave(event as IDragEvent); + break; + case 'lm-dragover': + this._evtDragOver(event as IDragEvent); + break; + case 'lm-drop': + this._evtDrop(event as IDragEvent); + break; + default: + break; + } + } + + /** + * A message handler invoked on an `'after-attach'` message. + */ + protected onAfterAttach(msg: Message): void { + super.onAfterAttach(msg); + const node = this.node; + const content = DOMUtils.findElement(node, CONTENT_CLASS); + node.addEventListener('mousedown', this); + node.addEventListener('keydown', this); + node.addEventListener('click', this); + node.addEventListener('dblclick', this); + content.addEventListener('dragenter', this); + content.addEventListener('dragover', this); + content.addEventListener('dragleave', this); + content.addEventListener('dragend', this); + content.addEventListener('drop', this); + content.addEventListener('scroll', this); + content.addEventListener('lm-dragenter', this); + content.addEventListener('lm-dragleave', this); + content.addEventListener('lm-dragover', this); + content.addEventListener('lm-drop', this); + } + + /** + * A message handler invoked on a `'before-detach'` message. + */ + protected onBeforeDetach(msg: Message): void { + super.onBeforeDetach(msg); + const node = this.node; + const content = DOMUtils.findElement(node, CONTENT_CLASS); + node.removeEventListener('mousedown', this); + node.removeEventListener('keydown', this); + node.removeEventListener('click', this); + node.removeEventListener('dblclick', this); + content.removeEventListener('scroll', this); + content.removeEventListener('dragover', this); + content.removeEventListener('dragover', this); + content.removeEventListener('dragleave', this); + content.removeEventListener('dragend', this); + content.removeEventListener('drop', this); + content.removeEventListener('lm-dragenter', this); + content.removeEventListener('lm-dragleave', this); + content.removeEventListener('lm-dragover', this); + content.removeEventListener('lm-drop', this); + document.removeEventListener('mousemove', this, true); + document.removeEventListener('mouseup', this, true); + } + + /** + * A message handler invoked on an `'after-show'` message. + */ + protected onAfterShow(msg: Message): void { + if (this._isDirty) { + // Update the sorted items. + this.sort(this.sortState); + this.update(); + } + } + + /** + * A handler invoked on an `'update-request'` message. + */ + protected onUpdateRequest(msg: Message): void { + this._isDirty = false; + // Fetch common variables. + const items = this._sortedItems; + const nodes = this._items; + const content = DOMUtils.findElement(this.node, CONTENT_CLASS); + const renderer = this._renderer; + + this.removeClass(MULTI_SELECTED_CLASS); + this.removeClass(SELECTED_CLASS); + + // Remove any excess item nodes. + while (nodes.length > items.length) { + content.removeChild(nodes.pop()!); // eslint-disable-line @typescript-eslint/no-non-null-assertion + } + + // Add any missing item nodes. + while (nodes.length < items.length) { + const node = renderer.createItemNode(this._hiddenColumns); + node.classList.add(ITEM_CLASS); + nodes.push(node); + content.appendChild(node); + } + + // Remove extra classes from the nodes. + nodes.forEach(item => { + item.classList.remove(SELECTED_CLASS); + item.classList.remove(RUNNING_CLASS); + item.classList.remove(CUT_CLASS); + }); + + // Add extra classes to item nodes based on widget state. + items.forEach((item, i) => { + const node = nodes[i]; + const ft = this._manager.registry.getFileTypeForModel(item); + const swan_item = item as ISwanModel; + renderer.updateItemNode( + node, + item, + ft, + this.translator, + this._hiddenColumns, + swan_item.is_project === true && swan_item.type === 'directory' + ); + if (this.selection[item.path]) { + node.classList.add(SELECTED_CLASS); + + if (this._isCut && this._model.path === this._prevPath) { + node.classList.add(CUT_CLASS); + } + } + // add metadata to the node + node.setAttribute( + 'data-isdir', + item.type === 'directory' ? 'true' : 'false' + ); + }); + + // Handle the selectors on the widget node. + const selected = Object.keys(this.selection).length; + if (selected) { + this.addClass(SELECTED_CLASS); + if (selected > 1) { + this.addClass(MULTI_SELECTED_CLASS); + } + } + + // Handle file session statuses. + const paths = items.map(item => item.path); + each(this._model.sessions(), session => { + const index = ArrayExt.firstIndexOf(paths, session.path); + const node = nodes[index]; + // Node may have been filtered out. + if (node) { + let name = session.kernel?.name; + const specs = this._model.specs; + + node.classList.add(RUNNING_CLASS); + if (specs && name) { + const spec = specs.kernelspecs[name]; + name = spec ? spec.display_name : 'unknown'; // FIXME-TRANS: Is this localizable? + } + node.title = this._trans.__('%1\nKernel: %2', node.title, name); + } + }); + + this._prevPath = this._model.path; + } + + onResize(msg: Widget.ResizeMessage): void { + const { width } = + msg.width === -1 ? this.node.getBoundingClientRect() : msg; + this.toggleClass('jp-DirListing-narrow', width < 250); + } + + setColumnVisibility( + name: SwanDirListing.ToggleableColumn, + visible: boolean + ): void { + if (visible) { + this._hiddenColumns.delete(name); + } else { + this._hiddenColumns.add(name); + } + + this.headerNode.innerHTML = ''; + this._renderer.populateHeaderNode( + this.headerNode, + this.translator, + this._hiddenColumns + ); + } + + /** + * Handle the `'click'` event for the widget. + */ + private _evtClick(event: MouseEvent) { + const target = event.target as HTMLElement; + + const header = this.headerNode; + if (header.contains(target)) { + const state = this.renderer.handleHeaderClick(header, event); + if (state) { + this.sort(state); + } + return; + } + } + + /** + * Handle the `'scroll'` event for the widget. + */ + private _evtScroll(event: MouseEvent): void { + this.headerNode.scrollLeft = this.contentNode.scrollLeft; + } + + /** + * Handle the `'mousedown'` event for the widget. + */ + private _evtMousedown(event: MouseEvent): void { + // Bail if clicking within the edit node + if (event.target === this._editNode) { + return; + } + + // Blur the edit node if necessary. + if (this._editNode.parentNode) { + if (this._editNode !== (event.target as HTMLElement)) { + this._editNode.focus(); + this._editNode.blur(); + clearTimeout(this._selectTimer); + } else { + return; + } + } + + const index = Private.hitTestNodes(this._items, event); + + if (index === -1) { + return; + } + + this.handleFileSelect(event); + + if (event.button !== 0) { + clearTimeout(this._selectTimer); + } + + // Check for clearing a context menu. + const newContext = (IS_MAC && event.ctrlKey) || event.button === 2; + if (newContext) { + return; + } + + // Left mouse press for drag start. + if (event.button === 0) { + this._dragData = { + pressX: event.clientX, + pressY: event.clientY, + index: index + }; + document.addEventListener('mouseup', this, true); + document.addEventListener('mousemove', this, true); + } + } + + /** + * Handle the `'mouseup'` event for the widget. + */ + private _evtMouseup(event: MouseEvent): void { + // Handle any soft selection from the previous mouse down. + if (this._softSelection) { + const altered = event.metaKey || event.shiftKey || event.ctrlKey; + // See if we need to clear the other selection. + if (!altered && event.button === 0) { + this.clearSelectedItems(); + this.selection[this._softSelection] = true; + this.update(); + } + this._softSelection = ''; + } + // Re-focus the selected file. This is needed because nodes corresponding + // to files selected in mousedown handler will not retain the focus + // as mousedown event is always followed by a blur/focus event. + if (event.button === 0) { + this._focusSelectedFile(); + } + + // Remove the drag listeners if necessary. + if (event.button !== 0 || !this._drag) { + document.removeEventListener('mousemove', this, true); + document.removeEventListener('mouseup', this, true); + return; + } + event.preventDefault(); + event.stopPropagation(); + } + + /** + * Handle the `'mousemove'` event for the widget. + */ + private _evtMousemove(event: MouseEvent): void { + event.preventDefault(); + event.stopPropagation(); + + // Bail if we are the one dragging. + if (this._drag || !this._dragData) { + return; + } + + // Check for a drag initialization. + const data = this._dragData; + const dx = Math.abs(event.clientX - data.pressX); + const dy = Math.abs(event.clientY - data.pressY); + if (dx < DRAG_THRESHOLD && dy < DRAG_THRESHOLD) { + return; + } + + this._startDrag(data.index, event.clientX, event.clientY); + } + + /** + * Handle the opening of an item. + */ + protected handleOpen(item: Contents.IModel): void { + this._onItemOpened.emit(item); + if (item.type === 'directory') { + const localPath = this._manager.services.contents.localPath(item.path); + this._model + .cd(`/${localPath}`) + .catch(error => + showErrorMessage( + this._trans._p('showErrorMessage', 'Open directory'), + error + ) + ); + } else { + const path = item.path; + this._manager.openOrReveal(path); + } + } + + /** + * Handle the `'keydown'` event for the widget. + */ + private _evtKeydown(event: KeyboardEvent): void { + switch (event.keyCode) { + case 13: { + // Enter + // Do nothing if any modifier keys are pressed. + if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey) { + return; + } + event.preventDefault(); + event.stopPropagation(); + + const selected = Object.keys(this.selection); + const path = selected[0]; + const items = this._sortedItems; + const i = ArrayExt.findFirstIndex(items, value => value.path === path); + if (i === -1) { + return; + } + + const item = this._sortedItems[i]; + this.handleOpen(item); + break; + } + case 38: // Up arrow + this.selectPrevious(event.shiftKey); + event.stopPropagation(); + event.preventDefault(); + break; + case 40: // Down arrow + this.selectNext(event.shiftKey); + event.stopPropagation(); + event.preventDefault(); + break; + default: + break; + } + + // Detects printable characters typed by the user. + // Not all browsers support .key, but it discharges us from reconstructing + // characters from key codes. + if (!this._inRename && event.key !== undefined && event.key.length === 1) { + if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey) { + return; + } + this._searchPrefix += event.key; + + clearTimeout(this._searchPrefixTimer); + this._searchPrefixTimer = window.setTimeout(() => { + this._searchPrefix = ''; + }, PREFIX_APPEND_DURATION); + + this.selectByPrefix(); + event.stopPropagation(); + event.preventDefault(); + } + } + + /** + * Handle the `'dblclick'` event for the widget. + */ + private _evtDblClick(event: MouseEvent): void { + // Do nothing if it's not a left mouse press. + if (event.button !== 0) { + return; + } + + // Do nothing if any modifier keys are pressed. + if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey) { + return; + } + + // Stop the event propagation. + event.preventDefault(); + event.stopPropagation(); + + clearTimeout(this._selectTimer); + this._editNode.blur(); + + // Find a valid double click target. + const target = event.target as HTMLElement; + const i = ArrayExt.findFirstIndex(this._items, node => + node.contains(target) + ); + if (i === -1) { + return; + } + + const item = this._sortedItems[i]; + this.handleOpen(item); + } + + /** + * Handle the `drop` event for the widget. + */ + private _evtNativeDrop(event: DragEvent): void { + const files = event.dataTransfer?.files; + if (!files || files.length === 0) { + return; + } + const length = event.dataTransfer?.items.length; + if (!length) { + return; + } + for (let i = 0; i < length; i++) { + const entry = event.dataTransfer?.items[i].webkitGetAsEntry(); + if (entry.isDirectory) { + console.log('currently not supporting drag + drop for folders'); + void showDialog({ + title: this._trans.__('Error Uploading Folder'), + body: this._trans.__( + 'Drag and Drop is currently not supported for folders' + ), + buttons: [Dialog.cancelButton({ label: this._trans.__('Close') })] + }); + } + } + event.preventDefault(); + for (let i = 0; i < files.length; i++) { + void this._model.upload(files[i]); + } + } + + /** + * Handle the `'lm-dragenter'` event for the widget. + */ + private _evtDragEnter(event: IDragEvent): void { + if (event.mimeData.hasData(CONTENTS_MIME)) { + const index = Private.hitTestNodes(this._items, event); + if (index === -1) { + return; + } + const item = this._sortedItems[index]; + if (item.type !== 'directory' || this.selection[item.path]) { + return; + } + const target = event.target as HTMLElement; + target.classList.add(DROP_TARGET_CLASS); + event.preventDefault(); + event.stopPropagation(); + } + } + + /** + * Handle the `'lm-dragleave'` event for the widget. + */ + private _evtDragLeave(event: IDragEvent): void { + event.preventDefault(); + event.stopPropagation(); + const dropTarget = DOMUtils.findElement(this.node, DROP_TARGET_CLASS); + if (dropTarget) { + dropTarget.classList.remove(DROP_TARGET_CLASS); + } + } + + /** + * Handle the `'lm-dragover'` event for the widget. + */ + private _evtDragOver(event: IDragEvent): void { + event.preventDefault(); + event.stopPropagation(); + event.dropAction = event.proposedAction; + const dropTarget = DOMUtils.findElement(this.node, DROP_TARGET_CLASS); + if (dropTarget) { + dropTarget.classList.remove(DROP_TARGET_CLASS); + } + const index = Private.hitTestNodes(this._items, event); + this._items[index].classList.add(DROP_TARGET_CLASS); + } + + /** + * Handle the `'lm-drop'` event for the widget. + */ + private _evtDrop(event: IDragEvent): void { + event.preventDefault(); + event.stopPropagation(); + clearTimeout(this._selectTimer); + if (event.proposedAction === 'none') { + event.dropAction = 'none'; + return; + } + if (!event.mimeData.hasData(CONTENTS_MIME)) { + return; + } + + let target = event.target as HTMLElement; + while (target && target.parentElement) { + if (target.classList.contains(DROP_TARGET_CLASS)) { + target.classList.remove(DROP_TARGET_CLASS); + break; + } + target = target.parentElement; + } + + // Get the path based on the target node. + const index = ArrayExt.firstIndexOf(this._items, target); + const items = this._sortedItems; + let basePath = this._model.path; + if (items[index].type === 'directory') { + basePath = PathExt.join(basePath, items[index].name); + } + const manager = this._manager; + + // Handle the items. + const promises: Promise[] = []; + const paths = event.mimeData.getData(CONTENTS_MIME) as string[]; + + if (event.ctrlKey && event.proposedAction === 'move') { + event.dropAction = 'copy'; + } else { + event.dropAction = event.proposedAction; + } + for (const path of paths) { + const localPath = manager.services.contents.localPath(path); + const name = PathExt.basename(localPath); + const newPath = PathExt.join(basePath, name); + // Skip files that are not moving. + if (newPath === path) { + continue; + } + + if (event.dropAction === 'copy') { + promises.push(manager.copy(path, basePath)); + } else { + promises.push(renameFile(manager, path, newPath)); + } + } + Promise.all(promises).catch(error => { + void showErrorMessage( + this._trans._p('showErrorMessage', 'Error while copying/moving files'), + error + ); + }); + } + + /** + * Start a drag event. + */ + private _startDrag(index: number, clientX: number, clientY: number): void { + let selectedPaths = Object.keys(this.selection); + const source = this._items[index]; + const items = this._sortedItems; + let selectedItems: Contents.IModel[]; + let item: Contents.IModel | undefined; + + // If the source node is not selected, use just that node. + if (!source.classList.contains(SELECTED_CLASS)) { + item = items[index]; + selectedPaths = [item.path]; + selectedItems = [item]; + } else { + const path = selectedPaths[0]; + item = find(items, value => value.path === path); + selectedItems = toArray(this.selectedItems()); + } + + if (!item) { + return; + } + + // Create the drag image. + const ft = this._manager.registry.getFileTypeForModel(item); + const dragImage = this.renderer.createDragImage( + source, + selectedPaths.length, + this._trans, + ft + ); + + // Set up the drag event. + this._drag = new Drag({ + dragImage, + mimeData: new MimeData(), + supportedActions: 'move', + proposedAction: 'move' + }); + + this._drag.mimeData.setData(CONTENTS_MIME, selectedPaths); + + // Add thunks for getting mime data content. + // We thunk the content so we don't try to make a network call + // when it's not needed. E.g. just moving files around + // in a filebrowser + const services = this.model.manager.services; + for (const item of selectedItems) { + this._drag.mimeData.setData(CONTENTS_MIME_RICH, { + model: item, + withContent: async () => { + return await services.contents.get(item.path); + } + } as SwanDirListing.IContentsThunk); + } + + if (item && item.type !== 'directory') { + const otherPaths = selectedPaths.slice(1).reverse(); + this._drag.mimeData.setData(FACTORY_MIME, () => { + if (!item) { + return; + } + const path = item.path; + let widget = this._manager.findWidget(path); + if (!widget) { + widget = this._manager.open(item.path); + } + if (otherPaths.length) { + const firstWidgetPlaced = new PromiseDelegate(); + void firstWidgetPlaced.promise.then(() => { + let prevWidget = widget; + otherPaths.forEach(path => { + const options: DocumentRegistry.IOpenOptions = { + ref: prevWidget?.id, + mode: 'tab-after' + }; + prevWidget = this._manager.openOrReveal( + path, + void 0, + void 0, + options + ); + this._manager.openOrReveal(item!.path); // eslint-disable-line @typescript-eslint/no-non-null-assertion + }); + }); + firstWidgetPlaced.resolve(void 0); + } + return widget; + }); + } + + // Start the drag and remove the mousemove and mouseup listeners. + document.removeEventListener('mousemove', this, true); + document.removeEventListener('mouseup', this, true); + clearTimeout(this._selectTimer); + void this._drag.start(clientX, clientY).then(action => { + this._drag = null; + clearTimeout(this._selectTimer); + }); + } + + /** + * Handle selection on a file node. + */ + protected handleFileSelect(event: MouseEvent): void { + // Fetch common variables. + const items = this._sortedItems; + const index = Private.hitTestNodes(this._items, event); + + clearTimeout(this._selectTimer); + + if (index === -1) { + return; + } + + // Clear any existing soft selection. + this._softSelection = ''; + + const path = items[index].path; + const selected = Object.keys(this.selection); + + // Handle toggling. + if ((IS_MAC && event.metaKey) || (!IS_MAC && event.ctrlKey)) { + if (this.selection[path]) { + delete this.selection[path]; + } else { + this.selection[path] = true; + } + + // Handle multiple select. + } else if (event.shiftKey) { + this._handleMultiSelect(selected, index); + + // Handle a 'soft' selection + } else if (path in this.selection && selected.length > 1) { + this._softSelection = path; + + // Default to selecting the only the item. + } else { + // Select only the given item. + return this._selectItem(index, false); + } + this.update(); + } + + /** + * (Re-)focus on the selected file. + * + * If index is not given, it will be inferred from the current selection; + * providing index saves on the iteration time. + */ + private _focusSelectedFile(index?: number): void { + if (typeof index === 'undefined') { + const selected = Object.keys(this.selection); + if (selected.length > 1) { + // Multiselect - do not focus on any single file + return; + } + index = ArrayExt.findFirstIndex( + this._sortedItems, + value => value.path === selected[0] + ); + } + if (index === -1) { + return; + } + // Focus on text to make shortcuts works + const node = this._items[index]; + const text = DOMUtils.findElement(node, ITEM_TEXT_CLASS); + if (text) { + text.focus(); + } + } + + /** + * Handle a multiple select on a file item node. + */ + private _handleMultiSelect(selected: string[], index: number): void { + // Find the "nearest selected". + const items = this._sortedItems; + let nearestIndex = -1; + for (let i = 0; i < this._items.length; i++) { + if (i === index) { + continue; + } + const path = items[i].path; + if (selected.indexOf(path) !== -1) { + if (nearestIndex === -1) { + nearestIndex = i; + } else { + if (Math.abs(index - i) < Math.abs(nearestIndex - i)) { + nearestIndex = i; + } + } + } + } + + // Default to the first element (and fill down). + if (nearestIndex === -1) { + nearestIndex = 0; + } + + // Select the rows between the current and the nearest selected. + for (let i = 0; i < this._items.length; i++) { + if ( + (nearestIndex >= i && index <= i) || + (nearestIndex <= i && index >= i) + ) { + this.selection[items[i].path] = true; + } + } + } + + /** + * Copy the selected items, and optionally cut as well. + */ + private _copy(): void { + this._clipboard.length = 0; + each(this.selectedItems(), item => { + this._clipboard.push(item.path); + }); + } + + /** + * Delete the files with the given paths. + */ + private async _delete(paths: string[]): Promise { + await Promise.all( + paths.map(path => + this._model.manager.deleteFile(path).catch(err => { + void showErrorMessage( + this._trans._p('showErrorMessage', 'Delete Failed'), + err + ); + }) + ) + ); + } + + /** + * Allow the user to rename item on a given row. + */ + private _doRename(): Promise { + this._inRename = true; + const items = this._sortedItems; + const path = Object.keys(this.selection)[0]; + const index = ArrayExt.findFirstIndex(items, value => value.path === path); + const row = this._items[index]; + const item = items[index]; + const nameNode = this.renderer.getNameNode(row); + const original = item.name; + this._editNode.value = original; + this._selectItem(index, false); + + return Private.doRename(nameNode, this._editNode, original).then( + newName => { + this.node.focus(); + if (!newName || newName === original) { + this._inRename = false; + return original; + } + if (!isValidFileName(newName)) { + void showErrorMessage( + this._trans.__('showErrorMessage', 'Rename Error'), + Error( + this._trans._p( + 'showErrorMessage', + '"%1" is not a valid name for a file. Names must have nonzero length, and cannot include "/", "\\", or ":"', + newName + ) + ) + ); + this._inRename = false; + return original; + } + + if (this.isDisposed) { + this._inRename = false; + throw new Error('File browser is disposed.'); + } + + const manager = this._manager; + const oldPath = PathExt.join(this._model.path, original); + const newPath = PathExt.join(this._model.path, newName); + const promise = renameFile(manager, oldPath, newPath); + return promise + .catch(error => { + if (error !== 'File not renamed') { + void showErrorMessage( + this._trans._p('showErrorMessage', 'Rename Error'), + error + ); + } + this._inRename = false; + return original; + }) + .then(() => { + if (this.isDisposed) { + this._inRename = false; + throw new Error('File browser is disposed.'); + } + if (this._inRename) { + // No need to catch because `newName` will always exit. + void this.selectItemByName(newName); + } + this._inRename = false; + return newName; + }); + } + ); + } + + /** + * Select a given item. + */ + private _selectItem(index: number, keepExisting: boolean, focus = true) { + // Selected the given row(s) + const items = this._sortedItems; + if (!keepExisting) { + this.clearSelectedItems(); + } + const path = items[index].path; + this.selection[path] = true; + + if (!keepExisting && focus) { + this._focusSelectedFile(index); + } + this.update(); + } + + /** + * Handle the `refreshed` signal from the model. + */ + private _onModelRefreshed(): void { + // Update the selection. + const existing = Object.keys(this.selection); + this.clearSelectedItems(); + each(this._model.items(), item => { + const path = item.path; + if (existing.indexOf(path) !== -1) { + this.selection[path] = true; + } + }); + if (this.isVisible) { + // Update the sorted items. + this.sort(this.sortState); + } else { + this._isDirty = true; + } + } + + /** + * Handle a `pathChanged` signal from the model. + */ + private _onPathChanged(): void { + // Reset the selection. + this.clearSelectedItems(); + // Update the sorted items. + this.sort(this.sortState); + } + + /** + * Handle a `fileChanged` signal from the model. + */ + private _onFileChanged( + sender: SwanFileBrowserModel, + args: Contents.IChangedArgs + ) { + const newValue = args.newValue; + if (!newValue) { + return; + } + + const name = newValue.name; + if (args.type !== 'new' || !name) { + return; + } + + void this.selectItemByName(name).catch(() => { + /* Ignore if file does not exist. */ + }); + } + + /** + * Handle an `activateRequested` signal from the manager. + */ + private _onActivateRequested(sender: IDocumentManager, args: string): void { + const dirname = PathExt.dirname(args); + if (dirname !== this._model.path) { + return; + } + const basename = PathExt.basename(args); + this.selectItemByName(basename).catch(() => { + /* Ignore if file does not exist. */ + }); + } + + protected translator: ITranslator; + protected _model: SwanFileBrowserModel; + private _trans: TranslationBundle; + private _editNode: HTMLInputElement; + private _items: HTMLElement[] = []; + private _sortedItems: Contents.IModel[] = []; + private _sortState: SwanDirListing.ISortState = { + direction: 'ascending', + key: 'name' + }; + private _onItemOpened = new Signal(this); + private _drag: Drag | null = null; + private _dragData: { + pressX: number; + pressY: number; + index: number; + } | null = null; + private _selectTimer = -1; + private _isCut = false; + private _prevPath = ''; + private _clipboard: string[] = []; + private _manager: IDocumentManager; + private _softSelection = ''; + protected selection: { [key: string]: boolean } = Object.create(null); + private _renderer: SwanDirListing.IRenderer; + private _searchPrefix = ''; + private _searchPrefixTimer = -1; + private _inRename = false; + private _isDirty = false; + private _hiddenColumns = new Set(); +} + +/** + * The namespace for the `DirListing` class statics. + */ +export namespace SwanDirListing { + /** + * An options object for initializing a file browser directory listing. + */ + export interface IOptions { + /** + * A file browser model instance. + */ + model: SwanFileBrowserModel; + + /** + * A renderer for file items. + * + * The default is a shared `Renderer` instance. + */ + renderer?: IRenderer; + + /** + * A language translator. + */ + translator?: ITranslator; + } + + /** + * A sort state. + */ + export interface ISortState { + /** + * The direction of sort. + */ + direction: 'ascending' | 'descending'; + + /** + * The sort key. + */ + key: 'name' | 'last_modified'; + } + + /** + * Toggleable columns. + */ + export type ToggleableColumn = 'last_modified'; + + /** + * A file contents model thunk. + * + * Note: The content of the model will be empty. + * To get the contents, call and await the `withContent` + * method. + */ + export interface IContentsThunk { + /** + * The contents model. + */ + model: Contents.IModel; + + /** + * Fetches the model with contents. + */ + withContent: () => Promise; + } + + /** + * The render interface for file browser listing options. + */ + export interface IRenderer { + /** + * Create the DOM node for a dir listing. + */ + createNode(): HTMLElement; + + /** + * Populate and empty header node for a dir listing. + * + * @param node - The header node to populate. + */ + populateHeaderNode( + node: HTMLElement, + translator?: ITranslator, + hiddenColumns?: Set + ): void; + + /** + * Handle a header click. + * + * @param node - A node populated by [[populateHeaderNode]]. + * + * @param event - A click event on the node. + * + * @returns The sort state of the header after the click event. + */ + handleHeaderClick(node: HTMLElement, event: MouseEvent): ISortState | null; + + /** + * Create a new item node for a dir listing. + * + * @returns A new DOM node to use as a content item. + */ + createItemNode( + hiddenColumns?: Set, + isProject?: boolean + ): HTMLElement; + + /** + * Update an item node to reflect the current state of a model. + * + * @param node - A node created by [[createItemNode]]. + * + * @param model - The model object to use for the item state. + * + * @param fileType - The file type of the item, if applicable. + */ + updateItemNode( + node: HTMLElement, + model: Contents.IModel, + fileType?: DocumentRegistry.IFileType, + translator?: ITranslator, + hiddenColumns?: Set, + isproject?: boolean + ): void; + + /** + * Get the node containing the file name. + * + * @param node - A node created by [[createItemNode]]. + * + * @returns The node containing the file name. + */ + getNameNode(node: HTMLElement): HTMLElement; + + /** + * Create an appropriate drag image for an item. + * + * @param node - A node created by [[createItemNode]]. + * + * @param count - The number of items being dragged. + * + * @param fileType - The file type of the item, if applicable. + * + * @returns An element to use as the drag image. + */ + createDragImage( + node: HTMLElement, + count: number, + trans: TranslationBundle, + fileType?: DocumentRegistry.IFileType, + isProject?: boolean + ): HTMLElement; + } + + /** + * The default implementation of an `IRenderer`. + */ + export class Renderer implements IRenderer { + /** + * Create the DOM node for a dir listing. + */ + createNode(): HTMLElement { + const node = document.createElement('div'); + const header = document.createElement('div'); + const content = document.createElement('ul'); + content.className = CONTENT_CLASS; + header.className = HEADER_CLASS; + node.appendChild(header); + node.appendChild(content); + node.tabIndex = 0; + return node; + } + + /** + * Populate and empty header node for a dir listing. + * + * @param node - The header node to populate. + */ + populateHeaderNode( + node: HTMLElement, + translator?: ITranslator, + hiddenColumns?: Set + ): void { + translator = translator || nullTranslator; + const trans = translator.load('jupyterlab'); + const name = this.createHeaderItemNode(trans.__('Name')); + const narrow = document.createElement('div'); + const modified = this.createHeaderItemNode(trans.__('Last Modified')); + name.classList.add(NAME_ID_CLASS); + name.classList.add(SELECTED_CLASS); + modified.classList.add(MODIFIED_ID_CLASS); + narrow.classList.add(NARROW_ID_CLASS); + narrow.textContent = '...'; + node.appendChild(name); + node.appendChild(narrow); + node.appendChild(modified); + + if (hiddenColumns?.has?.('last_modified')) { + modified.classList.add(MODIFIED_COLUMN_HIDDEN); + } else { + modified.classList.remove(MODIFIED_COLUMN_HIDDEN); + } + + // set the initial caret icon + Private.updateCaret( + DOMUtils.findElement(name, HEADER_ITEM_ICON_CLASS), + 'right', + 'up' + ); + } + + /** + * Handle a header click. + * + * @param node - A node populated by [[populateHeaderNode]]. + * + * @param event - A click event on the node. + * + * @returns The sort state of the header after the click event. + */ + handleHeaderClick(node: HTMLElement, event: MouseEvent): ISortState | null { + const name = DOMUtils.findElement(node, NAME_ID_CLASS); + const modified = DOMUtils.findElement(node, MODIFIED_ID_CLASS); + const state: ISortState = { direction: 'ascending', key: 'name' }; + const target = event.target as HTMLElement; + if (name.contains(target)) { + const modifiedIcon = DOMUtils.findElement( + modified, + HEADER_ITEM_ICON_CLASS + ); + const nameIcon = DOMUtils.findElement(name, HEADER_ITEM_ICON_CLASS); + + if (name.classList.contains(SELECTED_CLASS)) { + if (!name.classList.contains(DESCENDING_CLASS)) { + state.direction = 'descending'; + name.classList.add(DESCENDING_CLASS); + Private.updateCaret(nameIcon, 'right', 'down'); + } else { + name.classList.remove(DESCENDING_CLASS); + Private.updateCaret(nameIcon, 'right', 'up'); + } + } else { + name.classList.remove(DESCENDING_CLASS); + Private.updateCaret(nameIcon, 'right', 'up'); + } + name.classList.add(SELECTED_CLASS); + modified.classList.remove(SELECTED_CLASS); + modified.classList.remove(DESCENDING_CLASS); + Private.updateCaret(modifiedIcon, 'left'); + return state; + } + if (modified.contains(target)) { + const modifiedIcon = DOMUtils.findElement( + modified, + HEADER_ITEM_ICON_CLASS + ); + const nameIcon = DOMUtils.findElement(name, HEADER_ITEM_ICON_CLASS); + + state.key = 'last_modified'; + if (modified.classList.contains(SELECTED_CLASS)) { + if (!modified.classList.contains(DESCENDING_CLASS)) { + state.direction = 'descending'; + modified.classList.add(DESCENDING_CLASS); + Private.updateCaret(modifiedIcon, 'left', 'down'); + } else { + modified.classList.remove(DESCENDING_CLASS); + Private.updateCaret(modifiedIcon, 'left', 'up'); + } + } else { + modified.classList.remove(DESCENDING_CLASS); + Private.updateCaret(modifiedIcon, 'left', 'up'); + } + modified.classList.add(SELECTED_CLASS); + name.classList.remove(SELECTED_CLASS); + name.classList.remove(DESCENDING_CLASS); + Private.updateCaret(nameIcon, 'right'); + return state; + } + return state; + } + + /** + * Create a new item node for a dir listing. + * + * @returns A new DOM node to use as a content item. + */ + createItemNode( + hiddenColumns?: Set + ): HTMLElement { + const node = document.createElement('li'); + const icon = document.createElement('span'); + const text = document.createElement('span'); + const modified = document.createElement('span'); + icon.className = ITEM_ICON_CLASS; + + text.className = ITEM_TEXT_CLASS; + modified.className = ITEM_MODIFIED_CLASS; + node.appendChild(icon); + node.appendChild(text); + node.appendChild(modified); + + // Make the text note focusable so that it receives keyboard events; + // text node was specifically chosen to receive shortcuts because + // text element gets substituted with input area during file name edits + // which conveniently deactivate irrelevant shortcuts. + text.tabIndex = 0; + + if (hiddenColumns?.has?.('last_modified')) { + modified.classList.add(MODIFIED_COLUMN_HIDDEN); + } else { + modified.classList.remove(MODIFIED_COLUMN_HIDDEN); + } + return node; + } + + /** + * Update an item node to reflect the current state of a model. + * + * @param node - A node created by [[createItemNode]]. + * + * @param model - The model object to use for the item state. + * + * @param fileType - The file type of the item, if applicable. + * + */ + updateItemNode( + node: HTMLElement, + model: Contents.IModel, + fileType?: DocumentRegistry.IFileType, + translator?: ITranslator, + hiddenColumns?: Set, + isProject = false + ): void { + translator = translator || nullTranslator; + + fileType = + fileType || DocumentRegistry.getDefaultTextFileType(translator); + const { icon, iconClass, name } = fileType; + translator = translator || nullTranslator; + const trans = translator.load('jupyterlab'); + const iconContainer = DOMUtils.findElement(node, ITEM_ICON_CLASS); + const text = DOMUtils.findElement(node, ITEM_TEXT_CLASS); + const modified = DOMUtils.findElement(node, ITEM_MODIFIED_CLASS); + + if (hiddenColumns?.has?.('last_modified')) { + modified.classList.add(MODIFIED_COLUMN_HIDDEN); + } else { + modified.classList.remove(MODIFIED_COLUMN_HIDDEN); + } + + if (isProject) { + swanProjectIcon.element({ + container: iconContainer, + className: ITEM_ICON_CLASS, + stylesheet: 'listing' + }); + } else { + // render the file item's icon + LabIcon.resolveElement({ + icon, + iconClass: classes(iconClass, 'jp-Icon'), + container: iconContainer, + className: ITEM_ICON_CLASS, + stylesheet: 'listing' + }); + } + + let hoverText = trans.__('Name: %1', model.name); + + // add file size to pop up if its available + if (model.size !== null && model.size !== undefined) { + hoverText += trans.__( + '\nSize: %1', + Private.formatFileSize(model.size, 1, 1024) + ); + } + if (model.path) { + const dirname = PathExt.dirname(model.path); + if (dirname) { + hoverText += trans.__('\nPath: %1', dirname.substr(0, 50)); + if (dirname.length > 50) { + hoverText += '...'; + } + } + } + if (model.created) { + hoverText += trans.__( + '\nCreated: %1', + Time.format(new Date(model.created), 'YYYY-MM-DD HH:mm:ss') + ); + } + if (model.last_modified) { + hoverText += trans.__( + '\nModified: %1', + Time.format(new Date(model.last_modified), 'YYYY-MM-DD HH:mm:ss') + ); + } + hoverText += trans.__('\nWritable: %1', model.writable); + + node.title = hoverText; + node.setAttribute('data-file-type', name); + if (model.name.startsWith('.')) { + node.setAttribute('data-is-dot', 'true'); + } else { + node.removeAttribute('data-is-dot'); + } + // If an item is being edited currently, its text node is unavailable. + if (text) { + const indices = !model.indices ? [] : model.indices; + const highlightedName = StringExt.highlight( + model.name, + indices, + h.mark + ); + VirtualDOM.render(h.span(highlightedName), text); + } + + let modText = ''; + let modTitle = ''; + if (model.last_modified) { + modText = Time.formatHuman(new Date(model.last_modified)); + modTitle = Time.format(new Date(model.last_modified), 'lll'); + } + modified.textContent = modText; + modified.title = modTitle; + } + + /** + * Get the node containing the file name. + * + * @param node - A node created by [[createItemNode]]. + * + * @returns The node containing the file name. + */ + getNameNode(node: HTMLElement): HTMLElement { + return DOMUtils.findElement(node, ITEM_TEXT_CLASS); + } + + /** + * Create a drag image for an item. + * + * @param node - A node created by [[createItemNode]]. + * + * @param count - The number of items being dragged. + * + * @param fileType - The file type of the item, if applicable. + * + * @returns An element to use as the drag image. + */ + createDragImage( + node: HTMLElement, + count: number, + trans: TranslationBundle, + fileType?: DocumentRegistry.IFileType + ): HTMLElement { + const dragImage = node.cloneNode(true) as HTMLElement; + const modified = DOMUtils.findElement(dragImage, ITEM_MODIFIED_CLASS); + console.log('-----drag'); + console.log(node); + const isProject = node.getAttribute('is_project'); + let icon = null; + if (isProject === 'true') { + icon = DOMUtils.findElement(dragImage, ITEM_PROJECT_ICON_CLASS); + } else { + icon = DOMUtils.findElement(dragImage, ITEM_ICON_CLASS); + } + dragImage.removeChild(modified as HTMLElement); + + if (!fileType) { + icon.textContent = ''; + icon.className = ''; + } else { + icon.textContent = fileType.iconLabel || ''; + icon.className = fileType.iconClass || ''; + } + icon.classList.add(DRAG_ICON_CLASS); + + if (count > 1) { + const nameNode = DOMUtils.findElement(dragImage, ITEM_TEXT_CLASS); + nameNode.textContent = trans._n('%1 Item', '%1 Items', count); + } + return dragImage; + } + + /** + * Create a node for a header item. + */ + protected createHeaderItemNode(label: string): HTMLElement { + const node = document.createElement('div'); + const text = document.createElement('span'); + const icon = document.createElement('span'); + node.className = HEADER_ITEM_CLASS; + text.className = HEADER_ITEM_TEXT_CLASS; + icon.className = HEADER_ITEM_ICON_CLASS; + text.textContent = label; + node.appendChild(text); + node.appendChild(icon); + return node; + } + } + + /** + * The default `IRenderer` instance. + */ + export const defaultRenderer = new Renderer(); +} + +/** + * The namespace for the listing private data. + */ +namespace Private { + /** + * Handle editing text on a node. + * + * @returns Boolean indicating whether the name changed. + */ + export function doRename( + text: HTMLElement, + edit: HTMLInputElement, + original: string + ): Promise { + const parent = text.parentElement as HTMLElement; + parent.replaceChild(edit, text); + edit.focus(); + const index = edit.value.lastIndexOf('.'); + if (index === -1) { + edit.setSelectionRange(0, edit.value.length); + } else { + edit.setSelectionRange(0, index); + } + + return new Promise((resolve, reject) => { + edit.onblur = () => { + parent.replaceChild(text, edit); + resolve(edit.value); + }; + edit.onkeydown = (event: KeyboardEvent) => { + switch (event.keyCode) { + case 13: // Enter + event.stopPropagation(); + event.preventDefault(); + edit.blur(); + break; + case 27: // Escape + event.stopPropagation(); + event.preventDefault(); + edit.value = original; + edit.blur(); + break; + case 38: // Up arrow + event.stopPropagation(); + event.preventDefault(); + if (edit.selectionStart !== edit.selectionEnd) { + edit.selectionStart = edit.selectionEnd = 0; + } + break; + case 40: // Down arrow + event.stopPropagation(); + event.preventDefault(); + if (edit.selectionStart !== edit.selectionEnd) { + edit.selectionStart = edit.selectionEnd = edit.value.length; + } + break; + default: + break; + } + }; + }); + } + + /** + * Sort a list of items by sort state as a new array. + */ + export function sort( + items: IIterator, + state: SwanDirListing.ISortState + ): Contents.IModel[] { + const copy = toArray(items); + const reverse = state.direction === 'descending' ? 1 : -1; + + if (state.key === 'last_modified') { + // Sort by last modified (grouping directories first) + copy.sort((a, b) => { + const t1 = a.type === 'directory' ? 0 : 1; + const t2 = b.type === 'directory' ? 0 : 1; + + const valA = new Date(a.last_modified).getTime(); + const valB = new Date(b.last_modified).getTime(); + + return t1 - t2 || (valA - valB) * reverse; + }); + } else { + // Sort by name (grouping directories first) + copy.sort((a, b) => { + const t1 = a.type === 'directory' ? 0 : 1; + const t2 = b.type === 'directory' ? 0 : 1; + + return t1 - t2 || b.name.localeCompare(a.name) * reverse; + }); + } + return copy; + } + + /** + * Get the index of the node at a client position, or `-1`. + */ + export function hitTestNodes( + nodes: HTMLElement[], + event: MouseEvent + ): number { + return ArrayExt.findFirstIndex( + nodes, + node => + ElementExt.hitTest(node, event.clientX, event.clientY) || + event.target === node + ); + } + + /** + * Format bytes to human readable string. + */ + export function formatFileSize( + bytes: number, + decimalPoint: number, + k: number + ): string { + // https://www.codexworld.com/how-to/convert-file-size-bytes-kb-mb-gb-javascript/ + if (bytes === 0) { + return '0 Bytes'; + } + const dm = decimalPoint || 2; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + if (i >= 0 && i < sizes.length) { + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; + } else { + return String(bytes); + } + } + + /** + * Update an inline svg caret icon in a node. + */ + export function updateCaret( + container: HTMLElement, + float: 'left' | 'right', + state?: 'down' | 'up' | undefined + ): void { + if (state) { + (state === 'down' ? caretDownIcon : caretUpIcon).element({ + container, + tag: 'span', + stylesheet: 'listingHeaderItem', + + float + }); + } else { + LabIcon.remove(container); + container.className = HEADER_ITEM_ICON_CLASS; + } + } +} diff --git a/SwanFileBrowser/src/request.ts b/SwanFileBrowser/src/request.ts new file mode 100644 index 00000000..1fea3584 --- /dev/null +++ b/SwanFileBrowser/src/request.ts @@ -0,0 +1,34 @@ +import { URLExt } from '@jupyterlab/coreutils'; + +import { ServerConnection } from '@jupyterlab/services'; + +/** + * Call the API extension + * + * @param endPoint API REST end point for the extension + * @param init Initial values for the request + * @returns The response body interpreted as JSON + */ +export async function request( + endPoint = '', + init: RequestInit = {} +): Promise { + // Make request to Jupyter API + const settings = ServerConnection.makeSettings(); + const requestUrl = URLExt.join(settings.baseUrl, '', endPoint); + + let response: Response; + try { + response = await ServerConnection.makeRequest(requestUrl, init, settings); + } catch (error) { + throw new ServerConnection.NetworkError(error); + } + + const data = await response.json(); + + if (!response.ok) { + throw new ServerConnection.ResponseError(response, data.message); + } + + return data; +} diff --git a/SwanFileBrowser/src/svg.d.ts b/SwanFileBrowser/src/svg.d.ts new file mode 100644 index 00000000..81101e35 --- /dev/null +++ b/SwanFileBrowser/src/svg.d.ts @@ -0,0 +1,6 @@ +// svg.d.ts + +declare module '*.svg' { + const value: string; + export default value; +} diff --git a/SwanFileBrowser/src/swanfilebrowser.ts b/SwanFileBrowser/src/swanfilebrowser.ts new file mode 100755 index 00000000..4d0b18bd --- /dev/null +++ b/SwanFileBrowser/src/swanfilebrowser.ts @@ -0,0 +1,261 @@ +// Copyright (c) SWAN Development Team. +// Author: Omar.Zapata@cern.ch 2021 + +/** + * This file containts the implementation for SwanFileBrowser and SwanFileBrowserModel classes. + * + * Those classes are the replacement for the default FileBrowser and allows to + * manipulated the paths to check is the folder is a project or not and to set the proper kernel path. + */ + +import { FilterFileBrowserModel, FileBrowser } from '@jupyterlab/filebrowser'; +import { request } from './request'; +import { validateSpecModels } from './kernelspec/validate'; +import { SwanDirListing } from './listing'; +import { JSONObject } from '@lumino/coreutils'; +import { showErrorMessage, Dialog } from '@jupyterlab/apputils'; +import { CommandRegistry } from '@lumino/commands'; +/** + * SWAN Project options from .swanproject + * this is required to validate that the project file is not corrupted + */ +export interface ISwanProjectOptions { + name?: string; + stack?: string; + release?: string; + platform?: string; + user_script?: string; + python2?: any; + python3?: any; + kernel_dirs?: string[]; +} + +/** + * Customized SwanFileBrowserModel that inherits from FilterFileBrowserModel. + * + * This class has overloaded the method 'async cd(newValue: string): Promise' + * that a allows to take actions before go to the directory, actions like: + * 1) Get the contents of the folder (to check if the folder is a project) + * 2) If the folder is a project we can ge the information of the project stored in the .swanproject + * 3) if the information for the project is right then we can set the kernel spec manager + * 4) If the project is corrupted, the a Dialog is showed up telling the user the project requires + * to be configured again and the ProjectDialog is called. + */ +export class SwanFileBrowserModel extends FilterFileBrowserModel { + constructor( + options: FilterFileBrowserModel.IOptions, + commads: CommandRegistry + ) { + super(options); + this._commands = commads; + this.kernelSpecSetPathRequest(this.path); + } + + /** + * Request to set the kernelspec manager path in the backend. + * Local service manager.services.kernelspecs is updated as well. + * + * @param path path get information from jupyter api + * @returns json object with the information of the path or json object with the information of the error. + */ + protected kernelSpecSetPathRequest(path: string): any { + const dataToSend = { path: path, caller: 'swanfilebrowser' }; + try { + return request('/swan/kernelspec/set', { + body: JSON.stringify(dataToSend), + method: 'POST' + }).then(async (rvalue: { is_project: boolean; path: string }) => { + return request('/api/kernelspecs', { + method: 'GET' + }) + .then(specs => { + if (rvalue.is_project) { + const validate_specs = validateSpecModels(specs); + return Object.defineProperty( + this.manager.services.kernelspecs, + 'specs', + { + value: validate_specs, + configurable: true + } + ); + } else { + return Object.defineProperty( + this.manager.services.kernelspecs, + 'specs', + { + value: null, + configurable: true + } + ); + } + }) + .catch((err: any) => { + console.log(err); + }); + }); + } catch (reason) { + console.error( + `Error on POST 'swan/kernelspec/set'+ ${dataToSend}.\n${reason}` + ); + } + } + + /** + * Request to get the project information + * + * @param path path to the project + * @returns json object with the project information information. + */ + protected projectInfoRequest(path: string): any { + const uri = 'swan/project/info?caller=swanfilebrowser&path=' + path; + try { + return request(uri, { + method: 'GET' + }); + } catch (reason) { + console.error(`Error on GET ${uri}.\n${reason}`); + } + } + + /** + * Request to get contents from a path + * + * @param cwd path get information from jupyter api + * @returns json object with the information of the path + */ + protected contentRequest(cwd: string): any { + try { + return request('api/contents/' + cwd, { + method: 'GET' + }).then(rvalue => { + return rvalue; + }); + } catch (reason) { + console.error(`Error on GET 'api/contents'+ ${cwd}.\n${reason}`); + } + } + + /** + * Method to check if the project information is valid or it is corrupted. + * + * @param project_data json with project data such as name, stack, release etc.. + * @returns true if the project is valid or false it the project is corrupted. + */ + protected isValidProject(project_data: JSONObject): boolean { + for (const tag in this.project_tags) { + if (!(this.project_tags[tag] in project_data)) { + return false; + } + } + return true; + } + + /** + * Overloaded method cd, to check folder information before go in. + * + * @param newValue new path + * @returns void promise. + */ + async cd(newValue: string): Promise { + if (newValue !== '.') { + const content = await this.contentRequest(newValue); + if (content.is_project === true) { + const project_info = await this.projectInfoRequest(newValue); + const project_data = project_info[ + 'project_data' + ] as ISwanProjectOptions; + if (this.isValidProject(project_data as JSONObject)) { + await this.kernelSpecSetPathRequest(newValue); + return super.cd(newValue); + } else { + const okButton = Dialog.okButton({ accept: false }); + await showErrorMessage( + 'Project Error:', + 'Error reading the configuration of project ' + + project_data?.name + + ', please click OK to define a new one.', + [okButton] + ); + + if (okButton.accept) { + await this._commands + .execute('swan:edit-project-dialog', { + name: project_data?.name, + stack: project_data?.stack, + release: project_data?.release, + platform: project_data?.platform, + user_script: project_data?.user_script, + corrupted: true + }) + .catch(message => { + console.log(message); + }); + } + await this.kernelSpecSetPathRequest(this.path); + return super.cd('.'); // we stay in the current directory to fix the project at the moment + } + } else { + return super.cd(newValue).then(async () => { + await this.kernelSpecSetPathRequest(this.path); + }); + } + } else { + return super.cd(newValue); + } + } + private project_tags: string[] = [ + 'name', + 'stack', + 'release', + 'platform', + 'python2', + 'python3', + 'kernel_dirs' + ]; + private _commands: CommandRegistry; +} + +/** + * Customized SwanFileBrowser that inherits from FileBrowser. + * + * This class allows to set our classes SwanFileBrowserModel and SwanDirListing. + * + */ +export class SwanFileBrowser extends FileBrowser { + constructor(options: FileBrowser.IOptions) { + super(options); + super.id = options.id; + const model = (this.model = options.model); + const renderer = options.renderer; + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + this.layout.removeWidget(this._listing); + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + this._listing = this.createDirListing({ + model, + renderer, + translator: this.translator + }); + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + this.layout.addWidget(this._listing); + } + + /** + * Create the underlying SwanDirListing instance. + * + * @param options - The SwanDirListing constructor options. + * + * @returns The created SwanDirListing instance. + */ + protected createDirListing(options: SwanDirListing.IOptions): SwanDirListing { + return new SwanDirListing(options); + } + + public model: SwanFileBrowserModel; +} diff --git a/SwanFileBrowser/style/base.css b/SwanFileBrowser/style/base.css new file mode 100644 index 00000000..e69de29b diff --git a/SwanFileBrowser/style/index.css b/SwanFileBrowser/style/index.css new file mode 100644 index 00000000..6268b3ef --- /dev/null +++ b/SwanFileBrowser/style/index.css @@ -0,0 +1,5 @@ +/* @import url('~@jupyterlab/filebrowser/style/index.css'); +#filebrowser.jp-mod-restoring .jp-DirListing-content { + display: none; +} */ +@import url('base.css'); diff --git a/SwanFileBrowser/style/index.js b/SwanFileBrowser/style/index.js new file mode 100644 index 00000000..a028a764 --- /dev/null +++ b/SwanFileBrowser/style/index.js @@ -0,0 +1 @@ +import './base.css'; diff --git a/SwanFileBrowser/style/project_folder.svg b/SwanFileBrowser/style/project_folder.svg new file mode 100644 index 00000000..0a5351f4 --- /dev/null +++ b/SwanFileBrowser/style/project_folder.svg @@ -0,0 +1,54 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/SwanFileBrowser/swanfilebrowser/__init__.py b/SwanFileBrowser/swanfilebrowser/__init__.py new file mode 100644 index 00000000..63040033 --- /dev/null +++ b/SwanFileBrowser/swanfilebrowser/__init__.py @@ -0,0 +1,17 @@ + +import json +from pathlib import Path + +from ._version import __version__ + +HERE = Path(__file__).parent.resolve() + +with (HERE / "labextension" / "package.json").open() as fid: + data = json.load(fid) + +def _jupyter_labextension_paths(): + return [{ + "src": "labextension", + "dest": data["name"] + }] + diff --git a/SwanFileBrowser/swanfilebrowser/_version.py b/SwanFileBrowser/swanfilebrowser/_version.py new file mode 100644 index 00000000..351fbde5 --- /dev/null +++ b/SwanFileBrowser/swanfilebrowser/_version.py @@ -0,0 +1,18 @@ +import json +from pathlib import Path + +__all__ = ["__version__"] + +def _fetchVersion(): + HERE = Path(__file__).parent.resolve() + + for settings in HERE.rglob("package.json"): + try: + with settings.open() as f: + return json.load(f)["version"] + except FileNotFoundError: + pass + + raise FileNotFoundError(f"Could not find package.json under dir {HERE!s}") + +__version__ = _fetchVersion() diff --git a/SwanFileBrowser/tsconfig.json b/SwanFileBrowser/tsconfig.json new file mode 100644 index 00000000..fba26876 --- /dev/null +++ b/SwanFileBrowser/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "composite": true, + "declaration": true, + "esModuleInterop": true, + "incremental": true, + "jsx": "react", + "module": "esnext", + "moduleResolution": "node", + "noEmitOnError": true, + "noImplicitAny": true, + "noUnusedLocals": true, + "preserveWatchOutput": true, + "resolveJsonModule": true, + "outDir": "lib", + "rootDir": "src", + "strict": true, + "strictNullChecks": true, + "target": "es2017", + "types": [] + }, + "include": ["src/*","src/kernelspec/*"] +} diff --git a/SwanFileBrowser/typedoc.json b/SwanFileBrowser/typedoc.json new file mode 100644 index 00000000..ac945476 --- /dev/null +++ b/SwanFileBrowser/typedoc.json @@ -0,0 +1,6 @@ +{ + "excludeNotExported": true, + "mode": "file", + "out": "../../docs/api/filebrowser-extension", + "theme": "../../typedoc-theme" +} diff --git a/SwanFileBrowser/yarn.lock b/SwanFileBrowser/yarn.lock new file mode 100644 index 00000000..cf002c80 --- /dev/null +++ b/SwanFileBrowser/yarn.lock @@ -0,0 +1,4057 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + +"@babel/helper-validator-identifier@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" + integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== + +"@babel/highlight@^7.10.4": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/runtime@^7.1.2": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== + dependencies: + regenerator-runtime "^0.13.4" + +"@blueprintjs/core@^3.36.0", "@blueprintjs/core@^3.46.0": + version "3.46.0" + resolved "https://registry.yarnpkg.com/@blueprintjs/core/-/core-3.46.0.tgz#fde92406ed97d48c949d5fe5578e7880efdf7577" + integrity sha512-kcYrisJMz7jPIuTc9AwFAbHMmmP/BxM2CC3e8vLaLk5h+xtXVzRipx19GA6ysSdguYXOnCPETwM6421QLehCCw== + dependencies: + "@blueprintjs/icons" "^3.27.0" + "@types/dom4" "^2.0.1" + classnames "^2.2" + dom4 "^2.1.5" + normalize.css "^8.0.1" + popper.js "^1.16.1" + react-lifecycles-compat "^3.0.4" + react-popper "^1.3.7" + react-transition-group "^2.9.0" + resize-observer-polyfill "^1.5.1" + tslib "~1.13.0" + +"@blueprintjs/icons@^3.27.0": + version "3.27.0" + resolved "https://registry.yarnpkg.com/@blueprintjs/icons/-/icons-3.27.0.tgz#f4c03e8bc2f9310f7eaefaab26dd91f65935da43" + integrity sha512-ItRioyrr2s70chclj5q38HS9omKOa15b3JZXv9JcMIFz+6w6rAcoAH7DA+5xIs27bFjax/SdAZp/eYXSw0+QpA== + dependencies: + classnames "^2.2" + tslib "~1.13.0" + +"@blueprintjs/select@^3.15.0": + version "3.16.5" + resolved "https://registry.yarnpkg.com/@blueprintjs/select/-/select-3.16.5.tgz#31b15a606dafd15643aa539d93d74795ec2aabe4" + integrity sha512-+DJF7Fy11NjV1mUBHtEyx4fQTZDBki8NxxTZLsQWD6lGnUkZQDWToWmkr3oDC1+4MFG++Hf0nKvdp48FqY44IA== + dependencies: + "@blueprintjs/core" "^3.46.0" + classnames "^2.2" + tslib "~1.13.0" + +"@discoveryjs/json-ext@^0.5.0": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d" + integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g== + +"@eslint/eslintrc@^0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179" + integrity sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + +"@fortawesome/fontawesome-free@^5.12.0": + version "5.15.3" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.3.tgz#c36ffa64a2a239bf948541a97b6ae8d729e09a9a" + integrity sha512-rFnSUN/QOtnOAgqFRooTA3H57JLDm0QEG/jPdk+tLQNL/eWd+Aok8g3qCI+Q1xuDPWpGW/i9JySpJVsq8Q0s9w== + +"@hypnosphi/create-react-context@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6" + integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A== + dependencies: + gud "^1.0.0" + warning "^4.0.3" + +"@jupyterlab/application@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@jupyterlab/application/-/application-3.0.11.tgz#01d502656db1aa07afc439a58171897af2a2fdd1" + integrity sha512-UBqnRcXSy/Iz5vq1dCYkQvSkCFGPqjQdDFvOhvXacGxHklVjiku5Epltdbe2kQl+uhhn7VC4HEh1kzxiYamwcg== + dependencies: + "@fortawesome/fontawesome-free" "^5.12.0" + "@jupyterlab/apputils" "^3.0.9" + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/docregistry" "^3.0.11" + "@jupyterlab/rendermime" "^3.0.10" + "@jupyterlab/rendermime-interfaces" "^3.0.9" + "@jupyterlab/services" "^6.0.9" + "@jupyterlab/statedb" "^3.0.6" + "@jupyterlab/translation" "^3.0.9" + "@jupyterlab/ui-components" "^3.0.7" + "@lumino/algorithm" "^1.3.3" + "@lumino/application" "^1.13.1" + "@lumino/commands" "^1.12.0" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/messaging" "^1.4.3" + "@lumino/polling" "^1.3.3" + "@lumino/properties" "^1.2.3" + "@lumino/signaling" "^1.4.3" + "@lumino/widgets" "^1.16.1" + +"@jupyterlab/apputils@^3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/apputils/-/apputils-3.0.9.tgz#504273fc0b69f74d8a8b87b7a89ee3d4decd679d" + integrity sha512-fsJjl+NX2+e+1FM7SMfpI1VsaPQsaIPnPGsdpQoboJJqdQJHuj1oPXNwc/aI1daEElirB15fYGCUGc2oUrv6RQ== + dependencies: + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/services" "^6.0.9" + "@jupyterlab/settingregistry" "^3.0.6" + "@jupyterlab/statedb" "^3.0.6" + "@jupyterlab/translation" "^3.0.9" + "@jupyterlab/ui-components" "^3.0.7" + "@lumino/algorithm" "^1.3.3" + "@lumino/commands" "^1.12.0" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/domutils" "^1.2.3" + "@lumino/messaging" "^1.4.3" + "@lumino/properties" "^1.2.3" + "@lumino/signaling" "^1.4.3" + "@lumino/virtualdom" "^1.8.0" + "@lumino/widgets" "^1.16.1" + "@types/react" "^17.0.0" + buffer "^5.6.0" + react "^17.0.1" + react-dom "^17.0.1" + sanitize-html "~2.3.3" + url "^0.11.0" + +"@jupyterlab/builder@^3.0.0": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/builder/-/builder-3.0.9.tgz#60b184accd63afced196d2369c886f6fe238acc4" + integrity sha512-IjWHk/xTgufTyggbT/0tGFeRdsHe3rNMQkOMqDN5+8YqFV4uCTUNokgvyysedgwB7JP+tcPclN/a3QoIPjAq/w== + dependencies: + "@jupyterlab/buildutils" "^3.0.7" + "@lumino/algorithm" "^1.3.3" + "@lumino/application" "^1.13.1" + "@lumino/commands" "^1.12.0" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/domutils" "^1.2.3" + "@lumino/dragdrop" "^1.7.1" + "@lumino/messaging" "^1.4.3" + "@lumino/properties" "^1.2.3" + "@lumino/signaling" "^1.4.3" + "@lumino/virtualdom" "^1.8.0" + "@lumino/widgets" "^1.16.1" + ajv "^6.12.3" + commander "~6.0.0" + css-loader "^5.0.1" + duplicate-package-checker-webpack-plugin "^3.0.0" + file-loader "~6.0.0" + fs-extra "^9.0.1" + glob "~7.1.6" + mini-css-extract-plugin "~1.3.2" + path-browserify "^1.0.0" + process "^0.11.10" + raw-loader "~4.0.0" + style-loader "~2.0.0" + supports-color "^7.2.0" + svg-url-loader "~6.0.0" + terser-webpack-plugin "^4.1.0" + to-string-loader "^1.1.6" + url-loader "~4.1.0" + webpack "^5.3.1" + webpack-cli "^4.1.0" + webpack-merge "^5.1.2" + worker-loader "^3.0.2" + +"@jupyterlab/buildutils@^3.0.7": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@jupyterlab/buildutils/-/buildutils-3.0.7.tgz#e83d3303b5f2bddd0b6b39fdab81864b67574dec" + integrity sha512-V3A9foBIP9CJcblyZTEKHtkY6o/3pRodxNAZqveiDDpBdQhM8xv4uOLBKkkMxroa5Eh5Goub4fw+JHxI2nKGXw== + dependencies: + "@lumino/coreutils" "^1.5.3" + "@yarnpkg/lockfile" "^1.1.0" + child_process "~1.0.2" + commander "~6.0.0" + crypto "~1.0.1" + dependency-graph "^0.9.0" + fs-extra "^9.0.1" + glob "~7.1.6" + inquirer "^7.0.0" + package-json "^6.5.0" + prettier "^2.1.1" + semver "^7.3.2" + sort-package-json "~1.44.0" + typescript "~4.1.3" + +"@jupyterlab/codeeditor@^3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/codeeditor/-/codeeditor-3.0.9.tgz#e06f82ad3c5199be8e9eb97b598d212af0c4ca08" + integrity sha512-OUymghTH6CsAXc4z8EA7BqwdT99mdjJ/X488EOgXCBgeKz3QKB1gQ3GpH26soUv4S0prAs8RKU7rHjfb+DLYBQ== + dependencies: + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/nbformat" "^3.0.6" + "@jupyterlab/observables" "^4.0.6" + "@jupyterlab/translation" "^3.0.9" + "@jupyterlab/ui-components" "^3.0.7" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/dragdrop" "^1.7.1" + "@lumino/messaging" "^1.4.3" + "@lumino/signaling" "^1.4.3" + "@lumino/widgets" "^1.16.1" + +"@jupyterlab/codemirror@^3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/codemirror/-/codemirror-3.0.9.tgz#2b66c998547ce30a6162141bfb168fb7d2db2ea0" + integrity sha512-RgB4ZS1Rhzvk20VDvnP7oQ8Bh9fC0dWDO/hZZwLJamlJLgtQNsCnU3Qw/K2dxhCMWBexI3n+E+0mcv1IXbEtLQ== + dependencies: + "@jupyterlab/apputils" "^3.0.9" + "@jupyterlab/codeeditor" "^3.0.9" + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/nbformat" "^3.0.6" + "@jupyterlab/observables" "^4.0.6" + "@jupyterlab/statusbar" "^3.0.9" + "@jupyterlab/translation" "^3.0.9" + "@lumino/algorithm" "^1.3.3" + "@lumino/commands" "^1.12.0" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/polling" "^1.3.3" + "@lumino/signaling" "^1.4.3" + "@lumino/widgets" "^1.16.1" + codemirror "~5.58.0" + react "^17.0.1" + +"@jupyterlab/coreutils@^5.0.6": + version "5.0.6" + resolved "https://registry.yarnpkg.com/@jupyterlab/coreutils/-/coreutils-5.0.6.tgz#dd36591d01191762ff35e3b096f324e990e0e617" + integrity sha512-nXGpI1IJw+4pNq6Afy+oI3LrTsaQ14xG7Kxbhg9UPfoDgsNt2rdG4pwYe4NZyj2GJHAkUj00lcUD9eBTrxMWvw== + dependencies: + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/signaling" "^1.4.3" + minimist "~1.2.0" + moment "^2.24.0" + path-browserify "^1.0.0" + url-parse "~1.5.1" + +"@jupyterlab/docmanager@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@jupyterlab/docmanager/-/docmanager-3.0.11.tgz#dd30f93a9590369812f986198fc4c70f8452d8ca" + integrity sha512-TCMw9eHOeWyOkg5MoSL8GbrqBRbnvP6TrR4q8k6YHntVOCZc3uTBZ0PIWuY0dxNXw0vhJGd0W5OBqquY5btVCw== + dependencies: + "@jupyterlab/apputils" "^3.0.9" + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/docregistry" "^3.0.11" + "@jupyterlab/services" "^6.0.9" + "@jupyterlab/statusbar" "^3.0.9" + "@jupyterlab/translation" "^3.0.9" + "@lumino/algorithm" "^1.3.3" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/messaging" "^1.4.3" + "@lumino/properties" "^1.2.3" + "@lumino/signaling" "^1.4.3" + "@lumino/widgets" "^1.16.1" + react "^17.0.1" + +"@jupyterlab/docregistry@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@jupyterlab/docregistry/-/docregistry-3.0.11.tgz#21ffbabbbac56b6c8a7db5547068790a4b077bd6" + integrity sha512-kx+ZXgM2UcBXvy+LDwGOVa/zP3+CjKMj0jM5qaUW+sHFZzkFIV/ke/MuiX2p6J+78s2VY5Hyy2Tq07jZhMEACg== + dependencies: + "@jupyterlab/apputils" "^3.0.9" + "@jupyterlab/codeeditor" "^3.0.9" + "@jupyterlab/codemirror" "^3.0.9" + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/observables" "^4.0.6" + "@jupyterlab/rendermime" "^3.0.10" + "@jupyterlab/rendermime-interfaces" "^3.0.9" + "@jupyterlab/services" "^6.0.9" + "@jupyterlab/translation" "^3.0.9" + "@jupyterlab/ui-components" "^3.0.7" + "@lumino/algorithm" "^1.3.3" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/messaging" "^1.4.3" + "@lumino/signaling" "^1.4.3" + "@lumino/widgets" "^1.16.1" + +"@jupyterlab/filebrowser@^3.0.11": + version "3.0.11" + resolved "https://registry.yarnpkg.com/@jupyterlab/filebrowser/-/filebrowser-3.0.11.tgz#de0854084c61fd8e717966be677404580bd88d01" + integrity sha512-64K/acTwS4ABCmWyBKNDztypA+WtjU8dFA6yfXSE1TE6gryDwEcFGmUdvTGLQ5WihK5XmM7rEi7ZlJ05mhJ7UQ== + dependencies: + "@jupyterlab/apputils" "^3.0.9" + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/docmanager" "^3.0.11" + "@jupyterlab/docregistry" "^3.0.11" + "@jupyterlab/services" "^6.0.9" + "@jupyterlab/statedb" "^3.0.6" + "@jupyterlab/statusbar" "^3.0.9" + "@jupyterlab/translation" "^3.0.9" + "@jupyterlab/ui-components" "^3.0.7" + "@lumino/algorithm" "^1.3.3" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/domutils" "^1.2.3" + "@lumino/dragdrop" "^1.7.1" + "@lumino/messaging" "^1.4.3" + "@lumino/polling" "^1.3.3" + "@lumino/signaling" "^1.4.3" + "@lumino/virtualdom" "^1.8.0" + "@lumino/widgets" "^1.16.1" + react "^17.0.1" + +"@jupyterlab/mainmenu@^3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/mainmenu/-/mainmenu-3.0.9.tgz#246165a8ef7311dd1f560d81767770009845ee82" + integrity sha512-O2+4unzBhluunQLa7B/Nb51lP6kAoIrQtgF2mTXebgwwy0dLlJ4mQY0QwHXChcWxooWyTtVFpqHz+G0L1Az2jQ== + dependencies: + "@jupyterlab/apputils" "^3.0.9" + "@jupyterlab/services" "^6.0.9" + "@jupyterlab/ui-components" "^3.0.7" + "@lumino/algorithm" "^1.3.3" + "@lumino/commands" "^1.12.0" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/widgets" "^1.16.1" + +"@jupyterlab/nbformat@^3.0.6": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@jupyterlab/nbformat/-/nbformat-3.0.6.tgz#858a6567cdd60879bc7f9dad6c9dcb5587417b5d" + integrity sha512-4+u770JYPmRpLyEPpnG0crj8ePUkg/vCF1W4hnDDxnLTVjzKw5kv6KVb5yJGEHAihUOf51bjceNUOp/+nLVBTg== + dependencies: + "@lumino/coreutils" "^1.5.3" + +"@jupyterlab/observables@^4.0.6": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@jupyterlab/observables/-/observables-4.0.6.tgz#be3bb0f08d2e79f86f4553857ed0aa90d7b293f2" + integrity sha512-PYJosNXGSkLExaEXqpUuDjEXTEcxTpvM6kG8I6NFJyDQVD6E50LggC6NofY5EIcEsJsO771BLvI4kwNk7LRQSA== + dependencies: + "@lumino/algorithm" "^1.3.3" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/messaging" "^1.4.3" + "@lumino/signaling" "^1.4.3" + +"@jupyterlab/rendermime-interfaces@^3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/rendermime-interfaces/-/rendermime-interfaces-3.0.9.tgz#13badf733d79b34bed0392e8a34d30291090e536" + integrity sha512-KvoDcIzgvDhvCGDYqFhRM753iOryWFujAEzXjpzvYz/1yNUh5weYsdwdmdCjUTkToM9rFiIDMwjferJPU54thw== + dependencies: + "@jupyterlab/translation" "^3.0.9" + "@lumino/coreutils" "^1.5.3" + "@lumino/widgets" "^1.16.1" + +"@jupyterlab/rendermime@^3.0.10": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@jupyterlab/rendermime/-/rendermime-3.0.10.tgz#7592155ea00c3a81f0d9a5662d3ccdeb37f722b1" + integrity sha512-9Q32zYpBkbrlAkuHJ7760ZETWQYZkKT9UcJWOMVF7iNgoBfRohAYvPHsoc6JFZyFEFhKzkLwa+CTcL48aGjg7A== + dependencies: + "@jupyterlab/apputils" "^3.0.9" + "@jupyterlab/codemirror" "^3.0.9" + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/nbformat" "^3.0.6" + "@jupyterlab/observables" "^4.0.6" + "@jupyterlab/rendermime-interfaces" "^3.0.9" + "@jupyterlab/services" "^6.0.9" + "@jupyterlab/translation" "^3.0.9" + "@lumino/algorithm" "^1.3.3" + "@lumino/coreutils" "^1.5.3" + "@lumino/messaging" "^1.4.3" + "@lumino/signaling" "^1.4.3" + "@lumino/widgets" "^1.16.1" + lodash.escape "^4.0.1" + marked "^2.0.0" + +"@jupyterlab/services@^6.0.9": + version "6.0.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/services/-/services-6.0.9.tgz#70a10d7f6883b8fafff81216663d96858b0cf46b" + integrity sha512-zeN9roqwbYo6b2I5BXWx+Mr4KzTpe2UcVwrcAGw9NXqIieb0ZnvtHqtNj/vcHCM2xQKuPup9W1X1bE5b3wF5Yw== + dependencies: + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/nbformat" "^3.0.6" + "@jupyterlab/observables" "^4.0.6" + "@jupyterlab/settingregistry" "^3.0.6" + "@jupyterlab/statedb" "^3.0.6" + "@lumino/algorithm" "^1.3.3" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/polling" "^1.3.3" + "@lumino/signaling" "^1.4.3" + node-fetch "^2.6.0" + ws "^7.2.0" + +"@jupyterlab/settingregistry@^3.0.6": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@jupyterlab/settingregistry/-/settingregistry-3.0.6.tgz#000cd9dc4984a1ccac01d73c7967893befe14b8d" + integrity sha512-fIeVJjkaf8FYSJ4jwJobwNeco8J2CEuWzmEJKiDjhmzmRZApS9Jjx+CJXDkTxoSMDQ41ELxQKJq5bcbih/90zQ== + dependencies: + "@jupyterlab/statedb" "^3.0.6" + "@lumino/commands" "^1.12.0" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/signaling" "^1.4.3" + ajv "^6.12.3" + json5 "^2.1.1" + +"@jupyterlab/statedb@^3.0.6": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@jupyterlab/statedb/-/statedb-3.0.6.tgz#d331c815496f80083d53277e1972095da954f31f" + integrity sha512-hXewp5TAKneWJcYXenTZuzSUagGjyWv5vRHDFarw1O4pkEg7zz8IyN2yAvbYH6+GDqIhF/91rgGu9alkx/yjjA== + dependencies: + "@lumino/commands" "^1.12.0" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/properties" "^1.2.3" + "@lumino/signaling" "^1.4.3" + +"@jupyterlab/statusbar@^3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/statusbar/-/statusbar-3.0.9.tgz#b00d8b74e813bb9534e7a57d0419579e9367da7a" + integrity sha512-MaA6GVi59mH3YRkV5iJPcpdS9opMTgFvcfMQLzKeMJvEQvM2fFGMVixp+q2U6Pa8iJsCp59CUoTyuQQdkw1UFw== + dependencies: + "@jupyterlab/apputils" "^3.0.9" + "@jupyterlab/codeeditor" "^3.0.9" + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/services" "^6.0.9" + "@jupyterlab/translation" "^3.0.9" + "@jupyterlab/ui-components" "^3.0.7" + "@lumino/algorithm" "^1.3.3" + "@lumino/coreutils" "^1.5.3" + "@lumino/disposable" "^1.4.3" + "@lumino/messaging" "^1.4.3" + "@lumino/signaling" "^1.4.3" + "@lumino/widgets" "^1.16.1" + csstype "~3.0.3" + react "^17.0.1" + typestyle "^2.0.4" + +"@jupyterlab/translation@^3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@jupyterlab/translation/-/translation-3.0.9.tgz#54472d3d2fef0d56dfa61c2711a9155f3308ad5b" + integrity sha512-XsIUt08HDpA2zqhJFmNV9iuxMriV4sAdx4rM1rA0tEUuvWSXerLvpzNUw4LAz+iaJgyUgqqV1gKrOgoMTjtvWA== + dependencies: + "@jupyterlab/coreutils" "^5.0.6" + "@jupyterlab/services" "^6.0.9" + "@jupyterlab/statedb" "^3.0.6" + "@lumino/coreutils" "^1.5.3" + +"@jupyterlab/ui-components@^3.0.7": + version "3.0.7" + resolved "https://registry.yarnpkg.com/@jupyterlab/ui-components/-/ui-components-3.0.7.tgz#83525d98051e9c74bd415da9e4a0fb20ec6bd609" + integrity sha512-kuq2aZ3DcCQNqf5ucsXWREHxbYq23+S12zMertOs+74KQr8jm8chX9HmqpmefNKnSIqqi/RKVSS2PWuSTpkEEw== + dependencies: + "@blueprintjs/core" "^3.36.0" + "@blueprintjs/select" "^3.15.0" + "@jupyterlab/coreutils" "^5.0.6" + "@lumino/coreutils" "^1.5.3" + "@lumino/signaling" "^1.4.3" + "@lumino/virtualdom" "^1.8.0" + "@lumino/widgets" "^1.16.1" + react "^17.0.1" + react-dom "^17.0.1" + typestyle "^2.0.4" + +"@lumino/algorithm@^1.3.3", "@lumino/algorithm@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@lumino/algorithm/-/algorithm-1.6.0.tgz#771e7896cd94e660f9b58a52f80e1bb255de1d41" + integrity sha512-NMOcm5Yr9nXz5gokS/K4jHBbUMQYBkvDXl1n51XWdcz0LY+oGuIKPhjazhUgmbNRehzdZBj5hMMd1+htYWeVKQ== + +"@lumino/application@^1.13.1": + version "1.20.0" + resolved "https://registry.yarnpkg.com/@lumino/application/-/application-1.20.0.tgz#b50ca4180bc400589fdfcfcaab08c4af937fccd0" + integrity sha512-FAoQcq4L3ZswTK0lWfLKnG1ecG26cwqjzg2fyoBeuWGBi1TG9BYjFBdV7ErTFMxW8jE1CLOLuxsZaKFLNErcKA== + dependencies: + "@lumino/commands" "^1.15.0" + "@lumino/coreutils" "^1.8.0" + "@lumino/widgets" "^1.23.0" + +"@lumino/collections@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@lumino/collections/-/collections-1.6.0.tgz#7d3e94cee26409b0cd719c1934bdda471e6a5662" + integrity sha512-ZETm0/xF0oUHV03sOXNOfFI1EEpS317HvN5n+fZBJvCNZIrJkWmKD8QuxcfwHb7AChKUhXlVHhDbWlb1LKnd7g== + dependencies: + "@lumino/algorithm" "^1.6.0" + +"@lumino/commands@^1.12.0", "@lumino/commands@^1.15.0": + version "1.15.0" + resolved "https://registry.yarnpkg.com/@lumino/commands/-/commands-1.15.0.tgz#06eb94fb4b34cad59f35b1fcaf473e8d2047f779" + integrity sha512-JOE68KfbR9xw5YTfcwo+9E0PSWidifEMAcOC/aXd7iSzfsCRknMTcMQIUGL277IU7J7CJvoe10DUE5QKwTmX+g== + dependencies: + "@lumino/algorithm" "^1.6.0" + "@lumino/coreutils" "^1.8.0" + "@lumino/disposable" "^1.7.0" + "@lumino/domutils" "^1.5.0" + "@lumino/keyboard" "^1.5.0" + "@lumino/signaling" "^1.7.0" + "@lumino/virtualdom" "^1.11.0" + +"@lumino/coreutils@^1.5.3", "@lumino/coreutils@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@lumino/coreutils/-/coreutils-1.8.0.tgz#4feb3ccbfbc3efc8e395a90f22b5a938fbad959a" + integrity sha512-OvCsaASUqOE7R6Dxngyk4/b5QMOjyRUNxuZuuL+fx+JvGKZFZ/B2c9LYtAJ9mDmQ1BQiGNV/qSpL4o7x8PCfjw== + +"@lumino/disposable@^1.4.3", "@lumino/disposable@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@lumino/disposable/-/disposable-1.7.0.tgz#539463490cb42e8d2dc46b5ff7cc291f4f1a8d07" + integrity sha512-3mWi11ko3XVY63BPwvys7MXrbFddA2i+gp72d0wAKM2NDDUopVPikMHhJpjGJcw+otjahzXYiTewxPDEau9dYg== + dependencies: + "@lumino/algorithm" "^1.6.0" + "@lumino/signaling" "^1.7.0" + +"@lumino/domutils@^1.2.3", "@lumino/domutils@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@lumino/domutils/-/domutils-1.5.0.tgz#fdba0cfe404b4817e63aa064f63b3c965655e76e" + integrity sha512-dZ0Aa+/qhvfPc1aa5kX4LLGE3B6BW1XmJa0R1XVCEpAFY3cZiujuQWmhYHJtZPrOiqn0UtioT2OpqnWdtCWc0A== + +"@lumino/dragdrop@^1.10.0", "@lumino/dragdrop@^1.7.1": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@lumino/dragdrop/-/dragdrop-1.10.0.tgz#2fddacfee055e660dd33dd9a3cfbd8fbba811673" + integrity sha512-A3cNLcp09zygOprWmLTkLZCQYNq3dJfN+mhni4IZizqCTkKbTCEzo2/IwoCWvy+ABKft8d/A9Y40wFW6yJ9OyA== + dependencies: + "@lumino/coreutils" "^1.8.0" + "@lumino/disposable" "^1.7.0" + +"@lumino/keyboard@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@lumino/keyboard/-/keyboard-1.5.0.tgz#c12213822dd2645c412e8689aecd4a2726113ac6" + integrity sha512-/uF9xqHYVbIkser2Q6UIv7VWrzThr1fxAmSOShjSoKGocL0XHeaBaCOMezSaVxnJ1wm1ciNdhMsjscVM8Inp7g== + +"@lumino/messaging@^1.4.3", "@lumino/messaging@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@lumino/messaging/-/messaging-1.7.0.tgz#32542f9e9a266fd5b3f71842f70cfe141e016d93" + integrity sha512-QYWf9QGIGD0Oes104zw7mVln4S8yRije2mZhNNRBjkYcDuQlPW+eRSuC5LwAMsFnGymBlUPwPbKOUEO2RbhAtg== + dependencies: + "@lumino/algorithm" "^1.6.0" + "@lumino/collections" "^1.6.0" + +"@lumino/polling@^1.3.3": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@lumino/polling/-/polling-1.6.0.tgz#64f40bba4602fe9eceb9f3fae8f3647831e5b7e9" + integrity sha512-jG1nqw6UO5XEN7QamOr6iDW8WvYeZQcBVRjM38fszz62dwJ/VGPvO2hlNl6QWWIfCynbJudms0LQm+z0BT1EdA== + dependencies: + "@lumino/coreutils" "^1.8.0" + "@lumino/disposable" "^1.7.0" + "@lumino/signaling" "^1.7.0" + +"@lumino/properties@^1.2.3", "@lumino/properties@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@lumino/properties/-/properties-1.5.0.tgz#7e8638e84c51bb110c5a69f91ca8b0e40b2c3fca" + integrity sha512-YqpJE6/1Wkjrie0E+ypu+yzd55B5RlvKYMnQs3Ox+SrJsnNBhA6Oj44EhVf8SUTuHgn1t/mm+LvbswKN5RM4+g== + +"@lumino/signaling@^1.4.3", "@lumino/signaling@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@lumino/signaling/-/signaling-1.7.0.tgz#76da4738bf8f19e7da6de1d457a54220e2140670" + integrity sha512-a5kd11Sf04jTfpzxCr7TOBD2o5YvItA4IGwiOoG+QR6sPR0Rwmcf47fPItqXo5st58iNIblC3F+c264N+Me+gg== + dependencies: + "@lumino/algorithm" "^1.6.0" + +"@lumino/virtualdom@^1.11.0", "@lumino/virtualdom@^1.8.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@lumino/virtualdom/-/virtualdom-1.11.0.tgz#468b4d28a07e2b8988dc583b4aab40e37dc6955e" + integrity sha512-G0sIx4pLYbgJ4w+SIgsCYQgKP/GBrWgjh8wcumD6XpaYZNivJv4c01xITYYlh7FU61jZmMWMrxtZztArNRDSqg== + dependencies: + "@lumino/algorithm" "^1.6.0" + +"@lumino/widgets@^1.16.1", "@lumino/widgets@^1.23.0": + version "1.23.0" + resolved "https://registry.yarnpkg.com/@lumino/widgets/-/widgets-1.23.0.tgz#096c7574de75fa67b32bcb914c5dae290fbee6f3" + integrity sha512-0Akt9ESgc06SJ3EJG3VK1Liw+AAjRWkKMfm8VUTwT/1QJYYGZ8kfHNO97mkBLv+0EkLEkZIeaQb8fIoU6vh7bw== + dependencies: + "@lumino/algorithm" "^1.6.0" + "@lumino/commands" "^1.15.0" + "@lumino/coreutils" "^1.8.0" + "@lumino/disposable" "^1.7.0" + "@lumino/domutils" "^1.5.0" + "@lumino/dragdrop" "^1.10.0" + "@lumino/keyboard" "^1.5.0" + "@lumino/messaging" "^1.7.0" + "@lumino/properties" "^1.5.0" + "@lumino/signaling" "^1.7.0" + "@lumino/virtualdom" "^1.11.0" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz#94c23db18ee4653e129abd26fb06f870ac9e1ee2" + integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@types/dom4@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/dom4/-/dom4-2.0.1.tgz#506d5781b9bcab81bd9a878b198aec7dee2a6033" + integrity sha512-kSkVAvWmMZiCYtvqjqQEwOmvKwcH+V4uiv3qPQ8pAh1Xl39xggGEo8gHUqV4waYGHezdFw0rKBR8Jt0CrQSDZA== + +"@types/eslint-scope@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86" + integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "7.2.13" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.13.tgz#e0ca7219ba5ded402062ad6f926d491ebb29dd53" + integrity sha512-LKmQCWAlnVHvvXq4oasNUMTJJb2GwSyTY8+1C7OH5ILR8mPLaljv1jxL1bXW3xB3jFbQxTKxJAvI8PyjB09aBg== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.48": + version "0.0.48" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.48.tgz#18dc8091b285df90db2f25aa7d906cfc394b7f74" + integrity sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew== + +"@types/glob@^7.1.1": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" + integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6", "@types/json-schema@^7.0.7": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== + +"@types/minimatch@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" + integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== + +"@types/minimatch@3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/node@*": + version "15.12.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.5.tgz#9a78318a45d75c9523d2396131bd3cca54b2d185" + integrity sha512-se3yX7UHv5Bscf8f1ERKvQOD6sTyycH3hdaoozvaLxgUiY5lIGEeH37AD0G0Qi9kPqihPn0HOfd2yaIEN9VwEg== + +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + +"@types/react@^17.0.0": + version "17.0.11" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451" + integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + +"@typescript-eslint/eslint-plugin@^4.8.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.1.tgz#c045e440196ae45464e08e20c38aff5c3a825947" + integrity sha512-9yfcNpDaNGQ6/LQOX/KhUFTR1sCKH+PBr234k6hI9XJ0VP5UqGxap0AnNwBnWFk1MNyWBylJH9ZkzBXC+5akZQ== + dependencies: + "@typescript-eslint/experimental-utils" "4.28.1" + "@typescript-eslint/scope-manager" "4.28.1" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.1.tgz#3869489dcca3c18523c46018b8996e15948dbadc" + integrity sha512-n8/ggadrZ+uyrfrSEchx3jgODdmcx7MzVM2sI3cTpI/YlfSm0+9HEUaWw3aQn2urL2KYlWYMDgn45iLfjDYB+Q== + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.28.1" + "@typescript-eslint/types" "4.28.1" + "@typescript-eslint/typescript-estree" "4.28.1" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.8.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.1.tgz#5181b81658414f47291452c15bf6cd44a32f85bd" + integrity sha512-UjrMsgnhQIIK82hXGaD+MCN8IfORS1CbMdu7VlZbYa8LCZtbZjJA26De4IPQB7XYZbL8gJ99KWNj0l6WD0guJg== + dependencies: + "@typescript-eslint/scope-manager" "4.28.1" + "@typescript-eslint/types" "4.28.1" + "@typescript-eslint/typescript-estree" "4.28.1" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.1.tgz#fd3c20627cdc12933f6d98b386940d8d0ce8a991" + integrity sha512-o95bvGKfss6705x7jFGDyS7trAORTy57lwJ+VsYwil/lOUxKQ9tA7Suuq+ciMhJc/1qPwB3XE2DKh9wubW8YYA== + dependencies: + "@typescript-eslint/types" "4.28.1" + "@typescript-eslint/visitor-keys" "4.28.1" + +"@typescript-eslint/types@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.1.tgz#d0f2ecbef3684634db357b9bbfc97b94b828f83f" + integrity sha512-4z+knEihcyX7blAGi7O3Fm3O6YRCP+r56NJFMNGsmtdw+NCdpG5SgNz427LS9nQkRVTswZLhz484hakQwB8RRg== + +"@typescript-eslint/typescript-estree@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.1.tgz#af882ae41740d1f268e38b4d0fad21e7e8d86a81" + integrity sha512-GhKxmC4sHXxHGJv8e8egAZeTZ6HI4mLU6S7FUzvFOtsk7ZIDN1ksA9r9DyOgNqowA9yAtZXV0Uiap61bIO81FQ== + dependencies: + "@typescript-eslint/types" "4.28.1" + "@typescript-eslint/visitor-keys" "4.28.1" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@4.28.1": + version "4.28.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.1.tgz#162a515ee255f18a6068edc26df793cdc1ec9157" + integrity sha512-K4HMrdFqr9PFquPu178SaSb92CaWe2yErXyPumc8cYWxFmhgJsNY9eSePmO05j0JhBvf2Cdhptd6E6Yv9HVHcg== + dependencies: + "@typescript-eslint/types" "4.28.1" + eslint-visitor-keys "^2.0.0" + +"@webassemblyjs/ast@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.0.tgz#a5aa679efdc9e51707a4207139da57920555961f" + integrity sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" + +"@webassemblyjs/floating-point-hex-parser@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz#34d62052f453cd43101d72eab4966a022587947c" + integrity sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA== + +"@webassemblyjs/helper-api-error@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz#aaea8fb3b923f4aaa9b512ff541b013ffb68d2d4" + integrity sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w== + +"@webassemblyjs/helper-buffer@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz#d026c25d175e388a7dbda9694e91e743cbe9b642" + integrity sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA== + +"@webassemblyjs/helper-numbers@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz#7ab04172d54e312cc6ea4286d7d9fa27c88cd4f9" + integrity sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.0" + "@webassemblyjs/helper-api-error" "1.11.0" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz#85fdcda4129902fe86f81abf7e7236953ec5a4e1" + integrity sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA== + +"@webassemblyjs/helper-wasm-section@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz#9ce2cc89300262509c801b4af113d1ca25c1a75b" + integrity sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew== + dependencies: + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-buffer" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" + "@webassemblyjs/wasm-gen" "1.11.0" + +"@webassemblyjs/ieee754@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz#46975d583f9828f5d094ac210e219441c4e6f5cf" + integrity sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.0.tgz#f7353de1df38aa201cba9fb88b43f41f75ff403b" + integrity sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.0.tgz#86e48f959cf49e0e5091f069a709b862f5a2cadf" + integrity sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw== + +"@webassemblyjs/wasm-edit@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz#ee4a5c9f677046a210542ae63897094c2027cb78" + integrity sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ== + dependencies: + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-buffer" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" + "@webassemblyjs/helper-wasm-section" "1.11.0" + "@webassemblyjs/wasm-gen" "1.11.0" + "@webassemblyjs/wasm-opt" "1.11.0" + "@webassemblyjs/wasm-parser" "1.11.0" + "@webassemblyjs/wast-printer" "1.11.0" + +"@webassemblyjs/wasm-gen@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz#3cdb35e70082d42a35166988dda64f24ceb97abe" + integrity sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ== + dependencies: + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" + "@webassemblyjs/ieee754" "1.11.0" + "@webassemblyjs/leb128" "1.11.0" + "@webassemblyjs/utf8" "1.11.0" + +"@webassemblyjs/wasm-opt@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz#1638ae188137f4bb031f568a413cd24d32f92978" + integrity sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg== + dependencies: + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-buffer" "1.11.0" + "@webassemblyjs/wasm-gen" "1.11.0" + "@webassemblyjs/wasm-parser" "1.11.0" + +"@webassemblyjs/wasm-parser@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz#3e680b8830d5b13d1ec86cc42f38f3d4a7700754" + integrity sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw== + dependencies: + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/helper-api-error" "1.11.0" + "@webassemblyjs/helper-wasm-bytecode" "1.11.0" + "@webassemblyjs/ieee754" "1.11.0" + "@webassemblyjs/leb128" "1.11.0" + "@webassemblyjs/utf8" "1.11.0" + +"@webassemblyjs/wast-printer@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz#680d1f6a5365d6d401974a8e949e05474e1fab7e" + integrity sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ== + dependencies: + "@webassemblyjs/ast" "1.11.0" + "@xtuc/long" "4.2.2" + +"@webpack-cli/configtest@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.0.4.tgz#f03ce6311c0883a83d04569e2c03c6238316d2aa" + integrity sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ== + +"@webpack-cli/info@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.3.0.tgz#9d78a31101a960997a4acd41ffd9b9300627fe2b" + integrity sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w== + dependencies: + envinfo "^7.7.3" + +"@webpack-cli/serve@^1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.5.1.tgz#b5fde2f0f79c1e120307c415a4c1d5eb15a6f278" + integrity sha512-4vSVUiOPJLmr45S8rMGy7WDvpWxfFxfP/Qx/cxZFCfvoypTYpPPL1X8VIZMe0WTA+Jr7blUxwUSEZNkjoMTgSw== + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +"@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + +acorn-jsx@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== + +acorn@^7.4.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.2.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" + integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.1: + version "8.6.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.0.tgz#60cc45d9c46a477d80d92c48076d972c342e5720" + integrity sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +backbone@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/backbone/-/backbone-1.4.0.tgz#54db4de9df7c3811c3f032f34749a4cd27f3bd12" + integrity sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ== + dependencies: + underscore ">=1.8.3" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.14.5: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== + dependencies: + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" + escalade "^3.1.1" + node-releases "^1.1.71" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +cacache@^15.0.5: + version "15.2.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.2.0.tgz#73af75f77c58e72d8c630a7a2858cb18ef523389" + integrity sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw== + dependencies: + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +caniuse-lite@^1.0.30001219: + version "1.0.30001241" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001241.tgz#cd3fae47eb3d7691692b406568d7a3e5b23c7598" + integrity sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ== + +chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +child_process@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/child_process/-/child_process-1.0.2.tgz#b1f7e7fc73d25e7fd1d455adc94e143830182b5a" + integrity sha1-sffn/HPSXn/R1FWtyU4UODAYK1o= + +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +classnames@^2.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + +clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +codemirror@~5.58.0: + version "5.58.3" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.58.3.tgz#3f0689854ecfbed5d4479a98b96148b2c3b79796" + integrity sha512-KBhB+juiyOOgn0AqtRmWyAT3yoElkuvWTI6hsHa9E6GQrl6bk/fdAYcvuqW1/upO9T9rtEtapWdw4XYcNiVDEA== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^1.2.1, colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@~6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.0.0.tgz#2b270da94f8fb9014455312f829a1129dbf8887e" + integrity sha512-s7EA+hDtTYNhuXkTlhqew4txMZVdszBmKWSPEMxGr8ru8JXR7bLUFIAtPhcSuFdJQ0ILMxnJi8GkQL0yvDy/YA== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/crypto/-/crypto-1.0.1.tgz#2af1b7cad8175d24c8a1b0778255794a21803037" + integrity sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig== + +css-loader@^5.0.1: + version "5.2.6" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.6.tgz#c3c82ab77fea1f360e587d871a6811f4450cc8d1" + integrity sha512-0wyN5vXMQZu6BvjbrPdUJvkCzGEO24HC7IS7nW4llc6BBFC+zwR9CKtYGv63Puzsg10L/o12inMY5/2ByzfD6w== + dependencies: + icss-utils "^5.1.0" + loader-utils "^2.0.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^3.0.0" + semver "^7.3.5" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +csstype@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" + integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== + +csstype@^3.0.2, csstype@~3.0.3: + version "3.0.8" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== + +debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-equal@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + dependencies: + is-arguments "^1.0.4" + is-date-object "^1.0.1" + is-regex "^1.0.4" + object-is "^1.0.1" + object-keys "^1.1.1" + regexp.prototype.flags "^1.2.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +dependency-graph@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.9.0.tgz#11aed7e203bc8b00f48356d92db27b265c445318" + integrity sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w== + +detect-indent@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" + integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== + +detect-newline@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-helpers@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +dom4@^2.1.5: + version "2.1.6" + resolved "https://registry.yarnpkg.com/dom4/-/dom4-2.1.6.tgz#c90df07134aa0dbd81ed4d6ba1237b36fc164770" + integrity sha512-JkCVGnN4ofKGbjf5Uvc8mmxaATIErKQKSgACdBXpsQ3fY6DlIpAyWfiBSrGkttATssbDCp3psiAKWXk5gmjycA== + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domhandler@^4.0.0, domhandler@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059" + integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.5.2: + version "2.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.7.0.tgz#8ebaf0c41ebafcf55b0b72ec31c56323712c5442" + integrity sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplicate-package-checker-webpack-plugin@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/duplicate-package-checker-webpack-plugin/-/duplicate-package-checker-webpack-plugin-3.0.0.tgz#78bb89e625fa7cf8c2a59c53f62b495fda9ba287" + integrity sha512-aO50/qPC7X2ChjRFniRiscxBLT/K01bALqfcDaf8Ih5OqQ1N4iT/Abx9Ofu3/ms446vHTm46FACIuJUmgUQcDQ== + dependencies: + chalk "^2.3.0" + find-root "^1.0.0" + lodash "^4.17.4" + semver "^5.4.1" + +electron-to-chromium@^1.3.723: + version "1.3.762" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.762.tgz#3fa4e3bcbda539b50e3aa23041627063a5cffe61" + integrity sha512-LehWjRpfPcK8F1Lf/NZoAwWLWnjJVo0SZeQ9j/tvnBWYcT99qDqgo4raAfS2oTKZjPrR/jxruh85DGgDUmywEA== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^5.8.0: + version "5.8.2" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b" + integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +enquirer@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +envinfo@^7.7.3: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.18.0-next.2: + version "1.18.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" + integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.2" + is-callable "^1.2.3" + is-negative-zero "^2.0.1" + is-regex "^1.1.3" + is-string "^1.0.6" + object-inspect "^1.10.3" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-module-lexer@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.6.0.tgz#e72ab05b7412e62b9be37c37a09bdb6000d706f0" + integrity sha512-f8kcHX1ArhllUtb/wVSyvygoKCznIjnxhLxy7TCvIiMdT7fL4ZDTIKaadMe6eLvOXg6Wk02UeoFgUoZ2EKZZUA== + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-prettier@^6.15.0: + version "6.15.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9" + integrity sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw== + dependencies: + get-stdin "^6.0.0" + +eslint-plugin-prettier@^3.1.4: + version "3.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz#cdbad3bf1dbd2b177e9825737fe63b476a08f0c7" + integrity sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-scope@5.1.1, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint@^7.14.0: + version "7.29.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.29.0.tgz#ee2a7648f2e729485e4d0bd6383ec1deabc8b3c0" + integrity sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.2" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" + integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^3.0.3, fast-glob@^3.1.1: + version "3.2.6" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.6.tgz#434dd9529845176ea049acc9343e8282765c6e1a" + integrity sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastest-levenshtein@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" + integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== + +fastq@^1.6.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + dependencies: + reusify "^1.0.4" + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +file-loader@~6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f" + integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.6.5" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-cache-dir@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-root@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" + integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + +free-style@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/free-style/-/free-style-3.1.0.tgz#4e2996029534e6b1731611d843437b9e2f473f08" + integrity sha512-vJujYSIyT30iDoaoeigNAxX4yB1RUrh+N2ZMhIElMr3BvCuGXOw7XNJMEEJkDUeamK2Rnb/IKFGKRKlTWIGRWA== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +git-hooks-list@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/git-hooks-list/-/git-hooks-list-1.0.3.tgz#be5baaf78203ce342f2f844a9d2b03dba1b45156" + integrity sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ== + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@~7.1.6: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.6.0, globals@^13.9.0: + version "13.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" + integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== + dependencies: + type-fest "^0.20.2" + +globby@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.0.tgz#abfcd0630037ae174a88590132c2f6804e291072" + integrity sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + +globby@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== + +gud@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0" + integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw== + +handlebars@^4.7.0: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +highlight.js@^9.17.1: + version "9.18.5" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825" + integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA== + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +htmlparser2@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.1, ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6" + integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +inquirer@^7.0.0: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.19" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.6.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + +is-arguments@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + dependencies: + call-bind "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-bigint@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== + +is-boolean-object@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== + dependencies: + call-bind "^1.0.2" + +is-callable@^1.1.4, is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + +is-core-module@^2.2.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== + dependencies: + has "^1.0.3" + +is-date-object@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-number-object@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-regex@^1.0.4, is-regex@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== + dependencies: + call-bind "^1.0.2" + has-symbols "^1.0.2" + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-string@^1.0.5, is-string@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +jest-worker@^26.5.0: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest-worker@^27.0.2: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed" + integrity sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jquery@^3.4.1: + version "3.6.0" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" + integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.1, json5@^2.1.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klona@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" + integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-runner@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + +loader-utils@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +loader-utils@^2.0.0, loader-utils@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.escape@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" + integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg= + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= + +lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lunr@^2.3.8: + version "2.3.9" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== + +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +marked@^0.8.0: + version "0.8.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.2.tgz#4faad28d26ede351a7a1aaa5fec67915c869e355" + integrity sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw== + +marked@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753" + integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA== + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.2.3, merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.48.0: + version "1.48.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== + +mime-types@^2.1.27: + version "2.1.31" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== + dependencies: + mime-db "1.48.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mini-css-extract-plugin@~1.3.2: + version "1.3.9" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.9.tgz#47a32132b0fd97a119acd530e8421e8f6ab16d5e" + integrity sha512-Ac4s+xhVbqlyhXS5J/Vh/QXUz3ycXlCqoCPpg0vdfhsIBH9eg/It/9L1r1XhSCH737M1lqcWnMuWL13zcygn5A== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + webpack-sources "^1.1.0" + +minimatch@^3.0.0, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5, minimist@~1.2.0: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.2: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.0" + +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + +mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +moment@^2.24.0: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +nanoid@^3.1.23: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +neo-async@^2.6.0, neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +node-fetch@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + +node-releases@^1.1.71: + version "1.1.73" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" + integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg== + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +normalize.css@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-8.0.1.tgz#9b98a208738b9cc2634caacbc42d131c97487bf3" + integrity sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg== + +npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-inspect@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" + integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-json@^6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== + dependencies: + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-srcset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" + integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE= + +path-browserify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pidtree@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" + integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pkg-dir@^4.1.0, pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +popper.js@^1.14.4, popper.js@^1.16.1: + version "1.16.1" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" + integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== + +postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + +postcss-modules-local-by-default@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" + integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" + integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== + +postcss@^8.0.2, postcss@^8.2.15: + version "8.3.5" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709" + integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.23" + source-map-js "^0.6.2" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.1.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" + integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0, progress@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +prop-types@^15.6.1, prop-types@^15.6.2: + version "15.7.2" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" + integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.8.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +raw-loader@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dom@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + scheduler "^0.20.2" + +react-is@^16.8.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-popper@^1.3.7: + version "1.3.11" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd" + integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg== + dependencies: + "@babel/runtime" "^7.1.2" + "@hypnosphi/create-react-context" "^0.3.1" + deep-equal "^1.1.1" + popper.js "^1.14.4" + prop-types "^15.6.1" + typed-styles "^0.0.7" + warning "^4.0.2" + +react-transition-group@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + +react@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +rechoir@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca" + integrity sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q== + dependencies: + resolve "^1.9.0" + +regenerator-runtime@^0.13.4: + version "0.13.7" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" + integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== + +regexp.prototype.flags@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== + dependencies: + rc "^1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resize-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.9.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^6.6.0: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sanitize-html@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.3.3.tgz#3db382c9a621cce4c46d90f10c64f1e9da9e8353" + integrity sha512-DCFXPt7Di0c6JUnlT90eIgrjs6TsJl/8HYU3KLdmrVclFN4O0heTcVbJiMa23OKVr6aR051XYtsgd8EWwEBwUA== + dependencies: + deepmerge "^4.2.2" + escape-string-regexp "^4.0.0" + htmlparser2 "^6.0.0" + is-plain-object "^5.0.0" + klona "^2.0.3" + parse-srcset "^1.0.2" + postcss "^8.0.2" + +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" + integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + dependencies: + "@types/json-schema" "^7.0.6" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.2.1, semver@^7.3.2, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +serialize-javascript@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +shell-quote@^1.6.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" + integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== + +shelljs@^0.8.3: + version "0.8.4" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" + integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +sort-object-keys@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45" + integrity sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg== + +sort-package-json@~1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-1.44.0.tgz#470330be868f8a524a4607b26f2a0233e93d8b6d" + integrity sha512-u9GUZvpavUCXV5SbEqXu9FRbsJrYU6WM10r3zA0gymGPufK5X82MblCLh9GW9l46pXKEZvK+FA3eVTqC4oMp4A== + dependencies: + detect-indent "^6.0.0" + detect-newline "3.1.0" + git-hooks-list "1.0.3" + globby "10.0.0" + is-plain-obj "2.1.0" + sort-object-keys "^1.1.3" + +source-list-map@^2.0.0, source-list-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + +source-map-support@~0.5.19: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" + integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + +string.prototype.padend@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.2.tgz#6858ca4f35c5268ebd5e8615e1327d55f59ee311" + integrity sha512-/AQFLdYvePENU3W5rgurfWSMU6n+Ww8n/3cUt7E+vPBB/D7YDG8x+qjoFs4M/alR2bW7Qg6xMjVwWUOvuQ0XpQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +style-loader@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" + integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0, supports-color@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +svg-url-loader@~6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/svg-url-loader/-/svg-url-loader-6.0.0.tgz#b94861d9f6badfb8ca3e7d3ec4655c1bf732ac5d" + integrity sha512-Qr5SCKxyxKcRnvnVrO3iQj9EX/v40UiGEMshgegzV7vpo3yc+HexELOdtWcA3MKjL8IyZZ1zOdcILmDEa/8JJQ== + dependencies: + file-loader "~6.0.0" + loader-utils "~2.0.0" + +table@^6.0.9: + version "6.7.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== + dependencies: + ajv "^8.0.1" + lodash.clonedeep "^4.5.0" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.0" + strip-ansi "^6.0.0" + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" + integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== + +tar@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +terser-webpack-plugin@^4.1.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" + integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== + dependencies: + cacache "^15.0.5" + find-cache-dir "^3.3.1" + jest-worker "^26.5.0" + p-limit "^3.0.2" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" + source-map "^0.6.1" + terser "^5.3.4" + webpack-sources "^1.4.3" + +terser-webpack-plugin@^5.1.3: + version "5.1.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz#c369cf8a47aa9922bd0d8a94fe3d3da11a7678a1" + integrity sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA== + dependencies: + jest-worker "^27.0.2" + p-limit "^3.1.0" + schema-utils "^3.0.0" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.0" + +terser@^5.3.4, terser@^5.7.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784" + integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.19" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-string-loader@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/to-string-loader/-/to-string-loader-1.1.6.tgz#230529ccc63dd0ecca052a85e1fb82afe946b0ab" + integrity sha512-VNg62//PS1WfNwrK3n7t6wtK5Vdtx/qeYLLEioW46VMlYUwAYT6wnfB+OwS2FMTCalIHu0tk79D3RXX8ttmZTQ== + dependencies: + loader-utils "^1.0.0" + +tslib@^1.8.1, tslib@^1.9.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@~1.13.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" + integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +typed-styles@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" + integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== + +typedoc-default-themes@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.6.3.tgz#c214ce5bbcc6045558448a8fd422b90e3e9b6782" + integrity sha512-rouf0TcIA4M2nOQFfC7Zp4NEwoYiEX4vX/ZtudJWU9IHA29MPC+PPgSXYLPESkUo7FuB//GxigO3mk9Qe1xp3Q== + dependencies: + backbone "^1.4.0" + jquery "^3.4.1" + lunr "^2.3.8" + underscore "^1.9.1" + +typedoc@^0.15.4: + version "0.15.8" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.15.8.tgz#d83195445a718d173e0d5c73b5581052cb47d4d9" + integrity sha512-a0zypcvfIFsS7Gqpf2MkC1+jNND3K1Om38pbDdy/gYWX01NuJZhC5+O0HkIp0oRIZOo7PWrA5+fC24zkANY28Q== + dependencies: + "@types/minimatch" "3.0.3" + fs-extra "^8.1.0" + handlebars "^4.7.0" + highlight.js "^9.17.1" + lodash "^4.17.15" + marked "^0.8.0" + minimatch "^3.0.0" + progress "^2.0.3" + shelljs "^0.8.3" + typedoc-default-themes "^0.6.3" + typescript "3.7.x" + +typescript@3.7.x: + version "3.7.7" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.7.tgz#c931733e2ec10dda56b855b379cc488a72a81199" + integrity sha512-MmQdgo/XenfZPvVLtKZOq9jQQvzaUAUpcKW8Z43x9B2fOm4S5g//tPtMweZUIP+SoBqrVPEIm+dJeQ9dfO0QdA== + +typescript@~4.1.3: + version "4.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.6.tgz#1becd85d77567c3c741172339e93ce2e69932138" + integrity sha512-pxnwLxeb/Z5SP80JDRzVjh58KsM6jZHRAOtTpS7sXLS4ogXNKC9ANxHHZqLLeVHZN35jCtI4JdmLLbLiC1kBow== + +typestyle@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/typestyle/-/typestyle-2.1.0.tgz#7c5cc567de72cd8bfb686813150b92791aaa7636" + integrity sha512-6uCYPdG4xWLeEcl9O0GtNFnNGhami+irKiLsXSuvWHC/aTS7wdj49WeikWAKN+xHN3b1hm+9v0svwwgSBhCsNA== + dependencies: + csstype "2.6.9" + free-style "3.1.0" + +uglify-js@^3.1.4: + version "3.13.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.10.tgz#a6bd0d28d38f592c3adb6b180ea6e07e1e540a8d" + integrity sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +underscore@>=1.8.3, underscore@^1.9.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1" + integrity sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g== + +unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url-loader@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== + dependencies: + loader-utils "^2.0.0" + mime-types "^2.1.27" + schema-utils "^3.0.0" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-parse@~1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" + integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +v8-compile-cache@^2.0.3, v8-compile-cache@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +warning@^4.0.2, warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + +watchpack@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" + integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +webpack-cli@^4.1.0: + version "4.7.2" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.7.2.tgz#a718db600de6d3906a4357e059ae584a89f4c1a5" + integrity sha512-mEoLmnmOIZQNiRl0ebnjzQ74Hk0iKS5SiEEnpq3dRezoyR3yPaeQZCMCe+db4524pj1Pd5ghZXjT41KLzIhSLw== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.0.4" + "@webpack-cli/info" "^1.3.0" + "@webpack-cli/serve" "^1.5.1" + colorette "^1.2.1" + commander "^7.0.0" + execa "^5.0.0" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + v8-compile-cache "^2.2.0" + webpack-merge "^5.7.3" + +webpack-merge@^5.1.2, webpack-merge@^5.7.3: + version "5.8.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" + integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== + dependencies: + clone-deep "^4.0.1" + wildcard "^2.0.0" + +webpack-sources@^1.1.0, webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-sources@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.0.tgz#9ed2de69b25143a4c18847586ad9eccb19278cfa" + integrity sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ== + dependencies: + source-list-map "^2.0.1" + source-map "^0.6.1" + +webpack@^5.3.1: + version "5.41.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.41.1.tgz#23fa1d82c95c222d3fc3163806b9a833fe52b253" + integrity sha512-AJZIIsqJ/MVTmegEq9Tlw5mk5EHdGiJbDdz9qP15vmUH+oxI1FdWcL0E9EO8K/zKaRPWqEs7G/OPxq1P61u5Ug== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.48" + "@webassemblyjs/ast" "1.11.0" + "@webassemblyjs/wasm-edit" "1.11.0" + "@webassemblyjs/wasm-parser" "1.11.0" + acorn "^8.2.1" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.0" + es-module-lexer "^0.6.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.0.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.2.0" + webpack-sources "^2.3.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wildcard@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" + integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +worker-loader@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-3.0.8.tgz#5fc5cda4a3d3163d9c274a4e3a811ce8b60dbb37" + integrity sha512-XQyQkIFeRVC7f7uRhFdNMe/iJOdO6zxAaR3EWbDp45v3mDhrTi+++oswKNxShUNjPC/1xUp5DB29YKLhFo129g== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +ws@^7.2.0: + version "7.5.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.1.tgz#44fc000d87edb1d9c53e51fbc69a0ac1f6871d66" + integrity sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 1903a95bcb4a8b7f9e1b27366df5671840add3e9 Mon Sep 17 00:00:00 2001 From: Omar Zapata Date: Wed, 24 Nov 2021 15:00:02 +0100 Subject: [PATCH 2/5] fixed some comments --- SwanFileBrowser/setup.py | 2 -- SwanFileBrowser/src/index.ts | 6 +++--- SwanFileBrowser/src/swanfilebrowser.ts | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/SwanFileBrowser/setup.py b/SwanFileBrowser/setup.py index 44b28ffc..7977f65b 100644 --- a/SwanFileBrowser/setup.py +++ b/SwanFileBrowser/setup.py @@ -8,8 +8,6 @@ import setuptools -site.ENABLE_USER_SITE = "--user" in sys.argv[1:] - HERE = Path(__file__).parent.resolve() # The name of the project diff --git a/SwanFileBrowser/src/index.ts b/SwanFileBrowser/src/index.ts index 318ec5a0..635030f1 100644 --- a/SwanFileBrowser/src/index.ts +++ b/SwanFileBrowser/src/index.ts @@ -5,13 +5,13 @@ /** * SwanFileBrowser extension is based on the upstream filebrowser extension 3.0.x. * - * This file the entry point for the extension where is defined the commands such as + * This file is the entry point for the extension where is defined the commands such as * 'filebrowser:copy', 'filebrowser:cut', 'filebrowser:open' etc.. - * Those commands are reimplemented using our class SwanFileBrowser intead the default Jupyter FileBrowser. + * Those commands are reimplemented using our class SwanFileBrowser instead the default Jupyter FileBrowser. * * The classes SwanFileBrowser and SwanFileBrowserModel are defined in the file swanfilebrowser.ts * and the class SwanDirListing in the file listing.ts. Those have the code required to manipulate - * projects and kernel manager. + * projects and the kernel manager. * * Alsmot all the documentation for this file is the default one provided by the Jupyter extension. */ diff --git a/SwanFileBrowser/src/swanfilebrowser.ts b/SwanFileBrowser/src/swanfilebrowser.ts index 4d0b18bd..7437417b 100755 --- a/SwanFileBrowser/src/swanfilebrowser.ts +++ b/SwanFileBrowser/src/swanfilebrowser.ts @@ -5,7 +5,7 @@ * This file containts the implementation for SwanFileBrowser and SwanFileBrowserModel classes. * * Those classes are the replacement for the default FileBrowser and allows to - * manipulated the paths to check is the folder is a project or not and to set the proper kernel path. + * manipulated the paths to check if the folder is a project or not and to set the proper kernel path. */ import { FilterFileBrowserModel, FileBrowser } from '@jupyterlab/filebrowser'; From 6db3a15f116d4cd746e1f38c48ec3747637bde80 Mon Sep 17 00:00:00 2001 From: Omar Zapata Date: Tue, 30 Nov 2021 14:49:50 +0100 Subject: [PATCH 3/5] fixed typos and improved the documentation. --- SwanFileBrowser/src/index.ts | 15 ++++++++++---- SwanFileBrowser/src/kernelspec/validate.ts | 4 +++- SwanFileBrowser/src/listing.ts | 23 +++++++++++----------- SwanFileBrowser/src/request.ts | 6 ++++++ 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/SwanFileBrowser/src/index.ts b/SwanFileBrowser/src/index.ts index 635030f1..e8f7e1fa 100644 --- a/SwanFileBrowser/src/index.ts +++ b/SwanFileBrowser/src/index.ts @@ -3,17 +3,24 @@ // Author: Omar.Zapata@cern.ch 2021 /** + * This file is a hard copy of the original index.ts of the JupyterLab file browser, + * it was necessary because it was not possible to just extend it. * SwanFileBrowser extension is based on the upstream filebrowser extension 3.0.x. * - * This file is the entry point for the extension where is defined the commands such as - * 'filebrowser:copy', 'filebrowser:cut', 'filebrowser:open' etc.. - * Those commands are reimplemented using our class SwanFileBrowser instead the default Jupyter FileBrowser. + * This extension replaces the default FileBrowser, then we need to redefined the commands provided by the default FileBrowser + * such as,'filebrowser:copy', 'filebrowser:cut', 'filebrowser:open' etc.. + * Those commands are reimplemented using our class SwanFileBrowser instead of the default Jupyter FileBrowser. * * The classes SwanFileBrowser and SwanFileBrowserModel are defined in the file swanfilebrowser.ts * and the class SwanDirListing in the file listing.ts. Those have the code required to manipulate * projects and the kernel manager. + * The kernelspec/validate.ts file contains the functions to validate the kernel specifications to obtain the ISpecModel objects. * - * Alsmot all the documentation for this file is the default one provided by the Jupyter extension. + * Almost all the documentation for this file is the default one provided by the Jupyter extension. + * + * Modifications on this file: + * -> activateFactory creates a new SwanFileBrowserModel and a new SwanFileBrowser + * -> Other modifications consist mainly of changing the default FileBrowser objects to the SwanFileBrowser class. */ import { diff --git a/SwanFileBrowser/src/kernelspec/validate.ts b/SwanFileBrowser/src/kernelspec/validate.ts index 0bfe8c86..119d2749 100644 --- a/SwanFileBrowser/src/kernelspec/validate.ts +++ b/SwanFileBrowser/src/kernelspec/validate.ts @@ -1,10 +1,12 @@ /** - * File took from https://github.com/jupyterlab/jupyterlab/blob/master/packages/services/src/kernelspec/validate.ts + * File taken from https://github.com/jupyterlab/jupyterlab/blob/master/packages/services/src/kernelspec/validate.ts * for jupyterlab 3.0.x * * This allows to validate the kernels specs and to get the ISpecModel. * This is required to update the manager.services.kernelspecs.specs object * in the SwanFileBrowserModel. + * + * This file has not modifications from upstream. */ import { PartialJSONObject } from '@lumino/coreutils'; diff --git a/SwanFileBrowser/src/listing.ts b/SwanFileBrowser/src/listing.ts index f40e7746..b82f2426 100644 --- a/SwanFileBrowser/src/listing.ts +++ b/SwanFileBrowser/src/listing.ts @@ -1,10 +1,20 @@ /** - * File took from https://github.com/jupyterlab/jupyterlab/blob/master/packages/filebrowser/src/listing.ts + * File taken from https://github.com/jupyterlab/jupyterlab/blob/master/packages/filebrowser/src/listing.ts * for jupytrelab version 3.0.x. * * In this file, we reimplement the DirListing class in the SwanDirListing class. * This allows you to manipulate the low-level entries in the file browser widget, * allowing us, for example, to change the icon if the folder is a project. + * + * Modifications on this file: + * -> Implemented class SwanDirListing that extends Widget + * -> In the class SwanDirListing modified the methods: + * -> onUpdateRequest + * -> get model() + * -> In the class Renderer was reimplemented: + * -> the method updateItemNode + * -> changed DirListing by SwanDirListing + * All the other code are mainly from upstream. */ import { Dialog, @@ -64,15 +74,6 @@ export interface ISwanModel { type: string; writable: boolean; } -export interface ISwanFileType { - contentType: any; - displayName: string; - extensions: any; - fileFormat: any; - icon: any; - mimeTypes: any; - name: string; -} /** * The class name added to DirListing widget. @@ -1728,7 +1729,7 @@ export class SwanDirListing extends Widget { } /** - * The namespace for the `DirListing` class statics. + * The namespace for the `SwanDirListing` class statics. */ export namespace SwanDirListing { /** diff --git a/SwanFileBrowser/src/request.ts b/SwanFileBrowser/src/request.ts index 1fea3584..77531f99 100644 --- a/SwanFileBrowser/src/request.ts +++ b/SwanFileBrowser/src/request.ts @@ -1,3 +1,9 @@ +/** + * This file have the function that allows request to our backend extensions + * SwanProjects and SwanContents. + * + */ + import { URLExt } from '@jupyterlab/coreutils'; import { ServerConnection } from '@jupyterlab/services'; From 7391789d06f6e338811e82ae9cbd3e2ea8fdcddd Mon Sep 17 00:00:00 2001 From: Omar Zapata Date: Tue, 30 Nov 2021 14:57:55 +0100 Subject: [PATCH 4/5] fixed documentation on reqeust and listing files. --- SwanFileBrowser/src/listing.ts | 2 +- SwanFileBrowser/src/request.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SwanFileBrowser/src/listing.ts b/SwanFileBrowser/src/listing.ts index b82f2426..c760d6c6 100644 --- a/SwanFileBrowser/src/listing.ts +++ b/SwanFileBrowser/src/listing.ts @@ -1,6 +1,6 @@ /** * File taken from https://github.com/jupyterlab/jupyterlab/blob/master/packages/filebrowser/src/listing.ts - * for jupytrelab version 3.0.x. + * for Jupyterlab version 3.0.x. * * In this file, we reimplement the DirListing class in the SwanDirListing class. * This allows you to manipulate the low-level entries in the file browser widget, diff --git a/SwanFileBrowser/src/request.ts b/SwanFileBrowser/src/request.ts index 77531f99..a6911a27 100644 --- a/SwanFileBrowser/src/request.ts +++ b/SwanFileBrowser/src/request.ts @@ -1,5 +1,5 @@ /** - * This file have the function that allows request to our backend extensions + * This file has the function that allows requesting our backend extensions. * SwanProjects and SwanContents. * */ From 204c010e8e19e7facdd4766643e830423715beb4 Mon Sep 17 00:00:00 2001 From: Omar Zapata Date: Tue, 30 Nov 2021 15:26:50 +0100 Subject: [PATCH 5/5] Applied changes resquested by Enric. --- SwanFileBrowser/src/swanfilebrowser.ts | 31 ++++++++++++++++---------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/SwanFileBrowser/src/swanfilebrowser.ts b/SwanFileBrowser/src/swanfilebrowser.ts index 7437417b..e9d99ece 100755 --- a/SwanFileBrowser/src/swanfilebrowser.ts +++ b/SwanFileBrowser/src/swanfilebrowser.ts @@ -2,10 +2,17 @@ // Author: Omar.Zapata@cern.ch 2021 /** - * This file containts the implementation for SwanFileBrowser and SwanFileBrowserModel classes. + * This file contains the implementation for SwanFileBrowser and SwanFileBrowserModel classes. + * The code in this file is mainly from us. * - * Those classes are the replacement for the default FileBrowser and allows to - * manipulated the paths to check if the folder is a project or not and to set the proper kernel path. + * Those classes are the replacement for the default FileBrowser and allow to + * manipulate the paths to check if the folder is a project or not and to set the proper kernel path. + * + * Modifications on this file: + * -> created the class SwanFileBrowserModel that extends from FilterFileBrowserModel + * -> created the class SwanFileBrowser extends from FileBrowser + * + * All new methods were implemented by us, take a look in the documentation below for every class and method for more details. */ import { FilterFileBrowserModel, FileBrowser } from '@jupyterlab/filebrowser'; @@ -34,11 +41,11 @@ export interface ISwanProjectOptions { * Customized SwanFileBrowserModel that inherits from FilterFileBrowserModel. * * This class has overloaded the method 'async cd(newValue: string): Promise' - * that a allows to take actions before go to the directory, actions like: + * that allows to take actions before changing directory, actions like: * 1) Get the contents of the folder (to check if the folder is a project) - * 2) If the folder is a project we can ge the information of the project stored in the .swanproject + * 2) If the folder is a project we can get the information of the project stored in the .swanproject * 3) if the information for the project is right then we can set the kernel spec manager - * 4) If the project is corrupted, the a Dialog is showed up telling the user the project requires + * 4) If the project is corrupted, the Dialog is showed up telling the user the project requires * to be configured again and the ProjectDialog is called. */ export class SwanFileBrowserModel extends FilterFileBrowserModel { @@ -55,7 +62,7 @@ export class SwanFileBrowserModel extends FilterFileBrowserModel { * Request to set the kernelspec manager path in the backend. * Local service manager.services.kernelspecs is updated as well. * - * @param path path get information from jupyter api + * @param path path to get information from jupyter api * @returns json object with the information of the path or json object with the information of the error. */ protected kernelSpecSetPathRequest(path: string): any { @@ -105,7 +112,7 @@ export class SwanFileBrowserModel extends FilterFileBrowserModel { * Request to get the project information * * @param path path to the project - * @returns json object with the project information information. + * @returns json object with the project information. */ protected projectInfoRequest(path: string): any { const uri = 'swan/project/info?caller=swanfilebrowser&path=' + path; @@ -121,7 +128,7 @@ export class SwanFileBrowserModel extends FilterFileBrowserModel { /** * Request to get contents from a path * - * @param cwd path get information from jupyter api + * @param cwd path to get information from jupyter api * @returns json object with the information of the path */ protected contentRequest(cwd: string): any { @@ -139,8 +146,8 @@ export class SwanFileBrowserModel extends FilterFileBrowserModel { /** * Method to check if the project information is valid or it is corrupted. * - * @param project_data json with project data such as name, stack, release etc.. - * @returns true if the project is valid or false it the project is corrupted. + * @param project_data json with project data such as name, stack, release etc. + * @returns true if the project is valid or false if the project is corrupted. */ protected isValidProject(project_data: JSONObject): boolean { for (const tag in this.project_tags) { @@ -152,7 +159,7 @@ export class SwanFileBrowserModel extends FilterFileBrowserModel { } /** - * Overloaded method cd, to check folder information before go in. + * Overloaded method cd, to check folder information before changing directory. * * @param newValue new path * @returns void promise.