diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml new file mode 100644 index 0000000..7fe11d6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml @@ -0,0 +1,81 @@ +name: Bug report +description: File a bug report +labels: [bug, pending triage] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to file this bug report. + - type: textarea + attributes: + label: Bug description + description: A clear and concise description of the bug. + placeholder: | + + validations: + required: true + - type: textarea + attributes: + label: Reproduction + description: | + How can we reproduce the issue? When an issue is immediately reproducible, others can start debugging instead of following-up with questions. + placeholder: | + + validations: + required: true + - type: dropdown + attributes: + label: Node.js package manager + description: Which package manager are you using? [npm](https://docs.npmjs.com/cli/v7/commands/npm), [yarn](https://yarnpkg.com/), or [pnpm](https://pnpm.io/) + options: + - npm + - yarn + - pnpm + validations: + required: true + - type: textarea + attributes: + label: Environment + description: | + Describe the environment the issue is happening in. This information is used to for reproduction and debugging. + placeholder: | + + + System: + OS: + CPU: + Shell: + Binaries: + Node: + npm: + npmPackages: + cleye: + render: shell + validations: + required: true + - type: checkboxes + attributes: + label: Can you contribute a fix? + description: We would love it if you can open a pull request to fix this bug! + options: + - label: I’m interested in opening a pull request for this issue. diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml new file mode 100644 index 0000000..a14b635 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml @@ -0,0 +1,43 @@ +name: Feature request +description: Suggest an idea for this project +labels: [feature request, pending triage] +body: + - type: markdown + attributes: + value: | + Thank you for taking the time to file this feature request. + - type: textarea + attributes: + label: Feature request + description: A description of the feature you would like. + validations: + required: true + - type: textarea + attributes: + label: Why? + description: | + Describe the problem you’re tackling with this feature request. + placeholder: | + + validations: + required: true + - type: textarea + attributes: + label: Alternatives + description: | + Have you considered alternative solutions? Is there a workaround? + placeholder: | + + - type: textarea + attributes: + label: Additional context + description: | + Anything else to share? Screenshots? Links? diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..71a913a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Help / Questions / Discussions + url: https://github.com/privatenumber/cleye/discussions + about: Use GitHub Discussions for anything else diff --git a/.github/command-type-narrowing.png b/.github/command-type-narrowing.png new file mode 100644 index 0000000..e539831 Binary files /dev/null and b/.github/command-type-narrowing.png differ diff --git a/.github/logo.png b/.github/logo.png new file mode 100644 index 0000000..353577f Binary files /dev/null and b/.github/logo.png differ diff --git a/.github/responsive-narrow.png b/.github/responsive-narrow.png new file mode 100644 index 0000000..733c34b Binary files /dev/null and b/.github/responsive-narrow.png differ diff --git a/.github/responsive-normal.png b/.github/responsive-normal.png new file mode 100644 index 0000000..23fa3ef Binary files /dev/null and b/.github/responsive-normal.png differ diff --git a/.github/typed-flags.png b/.github/typed-flags.png new file mode 100644 index 0000000..f2b95a7 Binary files /dev/null and b/.github/typed-flags.png differ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ca4afae --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,29 @@ +name: Release + +on: + push: + branches: [master, next] + +jobs: + release: + name: Release + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: 14.x + - name: Install dependencies + run: npx ci + - name: Test + run: npm run test --if-present + - name: Build + run: npm run build --if-present + - name: Release + env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npx semantic-release diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..4bd0f1b --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,28 @@ +name: Test +on: + push: + branches: [develop] + pull_request: + branches: [master, develop, next] +jobs: + test: + name: Test + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + matrix: + node-version: [12.x, 14.x] + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Install dependencies + run: npx ci + - name: Lint + if: ${{ matrix.node-version == '14.x' }} + run: npm run lint + - name: Test + run: npm run test --if-present diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..49cd9be --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Mac OS X +.DS_Store + +# Logs +logs +*.log +npm-debug.log* + +# Dependency directories +node_modules/ + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Jest coverage data +coverage + +# Distribution files +dist diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..af6434b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib" +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..8738727 --- /dev/null +++ b/README.md @@ -0,0 +1,536 @@ + +

+ +

+

cleye

+ +The intuitive command-line interface (CLI) development tool. + +### Features +- Minimal API surface +- Powerful flag parsing +- Strongly typed parameters and flags +- Command support +- Help documentation generation (customizable too!) + +→ Try it out online + +Support this project by starring and sharing it. [Follow me](https://github.com/privatenumber) to see what other cool projects I'm working on. + +## Install + +```bash +npm i cleye +``` + +## About +_Cleye_ makes it very easy to develop command-line scripts in Node.js. It handles argv parsing to give you strongly typed parameters + flags and generates `--help` documentation based on the provided information. + +Here's an example script that simply logs: `Good morning/evening !`: + +_greet.js:_ +```ts +import { cli } from 'cleye' + +// Parse argv +const argv = cli({ + name: 'greet.js', + + // Define parameters + parameters: [ + '', // First name is required + '[last name]' // Last name is optional + ], + + // Define flags/options + flags: { + + // Parses `--time` as a string + time: { + type: String, + description: 'Time of day to greet (morning or evening)', + default: 'morning' + } + } +}) + +const name = [argv._.firstName, argv._.lastName].filter(Boolean).join(' ') + +if (argv.flags.time === 'morning') { + console.log(`Good morning ${name}!`) +} else { + console.log(`Good evening ${name}!`) +} +``` + +🛠 In development, type hints are provided on parsed flags and parameters: +

+ +

+ +📖 Generated help documentation can be viewed with the `--help` flag: + +```sh +$ node greet.js --help + +greet.js + +Usage: + greet.js [flags...] [last name] + +Flags: + -h, --help Show help + --time Time of day to greet (morning or evening) (default: "morning") +``` + +✅ Run the script to see it in action: + +```sh +$ node greet.js John Doe --time evening + +Good evening John Doe! +``` + +## Examples +Want to dive right into some code? Check out some of these examples: + +- [**greet.js**](/examples/greet/index.ts): Working example from above +- [**npm install**](/examples/npm/index.ts): Reimplementation of [`npm install`](https://docs.npmjs.com/cli/install/)'s CLI +- [**tsc**](/examples/tsc/index.ts): Reimplementation of TypeScript [`tsc`](https://www.typescriptlang.org/docs/handbook/compiler-options.html)'s CLI +- [**snap-tweet**](/examples/snap-tweet/index.ts): Reimplementation of [`snap-tweet`](https://github.com/privatenumber/snap-tweet)'s CLI +- [**pkg-size**](/examples/pkg-size/index.ts): Reimplementation of [`pkg-size`](https://github.com/pkg-size/pkg-size)'s CLI + +## Usage + +### Arguments +Arguments are values passed into the script that are not associated with any flags/options. + +For example, in the following command, the first argument is `file-a.txt` and the second is `file-b.txt`: + +``` +$ my-script file-a.txt file-b.txt +``` + +Arguments can be accessed from the `_` array-property of the returned object. + +Example: + +```ts +const argv = cli({ /* ... */ }) + +// $ my-script file-a.txt file-b.txt + +argv._ // => ["file-a.txt", "file-b.txt"] (string[]) +``` + +#### Parameters +Parameters (aka _positional arguments_) are the names that map against argument values. Think of parameters as variable names and arguments as values associated with the variables. + +Parameters can be defined in the `parameters` array-property to make specific arguments accessible by name. This is useful for writing more readable code, enforcing validation, and generating help documentation. + +Parameters are defined in the following formats: +- **Required parameters** are indicated by angle brackets (eg. ``). +- **Optional parameters** are indicated by square brackets (eg. `[parameter name]`). +- **Spread parameters** are indicated by `...` suffix (eg. `` or `[parameter name...]`). + +Note, required parameters cannot come after optional parameters, and spread parameters must be last. + +Parameters can be accessed in camelCase on the `_` property of the returned object. + +Example: + +```ts +const argv = cli({ + parameters: [ + '', + '[optional parameter]', + '[optional spread...]' + ] +}) + +// $ my-script a b c d + +argv._.requiredParameter // => "a" (string) +argv._.optionalParameter // => "b" (string | undefined) +argv._.optionalSpread // => ["c", "d"] (string[]) +``` + +### Flags +Flags (aka Options) are key-value pairs passed into the script in the format `--flag-name `. + +For example, in the following command, `--file-a` has value `data.json` and `--file-b` has value `file.txt`: + +``` +$ my-script --file-a data.json --file-b=file.txt +``` + +#### Parsing features +_Cleye_'s flag parsing is powered by [`type-flag`](https://github.com/privatenumber/type-flag) and comes with many features: + +- Array & Custom types +- Flag delimiters: `--flag value`, `--flag=value`, `--flag:value`, and `--flag.value` +- Combined aliases: `-abcd 2` → `-a -b -c -d 2` +- Early termination: Pass in `--` to end flag parsing +- Unknown flags: Unexpected flags stored in `unknownFlags` + + +Read the [_type-flag_ docs](https://github.com/privatenumber/type-flag) to learn more. + +#### Defining flags +Flags can be specified in the `flag` object-property, where the key is the flag name, and the value is a flag type function or an object that describes the flag. + +The flag name is recommended to be in camelCase as it will be interpreted to parse kebab-case equivalents. + +The flag type function can be any function that accepts a string and returns the parsed value. Default JavaScript constructors should cover most use-cases: [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/String), [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/Number), [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/Boolean), etc. + +The flag description object can be used to store additional information about the flag, such as `alias`, `default`, and `description`. To accept multiple values for a flag, wrap the type function in an array. + +All of the provided information will be used to generate better help documentation. + +Example: + +```ts +const argv = cli({ + flags: { + someBoolean: Boolean, + + someString: { + type: String, + description: 'Some string flag', + default: 'n/a' + }, + + someNumber: { + // Wrap the type function in an array to allow multiple values + type: [Number], + alias: 'n', + description: 'Array of numbers. (eg. -n 1 -n 2 -n 3)' + } + } +}) + +// $ my-script --some-boolean --some-string hello --some-number 1 -n 2 + +argv.flags.someBoolean // => true (boolean | undefined) +argv.flags.someString // => "hello" (string) +argv.flags.someNumber // => [1, 2] (number[]) +``` + +#### Custom flag types & validation +Custom flag types can be created to validate flags and narrow types. Simply create a new function that accepts a string and returns the parsed value. + +Here's an example with a custom `Size` type that narrows the flag type to `"small" | "medium" | "large"`: + +```ts +const possibleSizes = ['small', 'medium', 'large'] as const + +type Sizes = typeof possibleSizes[number] // => "small" | "medium" | "large" + +// Custom type function +function Size(size: Sizes) { + if (!possibleSizes.includes(size)) { + throw new Error(`Invalid size: "${size}"`) + } + + return size +} + +const argv = cli({ + flags: { + size: { + type: Size, + description: 'Size of the pizza (small, medium, large)' + } + } +}) + +// $ my-script --size large + +argv.flags.size // => "large" ("small" | "medium" | "large") +``` + +#### Default flags +By default, _Cleye_ will try to handle the `--help, -h` and `--version` flags. + +##### Help flag +Handling `--help, -h` is enabled by default. + +To disable it, set `help` to `false`. The help documentation can still be manually displayed by calling `.showHelp(helpOptions)` on the returned object. + +##### Version flag +To enable handling `--version`, specify the `version` property. + +```ts +cli({ + version: '1.2.3' +}) +``` + +```sh +$ my-script --version +1.2.3 +``` + +The version is also shown in the help documentation. To opt out of handling `--version` while still showing the version in `--help`, pass the version into `help.version`. + +### Commands +Commands allow organizing multiple "scripts" into a single script. An example of this is the [`npm install`](https://docs.npmjs.com/cli/install/) command, which is essentially an "install" script inside the "npm" script, adjacent to other commands like [`npm run`](https://docs.npmjs.com/cli/run-script/). + +#### Defining commands +A command can be created by importing the `command` function and initializing it with a name. The rest of the options are the same as the `cli` function. + +Pass the created command into `cli` option's `commands` array-property to register it: + +_npm.js_ +```ts +import { cli, command } from 'cleye' + +const argv = cli({ + name: 'npm', + + version: '1.2.3', + + commands: [ + command({ + // Command name + name: 'install', + + parameters: [''], + + flags: { + noSave: Boolean, + saveDev: Boolean + } + }) + ] +}) + +// $ npm install lodash + +argv.command // => "install" (string) +argv._.packageName // => "lodash" (string) +``` + +Depending on the command given, the resulting type can be narrowed: +

+ +

+ +#### Command callback + +When a CLI app has many commands, it's recommended to organize each command in its own file. With this structure, parsed output handling for each command is better placed where they are respectively defined rather than the single `cli` output point. This can be done by passing a callback function into the `command` function (callbacks are supported in the `cli` function too). + +Example: + +_install-command.js_ (`install` command using callback) +```ts +import { command } from 'cleye' + +export const installCommand = command({ + // Command name + name: 'install', + + parameters: [''], + + flags: { + noSave: Boolean, + saveDev: Boolean + } +}, (argv) => { + // $ npm install lodash + + argv._.packageName // => "lodash" (string) +}) +``` + +_npm.js_ (CLI entry file) +```ts +import { installCommand } from './install-command.js' + +cli({ + name: 'npm', + + commands: [ + installCommand + ] +}) +``` + +### Help documentation +_Cleye_ uses all information provided to generate rich help documentation. The more information you give, the better the docs! + +#### Help customization +The help document can be customized by passing a `render(nodes, renderers) => string` function to `help.render`. + +The `nodes` parameter contains an array of nodes that will be used to render the document. The `renderers` parameter is an object of functions used to render the document. Each node has properties `type` and `data`, where `type` corresponds to a property in `renderers` and `data` is passed into the render function. + +Default renderers can be found in [`/src/render-help/renderers.ts`](/src/render-help/renderers.ts). + +Here's an example that adds an extra sentence at the end and also updates the flags table to use the `=` operator (`--flag ` → `--flag=`): + +```ts +cli({ + // ..., + + help: { + render(nodes, renderers) { + /* Modify nodes... */ + + // Add some text at end of document + nodes.push('\nCheckout Cleye: https://github.com/privatenumber/cleye') + + /* Extend renderers... */ + + // Make all flag examples use `=` as the separator + renderers.flagOperator = () => '=' + + /* Render nodes and return help */ + return renderers.render(nodes) + } + } +}) +``` + +#### Responsive tables +_Cleye_'s "Flags" table in the help document is responsive and wraps cell text content based on the column & terminal width. It also has [breakpoints to display more vertically-optimized tables](/src/render-help/render-flags.ts#L4) for narrower viewports. + +This feature is powered by [terminal-columns](https://github.com/privatenumber/terminal-columns) and can be configured via the `renderers.table` renderer. + + + + + + + + + + +
Normal widthNarrow width
+ +## API + +### cli(options, callback?, argvs?) + +Return type: +```ts +type ParsedArgv = { + // Parsed arguments + _: string[] & Parameters + + // Parsed flags + flags: { + [flagName: string]: InferredType + } + + // Unexpected flags + unknownFlags: { + [flagName: string]: (string | boolean)[] + } + + // Method to print version + showVersion: () => void + + // Method to print help + showHelp: (options: HelpOptions) => void +} +``` + +Function to parse argvs by declaring parameters and flags. + +#### options + +Options object to configure `cli`. +##### name + +Type: `string` + +Name of the script used in the help documentation. + +##### version + +Type: `string` + +Version of the script used in the help documentation. + +Passing this in enables auto-handling `--version`. To provide a version for the documentation without auto-handling `--version`, pass it into [`help.version`](#version-1). + +##### parameters + +Type: `string[]` + +Parameter names to map onto arguments. Also used for validation and help documentation. + +Parameters must be defined in the following formats: +| Format | Description | +| - | - | +| `` | Required parameter | +| `[parameter name]` | Optional parameter | +| `` | Required spread parameter (1 or more) | +| `[parameter name...]` | Optional spread parameter (0 or more) | + +Required parameters must be defined before optional parameters, and spread parameters must be defined at the end. + +##### flags + +Type: An object that maps the flag name (in camelCase) to a flag type function or an object describing the flag: + +| Property | Type | Description | +| - | - | - | +| `type` | `Function` | Flag value parsing function. | +| `alias` | `string` | Single character alias for the flag. | +| `default` | `any` | Default value for the flag. | +| `description` | `string` | Description of the flag shown in `--help`. | +| `placeholder` | `string` | Placeholder for the flag value shown in `--help`. | + +##### help + +Type: `false` or an object with the following properties. + +| Property | Type | Description | +| - | - | - | +| `version` | `string` | Version shown in `--help`. | +| `description` | `string` | Description shown in `--help`. | +| `usage` | `string \| string[]` | Usage code examples shown in `--help`. | +| `examples` | `string \| string[]` | Example code snippets shown in `--help`. | +| `render` | `(nodes, renderers) => string` | Function to customize the help document. | + +Handling `--help, -h` is enabled by default. To disable it, pass in `false`. + +##### commands + +Type: `Command[]` + +Array of [commands](#commandoptions-callback) to register. + + +#### callback(parsed) + +Type: + +Optional callback function that is called when the script is invoked without a command. + +#### argvs + +Type: `string[]` + +Default: `process.argv.slice(2)` + +The raw parameters array to parse. + +### command(options, callback?) + +#### options + +| Property | Type | Description | +| - | - | - | +| `name` | `string` | Required name used to invoke the command. | +| `alias` | `string \| string[]` | Aliases used to invoke the command. | +| `parameters` | `string[]` | Parameters for the command. Same as [`parameters`](#parameters-1). | +| `flags` | `Flags` | Flags for the command. Same as [`flags`](#flags-1). | +| `help` | `false \| HelpOptions` | Help options for the command. Same as [`help`](#help-1). | + +#### callback(parsed) + +Type: + +Optional callback function that is called when the command is invoked. diff --git a/examples/esbuild/index.ts b/examples/esbuild/index.ts new file mode 100644 index 0000000..08515ee --- /dev/null +++ b/examples/esbuild/index.ts @@ -0,0 +1,292 @@ +import { underline } from 'colorette'; +import { cli } from '../../src'; + +const simpleFlags = { + bundle: { + type: Boolean, + description: 'Bundle all dependencies into the output files', + }, + define: { + type: String, + description: 'Substitute K with V while parsing', + }, + external: { + type: String, + description: 'Exclude module M from the bundle (can use * wildcards)', + }, + format: { + type: String, + description: 'Output format (iife | cjs | esm, no default when not bundling, otherwise default is iife when platform is browser and cjs when platform is node)', + }, + loader: { + type: String, + description: 'Use loader L to load file extension X, where L is one of: js | jsx | ts | tsx | json | text | base64 | file | dataurl | binary', + }, + minify: { + type: Boolean, + description: 'Minify the output (sets all --minify-* flags)', + }, + outdir: { + type: String, + description: 'The output directory (for multiple entry points)', + }, + outfile: { + type: String, + description: 'The output file (for one entry point)', + }, + platform: { + type: String, + description: 'Platform target (browser | node | neutral, default browser)', + }, + serve: { + type: String, + description: 'Start a local HTTP server on this host:port for outputs', + }, + sourcemap: { + type: Boolean, + description: 'Enable a source map', + }, + splitting: { + type: Boolean, + description: 'Enable code splitting (currently only for esm)', + }, + target: { + type: String, + description: 'Environment target (e.g. es2017, chrome58, firefox57, safari11, edge16, node10, default esnext)', + }, + watch: { + type: Boolean, + description: 'Watch mode: rebuild on file system changes', + }, +}; + +const advancedFlags = { + allowOverwrite: { + type: Boolean, + description: 'Allow output files to overwrite input files', + }, + assetNames: { + type: Boolean, + description: 'Path template to use for "file" loader files (default "[name]-[hash]")', + }, + charset: { + type: Boolean, + description: 'Do not escape UTF-8 code points', + }, + chunkNames: { + type: Boolean, + description: 'Path template to use for code splitting chunks (default "[name]-[hash]")', + }, + color: { + type: Boolean, + description: 'Force use of color terminal escapes (true | false)', + }, + entryNames: { + type: Boolean, + description: 'Path template to use for entry point output paths (default "[dir]/[name]", can also use "[hash]")', + }, + globalName: { + type: Boolean, + description: 'The name of the global for the IIFE format', + }, + jsxFactory: { + type: Boolean, + description: 'What to use for JSX instead of React.createElement', + }, + jsxFragment: { + type: Boolean, + description: 'What to use for JSX instead of React.Fragment', + }, + jsx: { + type: Boolean, + description: 'Set to "preserve" to disable transforming JSX to JS', + }, + keepNames: { + type: Boolean, + description: 'Preserve "name" on functions and classes', + }, + legalComments: { + type: Boolean, + description: 'Where to place license comments (none | inline | eof | linked | external, default eof when bundling and inline otherwise)', + }, + logLevel: { + type: Boolean, + description: 'Disable logging (verbose | debug | info | warning | error | silent, default info)', + }, + logLimit: { + type: Boolean, + description: 'Maximum message count or 0 to disable (default 10)', + }, + mainFields: { + type: Boolean, + description: 'Override the main file order in package.json (default "browser,module,main" when platform is browser and "main,module" when platform is node)', + }, + metafile: { + type: Boolean, + description: 'Write metadata about the build to a JSON file', + }, + minifyWhitespace: { + type: Boolean, + description: 'Remove whitespace in output files', + }, + minifyIdentifiers: { + type: Boolean, + description: 'Shorten identifiers in output files', + }, + minifySyntax: { + type: Boolean, + description: 'Use equivalent but shorter syntax in output files', + }, + outbase: { + type: Boolean, + description: 'The base path used to determine entry point output paths (for multiple entry points)', + }, + preserveSymlinks: { + type: Boolean, + description: 'Disable symlink resolution for module lookup', + }, + publicPath: { + type: Boolean, + description: 'Set the base URL for the "file" loader', + }, + resolveExtensions: { + type: Boolean, + description: 'A comma-separated list of implicit extensions (default ".tsx,.ts,.jsx,.js,.css,.json")', + }, + servedir: { + type: Boolean, + description: 'What to serve in addition to generated output files', + }, + sourceRoot: { + type: Boolean, + description: 'Sets the "sourceRoot" field in generated source maps', + }, + sourcefile: { + type: Boolean, + description: 'Set the source file for the source map (for stdin)', + }, + sourcesContent: { + type: Boolean, + description: 'Omit "sourcesContent" in generated source maps', + }, + treeShaking: { + type: Boolean, + description: 'Set to "ignore-annotations" to work with packages that have incorrect tree-shaking annotations', + }, + tsconfig: { + type: Boolean, + description: 'Use this tsconfig.json file instead of other ones', + }, + version: { + type: Boolean, + description: 'Print the current version (0.12.14) and exit', + }, +}; + +const app = cli({ + + name: 'esbuild', + + version: '1.0.0', + + parameters: ['[entry points]'], + + flags: { + ...simpleFlags, + ...advancedFlags, + help: Boolean, + }, + + help: { + examples: [ + '# Produces dist/entry_point.js and dist/entry_point.js.map', + 'esbuild --bundle entry_point.js --outdir=dist --minify --sourcemap', + '', + '# Allow JSX syntax in .js files', + 'esbuild --bundle entry_point.js --outfile=out.js --loader:.js=jsx', + '', + '# Substitute the identifier RELEASE for the literal true', + 'esbuild example.js --outfile=out.js --define:RELEASE=true', + '', + '# Provide input via stdin, get output via stdout', + 'esbuild --minify --loader=ts < input.ts > output.js', + '', + '# Automatically rebuild when input files are changed', + 'esbuild app.ts --bundle --watch', + '', + '# Start a local HTTP server for everything in "www"', + 'esbuild app.ts --bundle --servedir=www --outdir=www/js', + ], + + render(nodes, renderers) { + const [, usage, flags, examples] = nodes; + + // Replace "flags" with "options" + usage.data.body = usage.data.body.replace('flags', 'options'); + + // Update renderer so flags that accept a value shows `=...` + renderers.flagOperator = () => '='; + renderers.flagParameter = flagType => (flagType === Boolean ? '' : '...'); + + const { tableData: flagsTableData } = flags.data.body.data; + + return renderers.render([ + usage, + + // Add Documentation & Repository links + { + type: 'section', + data: { + title: 'Documentation:', + body: underline('https://esbuild.github.io/'), + }, + }, + { + type: 'section', + data: { + title: 'Repository:', + body: underline('https://github.com/evanw/esbuild'), + }, + }, + + // Split Flags into "Simple options" and "Advanced options" + { + type: 'section', + data: { + title: 'Simple options:', + body: { + type: 'table', + data: { + ...flags, + tableData: flagsTableData.filter( + ([flagName]: [{ data: { name: string }}]) => flagName.data.name in simpleFlags, + ), + }, + }, + indentBody: 0, + }, + }, + { + type: 'section', + data: { + title: 'Advanced options:', + body: { + type: 'table', + data: { + ...flags, + tableData: flagsTableData.filter( + ([flagName]: [{ data: { name: string }}]) => flagName.data.name in advancedFlags, + ), + }, + }, + indentBody: 0, + }, + }, + flags, + examples, + ]); + }, + }, +}); + +console.log(app); diff --git a/examples/greet/index.ts b/examples/greet/index.ts new file mode 100644 index 0000000..0b8694d --- /dev/null +++ b/examples/greet/index.ts @@ -0,0 +1,32 @@ +import { cli } from '../../src'; + +// Parse argv +const argv = cli({ + name: 'greet.js', + + // Define parameters + // Becomes available in ._.filePath + parameters: [ + '', // First name is required + '[last name]', // Last name is optional + ], + + // Define flags/options + // Becomes available in .flags + flags: { + // Parses `--time` as a string + time: { + type: String, + description: 'Time of day to greet (morning or evening)', + default: 'morning', + }, + }, +}); + +const name = [argv._.firstName, argv._.lastName].filter(Boolean).join(' '); + +if (argv.flags.time === 'morning') { + console.log(`Good morning ${name}!`); +} else { + console.log(`Good evening ${name}!`); +} diff --git a/examples/npm/commands/install.ts b/examples/npm/commands/install.ts new file mode 100644 index 0000000..8acd39f --- /dev/null +++ b/examples/npm/commands/install.ts @@ -0,0 +1,42 @@ +import { command } from '../../../src'; + +export const install = command({ + name: 'install', + + alias: ['i', 'isntall', 'add'], + + flags: { + global: { + type: Boolean, + alias: 'g', + }, + saveProd: String, + saveDev: { + type: Boolean, + alias: 'D', + }, + saveOptional: Boolean, + saveExact: Boolean, + noSave: Boolean, + }, + + help: { + description: 'Install a package', + + examples: [ + 'npm install (with no args, in package dir)', + 'npm install [<@scope>/]', + 'npm install [<@scope>/]@', + 'npm install [<@scope>/]@', + 'npm install [<@scope>/]@', + 'npm install @npm:', + 'npm install ', + 'npm install ', + 'npm install ', + 'npm install ', + 'npm install /', + ], + }, +}, (argv) => { + console.log('install!', argv); +}); diff --git a/examples/npm/index.ts b/examples/npm/index.ts new file mode 100644 index 0000000..40a5d5b --- /dev/null +++ b/examples/npm/index.ts @@ -0,0 +1,24 @@ +/** + * Demo showing how `npm i --help` can be re-implemented with cleye + * + * Usage: + * npx esno examples/npm i --help + */ + +import { cli } from '../../src'; +import { install } from './commands/install'; + +const argv = cli({ + name: 'npm', + + commands: [ + install, + ], +}); + +// Type narrowing by command name +if (argv.command === 'install') { + console.log(argv.flags); +} else { + console.log(argv.flags); +} diff --git a/examples/pkg-size/index.ts b/examples/pkg-size/index.ts new file mode 100644 index 0000000..87212ee --- /dev/null +++ b/examples/pkg-size/index.ts @@ -0,0 +1,75 @@ +/** + * Usage: + * npx esno examples/pkg-size --help + */ + +import { cli } from '../../src'; + +const argv = cli({ + name: 'pkg-size', + + version: '1.0.0', + + parameters: [''], + + flags: { + sizes: { + type: [String], + alias: 'S', + default: () => ['size', 'gzip', 'brotli'], + description: 'Comma separated list of sizes to show (size, gzip, brotli)', + placeholder: '', + }, + sortBy: { + type: String, + alias: 's', + default: 'brotli', + description: 'Sort list by (name, size, gzip, brotli)', + placeholder: '', + }, + unit: { + type: String, + alias: 'u', + default: 'metric', + description: 'Display units (metric, iec, metric_octet, iec_octet)', + placeholder: '', + }, + ignoreFiles: { + type: String, + alias: 'i', + description: 'Glob to ignores files from list. Total size will still include them.', + placeholder: '', + }, + json: { + type: Boolean, + description: 'JSON output', + }, + }, + + help: { + examples: [ + 'pkg-size', + 'pkg-size ./package/path', + + '', + + '# Display formats', + 'pkg-size --sizes=size,gzip,brotli', + 'pkg-size -S brotli', + + '', + + '# Sorting', + 'pkg-size --sort-by=name', + 'pkg-size -s size', + 'pkg-size --unit=iec', + + '', + + '# Formatting', + 'pkg-size -u metric_octet', + ], + }, +}); + +console.log(argv); diff --git a/examples/snap-tweet/index.ts b/examples/snap-tweet/index.ts new file mode 100644 index 0000000..61cca64 --- /dev/null +++ b/examples/snap-tweet/index.ts @@ -0,0 +1,61 @@ +/** + * Usage: + * npx esno examples/snap-tweet --help + */ + +import { cli } from '../../src'; + +const argv = cli({ + name: 'snap-tweet', + + version: '1.0.0', + + parameters: [''], + + flags: { + outputDir: { + type: String, + alias: 'o', + description: 'Tweet screenshot output directory', + placeholder: '', + }, + width: { + type: Number, + alias: 'w', + description: 'Width of tweet', + default: 550, + placeholder: '', + }, + showTweet: { + type: Boolean, + alias: 't', + description: 'Show tweet thread', + }, + darkMode: { + type: Boolean, + alias: 'd', + description: 'Show tweet in dark mode', + }, + locale: { + type: String, + description: 'Locale', + default: 'en', + placeholder: '', + }, + }, + + help: { + examples: [ + '# Snapshot a tweet', + 'snap-tweet https://twitter.com/jack/status/20', + '', + '# Snapshot a tweet with Japanese locale', + 'snap-tweet https://twitter.com/TwitterJP/status/578707432 --locale ja', + '', + '# Snapshot a tweet with dark mode and 900px width', + 'snap-tweet https://twitter.com/Interior/status/463440424141459456 --width 900 --dark-mode', + ], + }, +}); + +console.log(argv); diff --git a/examples/tsc/index.ts b/examples/tsc/index.ts new file mode 100644 index 0000000..8c54a8d --- /dev/null +++ b/examples/tsc/index.ts @@ -0,0 +1,307 @@ +/** + * Demo showing how `tsc --help` can be re-implemented with cleye + * + * Usage: + * npx esno examples/tsc --help + */ + +import assert from 'assert'; +import { cli } from '../../src'; + +// https://github.com/microsoft/TypeScript/blob/7a12909ae3f03b1feed19df2082aa84e5c7a5081/src/executeCommandLine/executeCommandLine.ts#L111 +function blue(string_: string) { + return `\u001B[94m${string_}\u001B[39m`; +} + +const targetType = ['es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'esnext']; + +const moduleTypes = ['none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'esnext'] as const; + +const libraryTypes = ['es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'webworker.iterable', 'scripthost', 'es2015.core', 'es2015.coll ection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015 .symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2 017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asyncgenerator', 'es2018.asynciterable', 'es201 8.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.object', 'es2019.string', 'es2019.symbo l', 'es2020.bigint', 'es2020.promise', 'es2020.sharedmemory', 'es2020.string', 'es2020.symbol.wellknown', 'es2020.intl', 'es2021.promise', 'es2021.string', 'es2021.weakref', 'esnext.array', 'esnext.symbol', 'esnext .asynciterable', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise', 'esnext.weakref'] as const; + +const jsxTypes = [undefined, 'preserve', 'react-native', 'react', 'react-jsx', 'react-jsxdev'] as const; + +const commandLineFlags = { + help: { + type: Boolean, + alias: 'h', + description: 'Print this message.', + }, + watch: { + type: Boolean, + alias: 'w', + description: 'Watch input files.', + }, + all: { + type: Boolean, + description: 'Show all compiler options.', + }, + version: { + type: Boolean, + alias: 'v', + description: 'Print the compiler\'s version.', + }, + init: { + type: Boolean, + description: 'Initializes a TypeScript project and creates a tsconfig.json file.', + }, + project: { + type: Boolean, + alias: 'p', + description: 'Compile the project given the path to its configuration file, or to a folder with a \'tsconfig.json\'.', + }, + build: { + type: Boolean, + alias: 'b', + description: 'Build one or more projects and their dependencies, if out of date', + }, + showConfig: { + type: Boolean, + description: 'Print the final configuration instead of building.', + }, +}; + +const commonCompilerOptions = { + pretty: { + type: Boolean, + description: 'Enable color and formatting in TypeScript\'s output to make compiler errors easier to read', + default: true, + }, + + target: { + type: function TargetType(value: typeof targetType[number]) { + assert(targetType.includes(value), 'Invalid target type'); + return value; + }, + alias: 't', + description: `Set the JavaScript language version for emitted JavaScript and include compatible library declarations.\none of: ${targetType.join(', ')}`, + default: 'ES3', + }, + + module: { + type: function ModuleType(value: typeof moduleTypes[number]) { + assert(moduleTypes.includes(value), 'Invalid module type'); + return value; + }, + alias: 'm', + description: `Specify what module code is generated.\none of: ${moduleTypes.join(', ')}`, + }, + + lib: { + type: [ + function LibraryType(value: typeof libraryTypes[number]) { + assert(libraryTypes.includes(value), 'Invalid library type'); + return value; + }, + ] as const, + description: `Specify a set of bundled library declaration files that describe the target runtime environment.\none or more: ${libraryTypes.join(', ')}`, + }, + + allowJs: { + type: Boolean, + description: 'Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files.', + + }, + + checkJs: { + type: Boolean, + description: 'Enable error reporting in type-checked JavaScript files.', + }, + + jsx: { + type: function JsxType(value: typeof jsxTypes[number]) { + assert(jsxTypes.includes(value), 'Invalid jsx type'); + return value; + }, + description: `Specify what JSX code is generated.\none of: ${jsxTypes.join(', ')}`, + }, + + declaration: { + type: Boolean, + alias: 'd', + description: 'Generate .d.ts files from TypeScript and JavaScript files in your project.', + }, + + declarationMap: { + type: Boolean, + description: 'Create sourcemaps for d.ts files.', + }, + + emitDeclarationOnly: { + type: Boolean, + description: 'Only output d.ts files and not JavaScript files.', + }, + + sourceMap: { + type: Boolean, + description: 'Create source map files for emitted JavaScript files.', + }, + + outFile: { + type: String, + description: 'Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output.', + }, + + outDir: { + type: String, + description: 'Specify an output folder for all emitted files.', + }, + + removeComments: { + type: Boolean, + description: 'Disable emitting comments.', + }, + + noEmit: { + type: Boolean, + description: 'Disable emitting files from a compilation.', + }, + + strict: { + type: Boolean, + description: 'Enable all strict type-checking options.', + }, + + types: { + type: String, + description: 'Specify type package names to be included without being referenced in a source file.', + }, + + esModuleInterop: { + type: Boolean, + description: 'Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility.', + }, +}; + +const tableBreakpoints = { + '> 80': [ + { + align: 'right', + width: 'content-width', + paddingLeft: 2, + paddingRight: 2, + paddingBottom: 1, + }, + { + paddingBottom: 1, + }, + ], + '> 0': [ + { + width: '100%', + paddingLeft: 2, + paddingRight: 2, + }, + { + width: '100%', + paddingLeft: 2, + paddingRight: 2, + paddingBottom: 1, + }, + ], +}; + +const argv = cli({ + flags: { + ...commandLineFlags, + ...commonCompilerOptions, + }, + + help: { + usage: false, + examples: [ + blue('tsc'), + 'Compiles the current project (tsconfig.json in the working directory.)', + + '', + + blue('tsc app.ts util.ts'), + 'Ignoring tsconfig.json, compiles the specified files with default compiler options.', + + '', + + blue('tsc -b'), + 'Build a composite project in the working directory.', + + '', + + blue('tsc --init'), + 'Creates a tsconfig.json with the recommended settings in the working directory.', + + '', + + blue('tsc -p ./path/to/tsconfig.json'), + 'Compiles the TypeScript project located at the specified path.', + + '', + + blue('tsc --help --all'), + 'An expanded version of this information, showing all possible compiler options', + + '', + + blue('tsc --noEmit'), + blue('tsc --target esnext'), + 'Compiles the current project, with additional settings.', + ], + + render(nodes, renderers) { + const [flags, commonCommands] = nodes; + + commonCommands.data.title = 'COMMON COMMANDS'; + commonCommands.data.body = `\n${commonCommands.data.body}`; + nodes.splice(1, 0, commonCommands); + + const { tableData: flagsTableData } = flags.data.body.data; + + renderers.flagName = function (flag) { + const flagName = `--${flag.name}`; + return blue(flagName + (flag.aliasFormatted ? `, ${flag.aliasFormatted}` : '')); + }; + + return renderers.render([ + 'tsc: The TypeScript Compiler - Version 0.0.0\n', + commonCommands, + { + type: 'section', + data: { + title: 'COMMAND LINE FLAGS\n', + body: { + type: 'table', + data: { + tableBreakpoints, + tableData: flagsTableData.filter( + ( + [flagName]: [{ data: { name: string }}], + ) => flagName.data.name in commandLineFlags, + ), + }, + }, + indentBody: 0, + }, + }, + { + type: 'section', + data: { + title: 'COMMON COMPILER OPTIONS\n', + body: { + type: 'table', + data: { + tableBreakpoints, + tableData: flagsTableData.filter( + ( + [flagName]: [{ data: { name: string }}], + ) => flagName.data.name in commonCompilerOptions, + ), + }, + }, + indentBody: 0, + }, + }, + 'You can learn about all of the compiler options at https://aka.ms/tsconfig-reference', + ]); + }, + }, +}); + +console.log(argv); diff --git a/examples/tsconfig.json b/examples/tsconfig.json new file mode 100644 index 0000000..d8e40f5 --- /dev/null +++ b/examples/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "..", + "include": ["."] +} diff --git a/jest.config.json b/jest.config.json new file mode 100644 index 0000000..5ee27d0 --- /dev/null +++ b/jest.config.json @@ -0,0 +1,3 @@ +{ + "preset": "es-jest" +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ad06451 --- /dev/null +++ b/package.json @@ -0,0 +1,73 @@ +{ + "name": "cleye", + "version": "0.0.0-semantic-release", + "description": "The intuitive CLI development tool", + "keywords": [ + "cli", + "command line", + "argv", + "parameters", + "flags", + "node", + "typescript" + ], + "license": "MIT", + "repository": "privatenumber/cleye", + "funding": "https://github.com/privatenumber/cleye?sponsor=1", + "author": { + "name": "Hiroki Osame", + "email": "hiroki.osame@gmail.com" + }, + "files": [ + "dist" + ], + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "require": "./dist/index.js", + "import": "./dist/index.mjs", + "types": "./dist/index.d.ts" + } + }, + "scripts": { + "build": "tsup src/index.ts --dts --format esm,cjs --minify", + "lint": "eslint .", + "test": "CI=true jest" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged && npm test" + } + }, + "lint-staged": { + "*.ts": [ + "eslint" + ] + }, + "dependencies": { + "terminal-columns": "^1.4.0", + "type-flag": "^2.0.0" + }, + "devDependencies": { + "@pvtnbr/eslint-config": "^0.11.0", + "@types/jest": "^27.4.0", + "@types/node": "^17.0.8", + "colorette": "^2.0.16", + "es-jest": "^1.5.0", + "eslint": "^8.6.0", + "esno": "^0.13.0", + "husky": "^4.3.8", + "jest": "^27.4.7", + "lint-staged": "^12.1.2", + "tsup": "^5.11.10", + "typescript": "^4.5.4" + }, + "eslintConfig": { + "extends": "@pvtnbr", + "rules": { + "unicorn/no-process-exit": "off" + } + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..5e35b01 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,5333 @@ +lockfileVersion: 5.3 + +specifiers: + '@pvtnbr/eslint-config': ^0.11.0 + '@types/jest': ^27.4.0 + '@types/node': ^17.0.8 + colorette: ^2.0.16 + es-jest: ^1.5.0 + eslint: ^8.6.0 + esno: ^0.13.0 + husky: ^4.3.8 + jest: ^27.4.7 + lint-staged: ^12.1.2 + terminal-columns: ^1.4.0 + tsup: ^5.11.10 + type-flag: ^2.0.0 + typescript: ^4.5.4 + +dependencies: + terminal-columns: 1.4.0 + type-flag: 2.0.0 + +devDependencies: + '@pvtnbr/eslint-config': 0.11.0_eslint@8.6.0+typescript@4.5.4 + '@types/jest': 27.4.0 + '@types/node': 17.0.8 + colorette: 2.0.16 + es-jest: 1.5.0 + eslint: 8.6.0 + esno: 0.13.0_typescript@4.5.4 + husky: 4.3.8 + jest: 27.4.7 + lint-staged: 12.1.5 + tsup: 5.11.10_typescript@4.5.4 + typescript: 4.5.4 + +packages: + + /@babel/code-frame/7.16.7: + resolution: {integrity: sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.16.7 + dev: true + + /@babel/compat-data/7.16.4: + resolution: {integrity: sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core/7.16.7: + resolution: {integrity: sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.16.7 + '@babel/generator': 7.16.7 + '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.16.7 + '@babel/helper-module-transforms': 7.16.7 + '@babel/helpers': 7.16.7 + '@babel/parser': 7.16.7 + '@babel/template': 7.16.7 + '@babel/traverse': 7.16.7 + '@babel/types': 7.16.7 + convert-source-map: 1.8.0 + debug: 4.3.3 + gensync: 1.0.0-beta.2 + json5: 2.2.0 + semver: 6.3.0 + source-map: 0.5.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/eslint-parser/7.16.5_@babel+core@7.16.7+eslint@8.6.0: + resolution: {integrity: sha512-mUqYa46lgWqHKQ33Q6LNCGp/wPR3eqOYTUixHFsfrSQqRxH0+WOzca75iEjFr5RDGH1dDz622LaHhLOzOuQRUA==} + engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} + peerDependencies: + '@babel/core': '>=7.11.0' + eslint: ^7.5.0 || ^8.0.0 + dependencies: + '@babel/core': 7.16.7 + eslint: 8.6.0 + eslint-scope: 5.1.1 + eslint-visitor-keys: 2.1.0 + semver: 6.3.0 + dev: true + + /@babel/generator/7.16.7: + resolution: {integrity: sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.16.7 + jsesc: 2.5.2 + source-map: 0.5.7 + dev: true + + /@babel/helper-compilation-targets/7.16.7_@babel+core@7.16.7: + resolution: {integrity: sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.16.4 + '@babel/core': 7.16.7 + '@babel/helper-validator-option': 7.16.7 + browserslist: 4.19.1 + semver: 6.3.0 + dev: true + + /@babel/helper-environment-visitor/7.16.7: + resolution: {integrity: sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.16.7 + dev: true + + /@babel/helper-function-name/7.16.7: + resolution: {integrity: sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-get-function-arity': 7.16.7 + '@babel/template': 7.16.7 + '@babel/types': 7.16.7 + dev: true + + /@babel/helper-get-function-arity/7.16.7: + resolution: {integrity: sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.16.7 + dev: true + + /@babel/helper-hoist-variables/7.16.7: + resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.16.7 + dev: true + + /@babel/helper-module-imports/7.16.7: + resolution: {integrity: sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.16.7 + dev: true + + /@babel/helper-module-transforms/7.16.7: + resolution: {integrity: sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.16.7 + '@babel/helper-module-imports': 7.16.7 + '@babel/helper-simple-access': 7.16.7 + '@babel/helper-split-export-declaration': 7.16.7 + '@babel/helper-validator-identifier': 7.16.7 + '@babel/template': 7.16.7 + '@babel/traverse': 7.16.7 + '@babel/types': 7.16.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-plugin-utils/7.16.7: + resolution: {integrity: sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-simple-access/7.16.7: + resolution: {integrity: sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.16.7 + dev: true + + /@babel/helper-split-export-declaration/7.16.7: + resolution: {integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.16.7 + dev: true + + /@babel/helper-validator-identifier/7.16.7: + resolution: {integrity: sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option/7.16.7: + resolution: {integrity: sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers/7.16.7: + resolution: {integrity: sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.16.7 + '@babel/traverse': 7.16.7 + '@babel/types': 7.16.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight/7.16.7: + resolution: {integrity: sha512-aKpPMfLvGO3Q97V0qhw/V2SWNWlwfJknuwAunU7wZLSfrM4xTBvg7E5opUVi1kJTBKihE38CPg4nBiqX83PWYw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.16.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser/7.16.7: + resolution: {integrity: sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==} + engines: {node: '>=6.0.0'} + hasBin: true + dev: true + + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.16.7: + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.16.7: + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.16.7: + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.16.7: + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.16.7: + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.16.7: + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.16.7: + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.16.7: + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.16.7: + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.16.7: + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.16.7: + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.16.7: + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/plugin-syntax-typescript/7.16.7_@babel+core@7.16.7: + resolution: {integrity: sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.16.7 + '@babel/helper-plugin-utils': 7.16.7 + dev: true + + /@babel/template/7.16.7: + resolution: {integrity: sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.16.7 + '@babel/parser': 7.16.7 + '@babel/types': 7.16.7 + dev: true + + /@babel/traverse/7.16.7: + resolution: {integrity: sha512-8KWJPIb8c2VvY8AJrydh6+fVRo2ODx1wYBU2398xJVq0JomuLBZmVQzLPBblJgHIGYG4znCpUZUZ0Pt2vdmVYQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.16.7 + '@babel/generator': 7.16.7 + '@babel/helper-environment-visitor': 7.16.7 + '@babel/helper-function-name': 7.16.7 + '@babel/helper-hoist-variables': 7.16.7 + '@babel/helper-split-export-declaration': 7.16.7 + '@babel/parser': 7.16.7 + '@babel/types': 7.16.7 + debug: 4.3.3 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types/7.16.7: + resolution: {integrity: sha512-E8HuV7FO9qLpx6OtoGfUQ2cjIYnbFwvZWYBS+87EwtdMvmUPJSwykpovFB+8insbpF0uJcpr8KMUi64XZntZcg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.16.7 + to-fast-properties: 2.0.0 + dev: true + + /@bcoe/v8-coverage/0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + + /@eslint/eslintrc/1.0.5: + resolution: {integrity: sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.3 + espree: 9.3.0 + globals: 13.12.0 + ignore: 4.0.6 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.0.4 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/config-array/0.9.2: + resolution: {integrity: sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.3 + minimatch: 3.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/object-schema/1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@istanbuljs/load-nyc-config/1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema/0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/console/27.4.6: + resolution: {integrity: sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + chalk: 4.1.2 + jest-message-util: 27.4.6 + jest-util: 27.4.2 + slash: 3.0.0 + dev: true + + /@jest/core/27.4.7: + resolution: {integrity: sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 27.4.6 + '@jest/reporters': 27.4.6 + '@jest/test-result': 27.4.6 + '@jest/transform': 27.4.6 + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.8.1 + exit: 0.1.2 + graceful-fs: 4.2.9 + jest-changed-files: 27.4.2 + jest-config: 27.4.7 + jest-haste-map: 27.4.6 + jest-message-util: 27.4.6 + jest-regex-util: 27.4.0 + jest-resolve: 27.4.6 + jest-resolve-dependencies: 27.4.6 + jest-runner: 27.4.6 + jest-runtime: 27.4.6 + jest-snapshot: 27.4.6 + jest-util: 27.4.2 + jest-validate: 27.4.6 + jest-watcher: 27.4.6 + micromatch: 4.0.4 + rimraf: 3.0.2 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /@jest/environment/27.4.6: + resolution: {integrity: sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/fake-timers': 27.4.6 + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + jest-mock: 27.4.6 + dev: true + + /@jest/fake-timers/27.4.6: + resolution: {integrity: sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + '@sinonjs/fake-timers': 8.1.0 + '@types/node': 17.0.8 + jest-message-util: 27.4.6 + jest-mock: 27.4.6 + jest-util: 27.4.2 + dev: true + + /@jest/globals/27.4.6: + resolution: {integrity: sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.4.6 + '@jest/types': 27.4.2 + expect: 27.4.6 + dev: true + + /@jest/reporters/27.4.6: + resolution: {integrity: sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 27.4.6 + '@jest/test-result': 27.4.6 + '@jest/transform': 27.4.6 + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + chalk: 4.1.2 + collect-v8-coverage: 1.0.1 + exit: 0.1.2 + glob: 7.2.0 + graceful-fs: 4.2.9 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 5.1.0 + istanbul-lib-report: 3.0.0 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.3 + jest-haste-map: 27.4.6 + jest-resolve: 27.4.6 + jest-util: 27.4.2 + jest-worker: 27.4.6 + slash: 3.0.0 + source-map: 0.6.1 + string-length: 4.0.2 + terminal-link: 2.1.1 + v8-to-istanbul: 8.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/source-map/27.4.0: + resolution: {integrity: sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + callsites: 3.1.0 + graceful-fs: 4.2.9 + source-map: 0.6.1 + dev: true + + /@jest/test-result/27.4.6: + resolution: {integrity: sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/console': 27.4.6 + '@jest/types': 27.4.2 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.1 + dev: true + + /@jest/test-sequencer/27.4.6: + resolution: {integrity: sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/test-result': 27.4.6 + graceful-fs: 4.2.9 + jest-haste-map: 27.4.6 + jest-runtime: 27.4.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/transform/27.4.6: + resolution: {integrity: sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@babel/core': 7.16.7 + '@jest/types': 27.4.2 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 1.8.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.9 + jest-haste-map: 27.4.6 + jest-regex-util: 27.4.0 + jest-util: 27.4.2 + micromatch: 4.0.4 + pirates: 4.0.4 + slash: 3.0.0 + source-map: 0.6.1 + write-file-atomic: 3.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types/27.4.2: + resolution: {integrity: sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 17.0.8 + '@types/yargs': 16.0.4 + chalk: 4.1.2 + dev: true + + /@nodelib/fs.scandir/2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat/2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk/1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.13.0 + dev: true + + /@pvtnbr/eslint-config/0.11.0_eslint@8.6.0+typescript@4.5.4: + resolution: {integrity: sha512-YL9c1F/IQc0biQozd22YvzfWgUv4J1YaxtbY4gYtJYU5aCebw1Y28fJWy+fJcKz3d0ULl+4xq60kGJb+m0XdUQ==} + peerDependencies: + eslint: ^7.15.0 + dependencies: + '@typescript-eslint/eslint-plugin': 5.9.0_bd2fd93dbcc607ad2f21b784bccfe0c8 + '@typescript-eslint/parser': 5.9.0_eslint@8.6.0+typescript@4.5.4 + confusing-browser-globals: 1.0.11 + eslint: 8.6.0 + eslint-import-resolver-typescript: 2.5.0_b5a36b8c1535387c8dd00eff7ec6b551 + eslint-plugin-eslint-comments: 3.2.0_eslint@8.6.0 + eslint-plugin-import: 2.25.4_eslint@8.6.0 + eslint-plugin-jsonc: 2.0.0_eslint@8.6.0 + eslint-plugin-markdown: 2.2.1_eslint@8.6.0 + eslint-plugin-no-use-extend-native: 0.5.0 + eslint-plugin-node: 11.1.0_eslint@8.6.0 + eslint-plugin-promise: 6.0.0_eslint@8.6.0 + eslint-plugin-react: 7.28.0_eslint@8.6.0 + eslint-plugin-react-hooks: 4.3.0_eslint@8.6.0 + eslint-plugin-regexp: 1.5.1_eslint@8.6.0 + eslint-plugin-unicorn: 39.0.0_eslint@8.6.0 + eslint-plugin-vue: 8.2.0_eslint@8.6.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@sinonjs/commons/1.8.3: + resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers/8.1.0: + resolution: {integrity: sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==} + dependencies: + '@sinonjs/commons': 1.8.3 + dev: true + + /@tootallnate/once/1.1.2: + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} + engines: {node: '>= 6'} + dev: true + + /@types/babel__core/7.1.18: + resolution: {integrity: sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==} + dependencies: + '@babel/parser': 7.16.7 + '@babel/types': 7.16.7 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.14.2 + dev: true + + /@types/babel__generator/7.6.4: + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + dependencies: + '@babel/types': 7.16.7 + dev: true + + /@types/babel__template/7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.16.7 + '@babel/types': 7.16.7 + dev: true + + /@types/babel__traverse/7.14.2: + resolution: {integrity: sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==} + dependencies: + '@babel/types': 7.16.7 + dev: true + + /@types/graceful-fs/4.1.5: + resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} + dependencies: + '@types/node': 17.0.8 + dev: true + + /@types/istanbul-lib-coverage/2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + + /@types/istanbul-lib-report/3.0.0: + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + dev: true + + /@types/istanbul-reports/3.0.1: + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + dependencies: + '@types/istanbul-lib-report': 3.0.0 + dev: true + + /@types/jest/27.4.0: + resolution: {integrity: sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ==} + dependencies: + jest-diff: 27.4.6 + pretty-format: 27.4.6 + dev: true + + /@types/json-schema/7.0.9: + resolution: {integrity: sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==} + dev: true + + /@types/json5/0.0.29: + resolution: {integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=} + dev: true + + /@types/mdast/3.0.10: + resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /@types/node/17.0.8: + resolution: {integrity: sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg==} + dev: true + + /@types/normalize-package-data/2.4.1: + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + dev: true + + /@types/parse-json/4.0.0: + resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} + dev: true + + /@types/prettier/2.4.2: + resolution: {integrity: sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA==} + dev: true + + /@types/stack-utils/2.0.1: + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + dev: true + + /@types/unist/2.0.6: + resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} + dev: true + + /@types/yargs-parser/20.2.1: + resolution: {integrity: sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==} + dev: true + + /@types/yargs/16.0.4: + resolution: {integrity: sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==} + dependencies: + '@types/yargs-parser': 20.2.1 + dev: true + + /@typescript-eslint/eslint-plugin/5.9.0_bd2fd93dbcc607ad2f21b784bccfe0c8: + resolution: {integrity: sha512-qT4lr2jysDQBQOPsCCvpPUZHjbABoTJW8V9ZzIYKHMfppJtpdtzszDYsldwhFxlhvrp7aCHeXD1Lb9M1zhwWwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/experimental-utils': 5.9.0_eslint@8.6.0+typescript@4.5.4 + '@typescript-eslint/parser': 5.9.0_eslint@8.6.0+typescript@4.5.4 + '@typescript-eslint/scope-manager': 5.9.0 + '@typescript-eslint/type-utils': 5.9.0_eslint@8.6.0+typescript@4.5.4 + debug: 4.3.3 + eslint: 8.6.0 + functional-red-black-tree: 1.0.1 + ignore: 5.2.0 + regexpp: 3.2.0 + semver: 7.3.5 + tsutils: 3.21.0_typescript@4.5.4 + typescript: 4.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/experimental-utils/5.9.0_eslint@8.6.0+typescript@4.5.4: + resolution: {integrity: sha512-ZnLVjBrf26dn7ElyaSKa6uDhqwvAi4jBBmHK1VxuFGPRAxhdi18ubQYSGA7SRiFiES3q9JiBOBHEBStOFkwD2g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@types/json-schema': 7.0.9 + '@typescript-eslint/scope-manager': 5.9.0 + '@typescript-eslint/types': 5.9.0 + '@typescript-eslint/typescript-estree': 5.9.0_typescript@4.5.4 + eslint: 8.6.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0_eslint@8.6.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/parser/5.9.0_eslint@8.6.0+typescript@4.5.4: + resolution: {integrity: sha512-/6pOPz8yAxEt4PLzgbFRDpZmHnXCeZgPDrh/1DaVKOjvn/UPMlWhbx/gA96xRi2JxY1kBl2AmwVbyROUqys5xQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.9.0 + '@typescript-eslint/types': 5.9.0 + '@typescript-eslint/typescript-estree': 5.9.0_typescript@4.5.4 + debug: 4.3.3 + eslint: 8.6.0 + typescript: 4.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager/5.9.0: + resolution: {integrity: sha512-DKtdIL49Qxk2a8icF6whRk7uThuVz4A6TCXfjdJSwOsf+9ree7vgQWcx0KOyCdk0i9ETX666p4aMhrRhxhUkyg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.9.0 + '@typescript-eslint/visitor-keys': 5.9.0 + dev: true + + /@typescript-eslint/type-utils/5.9.0_eslint@8.6.0+typescript@4.5.4: + resolution: {integrity: sha512-uVCb9dJXpBrK1071ri5aEW7ZHdDHAiqEjYznF3HSSvAJXyrkxGOw2Ejibz/q6BXdT8lea8CMI0CzKNFTNI6TEQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/experimental-utils': 5.9.0_eslint@8.6.0+typescript@4.5.4 + debug: 4.3.3 + eslint: 8.6.0 + tsutils: 3.21.0_typescript@4.5.4 + typescript: 4.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types/5.9.0: + resolution: {integrity: sha512-mWp6/b56Umo1rwyGCk8fPIzb9Migo8YOniBGPAQDNC6C52SeyNGN4gsVwQTAR+RS2L5xyajON4hOLwAGwPtUwg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/typescript-estree/5.9.0_typescript@4.5.4: + resolution: {integrity: sha512-kxo3xL2mB7XmiVZcECbaDwYCt3qFXz99tBSuVJR4L/sR7CJ+UNAPrYILILktGj1ppfZ/jNt/cWYbziJUlHl1Pw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.9.0 + '@typescript-eslint/visitor-keys': 5.9.0 + debug: 4.3.3 + globby: 11.0.4 + is-glob: 4.0.3 + semver: 7.3.5 + tsutils: 3.21.0_typescript@4.5.4 + typescript: 4.5.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/visitor-keys/5.9.0: + resolution: {integrity: sha512-6zq0mb7LV0ThExKlecvpfepiB+XEtFv/bzx7/jKSgyXTFD7qjmSu1FoiS0x3OZaiS+UIXpH2vd9O89f02RCtgw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.9.0 + eslint-visitor-keys: 3.1.0 + dev: true + + /abab/2.0.5: + resolution: {integrity: sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==} + dev: true + + /acorn-globals/6.0.0: + resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + dev: true + + /acorn-jsx/5.3.2_acorn@8.7.0: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.7.0 + dev: true + + /acorn-walk/7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn/7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn/8.7.0: + resolution: {integrity: sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agent-base/6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /aggregate-error/3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ajv/6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ansi-colors/4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + dev: true + + /ansi-escapes/4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-regex/5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-regex/6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + + /ansi-styles/3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles/5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansi-styles/6.1.0: + resolution: {integrity: sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==} + engines: {node: '>=12'} + dev: true + + /any-promise/1.3.0: + resolution: {integrity: sha1-q8av7tzqUugJzcA3au0845Y10X8=} + dev: true + + /anymatch/3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /argparse/1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /argparse/2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-includes/3.1.4: + resolution: {integrity: sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + es-abstract: 1.19.1 + get-intrinsic: 1.1.1 + is-string: 1.0.7 + dev: true + + /array-union/2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.flat/1.2.5: + resolution: {integrity: sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + es-abstract: 1.19.1 + dev: true + + /array.prototype.flatmap/1.2.5: + resolution: {integrity: sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + es-abstract: 1.19.1 + dev: true + + /astral-regex/2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /asynckit/0.4.0: + resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} + dev: true + + /babel-jest/27.4.6_@babel+core@7.16.7: + resolution: {integrity: sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.16.7 + '@jest/transform': 27.4.6 + '@jest/types': 27.4.2 + '@types/babel__core': 7.1.18 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 27.4.0_@babel+core@7.16.7 + chalk: 4.1.2 + graceful-fs: 4.2.9 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-istanbul/6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.16.7 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.1.0 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist/27.4.0: + resolution: {integrity: sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@babel/template': 7.16.7 + '@babel/types': 7.16.7 + '@types/babel__core': 7.1.18 + '@types/babel__traverse': 7.14.2 + dev: true + + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.16.7: + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.16.7 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.16.7 + '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.16.7 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.16.7 + '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.16.7 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.16.7 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.16.7 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.16.7 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.16.7 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.16.7 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.16.7 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.16.7 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.16.7 + dev: true + + /babel-preset-jest/27.4.0_@babel+core@7.16.7: + resolution: {integrity: sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.16.7 + babel-plugin-jest-hoist: 27.4.0 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.16.7 + dev: true + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /binary-extensions/2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces/3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browser-process-hrtime/1.0.0: + resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} + dev: true + + /browserslist/4.19.1: + resolution: {integrity: sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001296 + electron-to-chromium: 1.4.35 + escalade: 3.1.1 + node-releases: 2.0.1 + picocolors: 1.0.0 + dev: true + + /bser/2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + + /buffer-from/1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /builtin-modules/3.2.0: + resolution: {integrity: sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==} + engines: {node: '>=6'} + dev: true + + /builtins/4.0.0: + resolution: {integrity: sha512-qC0E2Dxgou1IHhvJSLwGDSTvokbRovU5zZFuDY6oY8Y2lF3nGt5Ad8YZK7GMtqzY84Wu7pXTPeHQeHcXSXsRhw==} + dependencies: + semver: 7.3.5 + dev: true + + /bundle-require/2.2.0_esbuild@0.14.10: + resolution: {integrity: sha512-JDVxYEAxEX1g8AWtadiIkCkFf42RulEl5AOIvUa4cpuEL/VKpK2lJwogyswHnp+qizNQxM0Ylamw7CjPRaJZuA==} + peerDependencies: + esbuild: '>=0.13' + dependencies: + esbuild: 0.14.10 + dev: true + + /cac/6.7.12: + resolution: {integrity: sha512-rM7E2ygtMkJqD9c7WnFU6fruFcN3xe4FM5yUmgxhZzIKJk4uHl9U/fhwdajGFQbQuv43FAUo1Fe8gX/oIKDeSA==} + engines: {node: '>=8'} + dev: true + + /call-bind/1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.1 + dev: true + + /callsites/3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase/5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase/6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /caniuse-lite/1.0.30001296: + resolution: {integrity: sha512-WfrtPEoNSoeATDlf4y3QvkwiELl9GyPLISV5GejTbbQRtQx4LhsXmc9IQ6XCL2d7UxCyEzToEZNMeqR79OUw8Q==} + dev: true + + /chalk/2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk/4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /char-regex/1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + + /character-entities-legacy/1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + dev: true + + /character-entities/1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + dev: true + + /character-reference-invalid/1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + dev: true + + /chokidar/3.5.2: + resolution: {integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.2 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /ci-info/2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + dev: true + + /ci-info/3.3.0: + resolution: {integrity: sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==} + dev: true + + /cjs-module-lexer/1.2.2: + resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} + dev: true + + /clean-regexp/1.0.0: + resolution: {integrity: sha1-jffHquUf02h06PjQW5GAvBGj/tc=} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /clean-stack/2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-cursor/3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-truncate/2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + dev: true + + /cli-truncate/3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + slice-ansi: 5.0.0 + string-width: 5.0.1 + dev: true + + /cliui/7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /co/4.6.0: + resolution: {integrity: sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + + /collect-v8-coverage/1.0.1: + resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} + dev: true + + /color-convert/1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name/1.1.3: + resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} + dev: true + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /colorette/2.0.16: + resolution: {integrity: sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==} + dev: true + + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + + /commander/4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + + /commander/8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + dev: true + + /comment-parser/1.3.0: + resolution: {integrity: sha512-hRpmWIKgzd81vn0ydoWoyPoALEOnF4wt8yKD35Ib1D6XC2siLiYaiqfGkYrunuKdsXGwpBpHU3+9r+RVw2NZfA==} + engines: {node: '>= 12.0.0'} + dev: true + + /compare-versions/3.6.0: + resolution: {integrity: sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==} + dev: true + + /concat-map/0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true + + /confusing-browser-globals/1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + dev: true + + /convert-source-map/1.8.0: + resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /cosmiconfig/7.0.1: + resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==} + engines: {node: '>=10'} + dependencies: + '@types/parse-json': 4.0.0 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + dev: true + + /cross-spawn/7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /cssom/0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + dev: true + + /cssom/0.4.4: + resolution: {integrity: sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==} + dev: true + + /cssstyle/2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + dependencies: + cssom: 0.3.8 + dev: true + + /data-urls/2.0.0: + resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==} + engines: {node: '>=10'} + dependencies: + abab: 2.0.5 + whatwg-mimetype: 2.3.0 + whatwg-url: 8.7.0 + dev: true + + /debug/2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + dependencies: + ms: 2.0.0 + dev: true + + /debug/3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + dependencies: + ms: 2.1.3 + dev: true + + /debug/4.3.3: + resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /debug/4.3.3_supports-color@9.2.1: + resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + supports-color: 9.2.1 + dev: true + + /decimal.js/10.3.1: + resolution: {integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==} + dev: true + + /dedent/0.7.0: + resolution: {integrity: sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=} + dev: true + + /deep-is/0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /deepmerge/4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + dev: true + + /define-properties/1.1.3: + resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==} + engines: {node: '>= 0.4'} + dependencies: + object-keys: 1.1.1 + dev: true + + /delayed-stream/1.0.0: + resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} + engines: {node: '>=0.4.0'} + dev: true + + /detect-newline/3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + + /diff-sequences/27.4.0: + resolution: {integrity: sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dev: true + + /dir-glob/3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /doctrine/2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine/3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /domexception/2.0.1: + resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} + engines: {node: '>=8'} + dependencies: + webidl-conversions: 5.0.0 + dev: true + + /electron-to-chromium/1.4.35: + resolution: {integrity: sha512-wzTOMh6HGFWeALMI3bif0mzgRrVGyP1BdFRx7IvWukFrSC5QVQELENuy+Fm2dCrAdQH9T3nuqr07n94nPDFBWA==} + dev: true + + /emittery/0.8.1: + resolution: {integrity: sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==} + engines: {node: '>=10'} + dev: true + + /emoji-regex/8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /emoji-regex/9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + + /enquirer/2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.1 + dev: true + + /error-ex/1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract/1.19.1: + resolution: {integrity: sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + es-to-primitive: 1.2.1 + function-bind: 1.1.1 + get-intrinsic: 1.1.1 + get-symbol-description: 1.0.0 + has: 1.0.3 + has-symbols: 1.0.2 + internal-slot: 1.0.3 + is-callable: 1.2.4 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.1 + is-string: 1.0.7 + is-weakref: 1.0.2 + object-inspect: 1.12.0 + 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 + dev: true + + /es-jest/1.5.0: + resolution: {integrity: sha512-LC6IKr3IqmdYeFCnmi53vktU4GB0CAWFQ2HPi8hoab5jvtaBy62P7mFNnARw5Es3hgF99qiB0c/0N0eBsk8Cww==} + engines: {node: '>=10'} + dependencies: + esbuild: 0.14.8 + dev: true + + /es-to-primitive/1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.4 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /esbuild-android-arm64/0.13.15: + resolution: {integrity: sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg==} + cpu: [arm64] + os: [android] + dev: true + optional: true + + /esbuild-android-arm64/0.14.10: + resolution: {integrity: sha512-vzkTafHKoiMX4uIN1kBnE/HXYLpNT95EgGanVk6DHGeYgDolU0NBxjO7yZpq4ZGFPOx8384eAdDrBYhO11TAlQ==} + cpu: [arm64] + os: [android] + dev: true + optional: true + + /esbuild-android-arm64/0.14.8: + resolution: {integrity: sha512-tAEoSHnPBSH0cCAFa/aYs3LPsoTY4SwsP6wDKi4PaelbQYNJjqNpAeweyJ8l98g1D6ZkLyqsHbkYj+209sezkA==} + cpu: [arm64] + os: [android] + dev: true + optional: true + + /esbuild-darwin-64/0.13.15: + resolution: {integrity: sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==} + cpu: [x64] + os: [darwin] + dev: true + optional: true + + /esbuild-darwin-64/0.14.10: + resolution: {integrity: sha512-DJwzFVB95ZV7C3PQbf052WqaUuuMFXJeZJ0LKdnP1w+QOU0rlbKfX0tzuhoS//rOXUj1TFIwRuRsd0FX6skR7A==} + cpu: [x64] + os: [darwin] + dev: true + optional: true + + /esbuild-darwin-64/0.14.8: + resolution: {integrity: sha512-t7p7WzTb+ybiD/irkMt5j/NzB+jY+8yPTsrXk5zCOH1O7DdthRnAUJ7pJPwImdL7jAGRbLtYRxUPgCHs/0qUPw==} + cpu: [x64] + os: [darwin] + dev: true + optional: true + + /esbuild-darwin-arm64/0.13.15: + resolution: {integrity: sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==} + cpu: [arm64] + os: [darwin] + dev: true + optional: true + + /esbuild-darwin-arm64/0.14.10: + resolution: {integrity: sha512-RNaaoZDg3nsqs5z56vYCjk/VJ76npf752W0rOaCl5lO5TsgV9zecfdYgt7dtUrIx8b7APhVaNYud+tGsDOVC9g==} + cpu: [arm64] + os: [darwin] + dev: true + optional: true + + /esbuild-darwin-arm64/0.14.8: + resolution: {integrity: sha512-5FeaT2zMUajKnBwUMSsjZev5iA38YHrDmXhkOCwZQIFUvhqojinqCrvv/X7dyxb1987bcY9KGwJ+EwDwd922HQ==} + cpu: [arm64] + os: [darwin] + dev: true + optional: true + + /esbuild-freebsd-64/0.13.15: + resolution: {integrity: sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==} + cpu: [x64] + os: [freebsd] + dev: true + optional: true + + /esbuild-freebsd-64/0.14.10: + resolution: {integrity: sha512-10B3AzW894u6bGZZhWiJOHw1uEHb4AFbUuBdyml1Ht0vIqd+KqWW+iY/yMwQAzILr2WJZqEhbOXRkJtY8aRqOw==} + cpu: [x64] + os: [freebsd] + dev: true + optional: true + + /esbuild-freebsd-64/0.14.8: + resolution: {integrity: sha512-pGHBLSf7ynfyDZXUtbq/GsA2VIwQlWXrUj1AMcE0id47mRdEUM8/1ZuqMGZx63hRnNgtK9zNJ8OIu2c7qq76Qw==} + cpu: [x64] + os: [freebsd] + dev: true + optional: true + + /esbuild-freebsd-arm64/0.13.15: + resolution: {integrity: sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==} + cpu: [arm64] + os: [freebsd] + dev: true + optional: true + + /esbuild-freebsd-arm64/0.14.10: + resolution: {integrity: sha512-mSQrKB7UaWvuryBTCo9leOfY2uEUSimAvcKIaUWbk5Hth9Sg+Try+qNA/NibPgs/vHkX0KFo/Rce6RPea+P15g==} + cpu: [arm64] + os: [freebsd] + dev: true + optional: true + + /esbuild-freebsd-arm64/0.14.8: + resolution: {integrity: sha512-g4GgAnrx6Gh1BjKJjJWgPnOR4tW2FcAx9wFvyUjRsIjB35gT+aAFR+P/zStu5OG9LnbS8Pvjd4wS68QIXk+2dA==} + cpu: [arm64] + os: [freebsd] + dev: true + optional: true + + /esbuild-linux-32/0.13.15: + resolution: {integrity: sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==} + cpu: [ia32] + os: [linux] + dev: true + optional: true + + /esbuild-linux-32/0.14.10: + resolution: {integrity: sha512-lktF09JgJLZ63ANYHIPdYe339PDuVn19Q/FcGKkXWf+jSPkn5xkYzAabboNGZNUgNqSJ/vY7VrOn6UrBbJjgYA==} + cpu: [ia32] + os: [linux] + dev: true + optional: true + + /esbuild-linux-32/0.14.8: + resolution: {integrity: sha512-wPfQJadF5vTzriw/B8Ide74PeAJlZW7czNx3NIUHkHlXb+En1SeIqNzl6jG9DuJUl57xD9Ucl9YJFEkFeX8eLg==} + cpu: [ia32] + os: [linux] + dev: true + optional: true + + /esbuild-linux-64/0.13.15: + resolution: {integrity: sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==} + cpu: [x64] + os: [linux] + dev: true + optional: true + + /esbuild-linux-64/0.14.10: + resolution: {integrity: sha512-K+gCQz2oLIIBI8ZM77e9sYD5/DwEpeYCrOQ2SYXx+R4OU2CT9QjJDi4/OpE7ko4AcYMlMW7qrOCuLSgAlEj4Wg==} + cpu: [x64] + os: [linux] + dev: true + optional: true + + /esbuild-linux-64/0.14.8: + resolution: {integrity: sha512-+RNuLk9RhRDL2kG+KTEYl5cIgF6AGLkRnKKWEu9DpCZaickONEqrKyQSVn410Hj105DLdW6qvIXQQHPycJhExg==} + cpu: [x64] + os: [linux] + dev: true + optional: true + + /esbuild-linux-arm/0.13.15: + resolution: {integrity: sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==} + cpu: [arm] + os: [linux] + dev: true + optional: true + + /esbuild-linux-arm/0.14.10: + resolution: {integrity: sha512-BYa60dZ/KPmNKYxtHa3LSEdfKWHcm/RzP0MjB4AeBPhjS0D6/okhaBesZIY9kVIGDyeenKsJNOmnVt4+dhNnvQ==} + cpu: [arm] + os: [linux] + dev: true + optional: true + + /esbuild-linux-arm/0.14.8: + resolution: {integrity: sha512-HIct38SvUAIJbiTwV/PVQroimQo96TGtzRDAEZxTorB4vsAj1r8bd0keXExPU4RH7G0zIqC4loQQpWYL+nH4Vg==} + cpu: [arm] + os: [linux] + dev: true + optional: true + + /esbuild-linux-arm64/0.13.15: + resolution: {integrity: sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==} + cpu: [arm64] + os: [linux] + dev: true + optional: true + + /esbuild-linux-arm64/0.14.10: + resolution: {integrity: sha512-+qocQuQvcp5wo/V+OLXxqHPc+gxHttJEvbU/xrCGE03vIMqraL4wMua8JQx0SWEnJCWP+Nhf//v8OSwz1Xr5kA==} + cpu: [arm64] + os: [linux] + dev: true + optional: true + + /esbuild-linux-arm64/0.14.8: + resolution: {integrity: sha512-BtWoKNYul9UoxUvQUSdSrvSmJyFL1sGnNPTSqWCg1wMe4kmc8UY2yVsXSSkKO8N2jtHxlgFyz/XhvNBzEwGVcw==} + cpu: [arm64] + os: [linux] + dev: true + optional: true + + /esbuild-linux-mips64le/0.13.15: + resolution: {integrity: sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==} + cpu: [mips64el] + os: [linux] + dev: true + optional: true + + /esbuild-linux-mips64le/0.14.10: + resolution: {integrity: sha512-nmUd2xoBXpGo4NJCEWoaBj+n4EtDoLEvEYc8Z3aSJrY0Oa6s04czD1flmhd0I/d6QEU8b7GQ9U0g/rtBfhtxBg==} + cpu: [mips64el] + os: [linux] + dev: true + optional: true + + /esbuild-linux-mips64le/0.14.8: + resolution: {integrity: sha512-0DxnCl9XTvaQtsX6Qa+Phr5i9b04INwwSv2RbQ2UWRLoQ/037iaFzbmuhgrcmaGOcRwPkCa+4Qo5EgI01MUgsQ==} + cpu: [mips64el] + os: [linux] + dev: true + optional: true + + /esbuild-linux-ppc64le/0.13.15: + resolution: {integrity: sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==} + cpu: [ppc64] + os: [linux] + dev: true + optional: true + + /esbuild-linux-ppc64le/0.14.10: + resolution: {integrity: sha512-vsOWZjm0rZix7HSmqwPph9arRVCyPtUpcURdayQDuIhMG2/UxJxpbdRaa//w4zYqcJzAWwuyH2PAlyy0ZNuxqQ==} + cpu: [ppc64] + os: [linux] + dev: true + optional: true + + /esbuild-linux-ppc64le/0.14.8: + resolution: {integrity: sha512-Uzr/OMj97Q0qoWLXCvXCKUY/z1SNI4iSZEuYylM5Nd71HGStL32XWq/MReJ0PYMvUMKKJicKSKw2jWM1uBQ84Q==} + cpu: [ppc64] + os: [linux] + dev: true + optional: true + + /esbuild-linux-s390x/0.14.10: + resolution: {integrity: sha512-knArKKZm0ypIYWOWyOT7+accVwbVV1LZnl2FWWy05u9Tyv5oqJ2F5+X2Vqe/gqd61enJXQWqoufXopvG3zULOg==} + cpu: [s390x] + os: [linux] + dev: true + optional: true + + /esbuild-linux-s390x/0.14.8: + resolution: {integrity: sha512-vURka7aCA5DrRoOqOn6pXYwFlDSoQ4qnqam8AC0Ikn6tibutuhgar6M3Ek2DCuz9yqd396mngdYr5A8x2TPkww==} + cpu: [s390x] + os: [linux] + dev: true + optional: true + + /esbuild-netbsd-64/0.13.15: + resolution: {integrity: sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==} + cpu: [x64] + os: [netbsd] + dev: true + optional: true + + /esbuild-netbsd-64/0.14.10: + resolution: {integrity: sha512-6Gg8neVcLeyq0yt9bZpReb8ntZ8LBEjthxrcYWVrBElcltnDjIy1hrzsujt0+sC2rL+TlSsE9dzgyuvlDdPp2w==} + cpu: [x64] + os: [netbsd] + dev: true + optional: true + + /esbuild-netbsd-64/0.14.8: + resolution: {integrity: sha512-tjyDak2/pp0VUAhBW6/ueuReMd5qLHNlisXl5pq0Xn0z+kH9urA/t1igm0JassWbdMz123td5ZEQWoD9KbtOAw==} + cpu: [x64] + os: [netbsd] + dev: true + optional: true + + /esbuild-node-loader/0.6.3_typescript@4.5.4: + resolution: {integrity: sha512-Bf6o8SiMMh5+r20jsjAThNOtzo3t8Ye4Qdzz+twWHnxu28SdkGUr5ahq8iX0qbd+I9ge8sLNX7oQoNW1YzHlqA==} + peerDependencies: + typescript: ^4.0 + dependencies: + esbuild: 0.13.15 + typescript: 4.5.4 + dev: true + + /esbuild-openbsd-64/0.13.15: + resolution: {integrity: sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==} + cpu: [x64] + os: [openbsd] + dev: true + optional: true + + /esbuild-openbsd-64/0.14.10: + resolution: {integrity: sha512-9rkHZzp10zI90CfKbFrwmQjqZaeDmyQ6s9/hvCwRkbOCHuto6RvMYH9ghQpcr5cUxD5OQIA+sHXi0zokRNXjcg==} + cpu: [x64] + os: [openbsd] + dev: true + optional: true + + /esbuild-openbsd-64/0.14.8: + resolution: {integrity: sha512-zAKKV15fIyAuDDga5rQv0lW2ufBWj/OCjqjDBb3dJf5SfoAi/DMIHuzmkKQeDQ+oxt9Rp1D7ZOlOBVflutFTqQ==} + cpu: [x64] + os: [openbsd] + dev: true + optional: true + + /esbuild-register/3.3.0_esbuild@0.14.8: + resolution: {integrity: sha512-X4irLPLJwwuy8WSI9KsG2htKOoQBveVbmjYGBeBNnha+9IL56wffjj4VeU5zDb3PQtWaE7cdAML87L3rZUYhZw==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + esbuild: 0.14.8 + jsonc-parser: 3.0.0 + tsconfig-paths: 3.12.0 + dev: true + + /esbuild-sunos-64/0.13.15: + resolution: {integrity: sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==} + cpu: [x64] + os: [sunos] + dev: true + optional: true + + /esbuild-sunos-64/0.14.10: + resolution: {integrity: sha512-mEU+pqkhkhbwpJj5DiN3vL0GUFR/yrL3qj8ER1amIVyRibKbj02VM1QaIuk1sy5DRVIKiFXXgCaHvH3RNWCHIw==} + cpu: [x64] + os: [sunos] + dev: true + optional: true + + /esbuild-sunos-64/0.14.8: + resolution: {integrity: sha512-xV41Wa8imziM/2dbWZjLKQbIETRgo5dE0oc/uPsgaecJhsrdA0VkGa/V432LJSUYv967xHDQdoRRl5tr80+NnQ==} + cpu: [x64] + os: [sunos] + dev: true + optional: true + + /esbuild-windows-32/0.13.15: + resolution: {integrity: sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==} + cpu: [ia32] + os: [win32] + dev: true + optional: true + + /esbuild-windows-32/0.14.10: + resolution: {integrity: sha512-Z5DieUL1N6s78dOSdL95KWf8Y89RtPGxIoMF+LEy8ChDsX+pZpz6uAVCn+YaWpqQXO+2TnrcbgBIoprq2Mco1g==} + cpu: [ia32] + os: [win32] + dev: true + optional: true + + /esbuild-windows-32/0.14.8: + resolution: {integrity: sha512-AxpdeLKQSyCZo7MzdOyV4OgEbEJcjnrS/2niAjbHESbjuS5P1DN/5vZoJ/JSWDVa/40OkBuHBhAXMx1HK3UDsg==} + cpu: [ia32] + os: [win32] + dev: true + optional: true + + /esbuild-windows-64/0.13.15: + resolution: {integrity: sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==} + cpu: [x64] + os: [win32] + dev: true + optional: true + + /esbuild-windows-64/0.14.10: + resolution: {integrity: sha512-LE5Mm62y0Bilu7RDryBhHIX8rK3at5VwJ6IGM3BsASidCfOBTzqcs7Yy0/Vkq39VKeTmy9/66BAfVoZRNznoDw==} + cpu: [x64] + os: [win32] + dev: true + optional: true + + /esbuild-windows-64/0.14.8: + resolution: {integrity: sha512-/3pllNoy8mrz/E1rYalwiwwhzJBrYQhEapwAteHZbFVhGzYuB8F80e8x5eA8dhFHxDiZh1VzK+hREwwSt8UTQA==} + cpu: [x64] + os: [win32] + dev: true + optional: true + + /esbuild-windows-arm64/0.13.15: + resolution: {integrity: sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==} + cpu: [arm64] + os: [win32] + dev: true + optional: true + + /esbuild-windows-arm64/0.14.10: + resolution: {integrity: sha512-OJOyxDtabvcUYTc+O4dR0JMzLBz6G9+gXIHA7Oc5d5Fv1xiYa0nUeo8+W5s2e6ZkPRdIwOseYoL70rZz80S5BA==} + cpu: [arm64] + os: [win32] + dev: true + optional: true + + /esbuild-windows-arm64/0.14.8: + resolution: {integrity: sha512-lTm5naoNgaUvzIiax3XYIEebqwr3bIIEEtqUhzQ2UQ+JMBmvhr02w3sJIJqF3axTX6TgWrC1OtM7DYNvFG+aXA==} + cpu: [arm64] + os: [win32] + dev: true + optional: true + + /esbuild/0.13.15: + resolution: {integrity: sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-arm64: 0.13.15 + esbuild-darwin-64: 0.13.15 + esbuild-darwin-arm64: 0.13.15 + esbuild-freebsd-64: 0.13.15 + esbuild-freebsd-arm64: 0.13.15 + esbuild-linux-32: 0.13.15 + esbuild-linux-64: 0.13.15 + esbuild-linux-arm: 0.13.15 + esbuild-linux-arm64: 0.13.15 + esbuild-linux-mips64le: 0.13.15 + esbuild-linux-ppc64le: 0.13.15 + esbuild-netbsd-64: 0.13.15 + esbuild-openbsd-64: 0.13.15 + esbuild-sunos-64: 0.13.15 + esbuild-windows-32: 0.13.15 + esbuild-windows-64: 0.13.15 + esbuild-windows-arm64: 0.13.15 + dev: true + + /esbuild/0.14.10: + resolution: {integrity: sha512-ibZb+NwFqBwHHJlpnFMtg4aNmVK+LUtYMFC9CuKs6lDCBEvCHpqCFZFEirpqt1jOugwKGx8gALNGvX56lQyfew==} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-arm64: 0.14.10 + esbuild-darwin-64: 0.14.10 + esbuild-darwin-arm64: 0.14.10 + esbuild-freebsd-64: 0.14.10 + esbuild-freebsd-arm64: 0.14.10 + esbuild-linux-32: 0.14.10 + esbuild-linux-64: 0.14.10 + esbuild-linux-arm: 0.14.10 + esbuild-linux-arm64: 0.14.10 + esbuild-linux-mips64le: 0.14.10 + esbuild-linux-ppc64le: 0.14.10 + esbuild-linux-s390x: 0.14.10 + esbuild-netbsd-64: 0.14.10 + esbuild-openbsd-64: 0.14.10 + esbuild-sunos-64: 0.14.10 + esbuild-windows-32: 0.14.10 + esbuild-windows-64: 0.14.10 + esbuild-windows-arm64: 0.14.10 + dev: true + + /esbuild/0.14.8: + resolution: {integrity: sha512-stMsCBmxwaMpeK8GC/49L/cRGIwsHwoEN7Twk5zDTHlm/63c0KXFKzDC8iM2Mi3fyCKwS002TAH6IlAvqR6t3g==} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-arm64: 0.14.8 + esbuild-darwin-64: 0.14.8 + esbuild-darwin-arm64: 0.14.8 + esbuild-freebsd-64: 0.14.8 + esbuild-freebsd-arm64: 0.14.8 + esbuild-linux-32: 0.14.8 + esbuild-linux-64: 0.14.8 + esbuild-linux-arm: 0.14.8 + esbuild-linux-arm64: 0.14.8 + esbuild-linux-mips64le: 0.14.8 + esbuild-linux-ppc64le: 0.14.8 + esbuild-linux-s390x: 0.14.8 + esbuild-netbsd-64: 0.14.8 + esbuild-openbsd-64: 0.14.8 + esbuild-sunos-64: 0.14.8 + esbuild-windows-32: 0.14.8 + esbuild-windows-64: 0.14.8 + esbuild-windows-arm64: 0.14.8 + dev: true + + /escalade/3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-string-regexp/1.0.5: + resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp/2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /escape-string-regexp/4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /escodegen/2.0.0: + resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /eslint-import-resolver-node/0.3.6: + resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} + dependencies: + debug: 3.2.7 + resolve: 1.21.0 + dev: true + + /eslint-import-resolver-typescript/2.5.0_b5a36b8c1535387c8dd00eff7ec6b551: + resolution: {integrity: sha512-qZ6e5CFr+I7K4VVhQu3M/9xGv9/YmwsEXrsm3nimw8vWaVHRDrQRp26BgCypTxBp3vUp4o5aVEJRiy0F2DFddQ==} + engines: {node: '>=4'} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + dependencies: + debug: 4.3.3 + eslint: 8.6.0 + eslint-plugin-import: 2.25.4_eslint@8.6.0 + glob: 7.2.0 + is-glob: 4.0.3 + resolve: 1.21.0 + tsconfig-paths: 3.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils/2.7.2: + resolution: {integrity: sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg==} + engines: {node: '>=4'} + dependencies: + debug: 3.2.7 + find-up: 2.1.0 + dev: true + + /eslint-plugin-es/3.0.1_eslint@8.6.0: + resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + eslint: 8.6.0 + eslint-utils: 2.1.0 + regexpp: 3.2.0 + dev: true + + /eslint-plugin-eslint-comments/3.2.0_eslint@8.6.0: + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + escape-string-regexp: 1.0.5 + eslint: 8.6.0 + ignore: 5.2.0 + dev: true + + /eslint-plugin-import/2.25.4_eslint@8.6.0: + resolution: {integrity: sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + dependencies: + array-includes: 3.1.4 + array.prototype.flat: 1.2.5 + debug: 2.6.9 + doctrine: 2.1.0 + eslint: 8.6.0 + eslint-import-resolver-node: 0.3.6 + eslint-module-utils: 2.7.2 + has: 1.0.3 + is-core-module: 2.8.0 + is-glob: 4.0.3 + minimatch: 3.0.4 + object.values: 1.1.5 + resolve: 1.21.0 + tsconfig-paths: 3.12.0 + dev: true + + /eslint-plugin-jsonc/2.0.0_eslint@8.6.0: + resolution: {integrity: sha512-5UbUUvx4gUVeF9hJ+SHDW9a4OPQ8vJWu12rttQ76qGO2tlH17OC103CLq+vrmjo5VQULeVzSJ0u4s+jUATJyWQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + eslint: 8.6.0 + eslint-utils: 3.0.0_eslint@8.6.0 + jsonc-eslint-parser: 2.0.4_eslint@8.6.0 + natural-compare: 1.4.0 + dev: true + + /eslint-plugin-markdown/2.2.1_eslint@8.6.0: + resolution: {integrity: sha512-FgWp4iyYvTFxPwfbxofTvXxgzPsDuSKHQy2S+a8Ve6savbujey+lgrFFbXQA0HPygISpRYWYBjooPzhYSF81iA==} + engines: {node: ^8.10.0 || ^10.12.0 || >= 12.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + eslint: 8.6.0 + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-no-use-extend-native/0.5.0: + resolution: {integrity: sha512-dBNjs8hor8rJgeXLH4HTut5eD3RGWf9JUsadIfuL7UosVQ/dnvOKwxEcRrXrFxrMZ8llUVWT+hOimxJABsAUzQ==} + engines: {node: '>=6.0.0'} + dependencies: + is-get-set-prop: 1.0.0 + is-js-type: 2.0.0 + is-obj-prop: 1.0.0 + is-proto-prop: 2.0.0 + dev: true + + /eslint-plugin-node/11.1.0_eslint@8.6.0: + resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=5.16.0' + dependencies: + eslint: 8.6.0 + eslint-plugin-es: 3.0.1_eslint@8.6.0 + eslint-utils: 2.1.0 + ignore: 5.2.0 + minimatch: 3.0.4 + resolve: 1.21.0 + semver: 6.3.0 + dev: true + + /eslint-plugin-promise/6.0.0_eslint@8.6.0: + resolution: {integrity: sha512-7GPezalm5Bfi/E22PnQxDWH2iW9GTvAlUNTztemeHb6c1BniSyoeTrM87JkC0wYdi6aQrZX9p2qEiAno8aTcbw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.6.0 + dev: true + + /eslint-plugin-react-hooks/4.3.0_eslint@8.6.0: + resolution: {integrity: sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + dependencies: + eslint: 8.6.0 + dev: true + + /eslint-plugin-react/7.28.0_eslint@8.6.0: + resolution: {integrity: sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + dependencies: + array-includes: 3.1.4 + array.prototype.flatmap: 1.2.5 + doctrine: 2.1.0 + eslint: 8.6.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.2.1 + minimatch: 3.0.4 + object.entries: 1.1.5 + object.fromentries: 2.0.5 + object.hasown: 1.1.0 + object.values: 1.1.5 + prop-types: 15.8.1 + resolve: 2.0.0-next.3 + semver: 6.3.0 + string.prototype.matchall: 4.0.6 + dev: true + + /eslint-plugin-regexp/1.5.1_eslint@8.6.0: + resolution: {integrity: sha512-5v0rQIi54m2KycQHqmOAHrZhvI56GHmI2acr6zEffAqfeifTtobAEapv9Uf4o8//lGvwVkHKyjLoSbBNEFcfOA==} + engines: {node: ^12 || >=14} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + comment-parser: 1.3.0 + eslint: 8.6.0 + eslint-utils: 3.0.0_eslint@8.6.0 + grapheme-splitter: 1.0.4 + jsdoctypeparser: 9.0.0 + refa: 0.9.1 + regexp-ast-analysis: 0.3.0 + regexpp: 3.2.0 + scslre: 0.1.6 + dev: true + + /eslint-plugin-unicorn/39.0.0_eslint@8.6.0: + resolution: {integrity: sha512-fd5RK2FtYjGcIx3wra7csIE/wkkmBo22T1gZtRTsLr1Mb+KsFKJ+JOdSqhHXQUrI/JTs/Mon64cEYzTgSCbltw==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=7.32.0' + dependencies: + '@babel/helper-validator-identifier': 7.16.7 + ci-info: 3.3.0 + clean-regexp: 1.0.0 + eslint: 8.6.0 + eslint-template-visitor: 2.3.2_eslint@8.6.0 + eslint-utils: 3.0.0_eslint@8.6.0 + esquery: 1.4.0 + indent-string: 4.0.0 + is-builtin-module: 3.1.0 + lodash: 4.17.21 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.24 + safe-regex: 2.1.1 + semver: 7.3.5 + strip-indent: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-vue/8.2.0_eslint@8.6.0: + resolution: {integrity: sha512-cLIdTuOAMXyHeQ4drYKcZfoyzdwdBpH279X8/N0DgmotEI9yFKb5O/cAgoie/CkQZCH/MOmh0xw/KEfS90zY2A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.6.0 + eslint-utils: 3.0.0_eslint@8.6.0 + natural-compare: 1.4.0 + semver: 7.3.5 + vue-eslint-parser: 8.0.1_eslint@8.6.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-scope/5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-scope/6.0.0: + resolution: {integrity: sha512-uRDL9MWmQCkaFus8RF5K9/L/2fn+80yoW3jkD53l4shjCh26fCtvJGasxjUqP5OT87SYTxCVA3BwTUzuELx9kA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-scope/7.1.0: + resolution: {integrity: sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-template-visitor/2.3.2_eslint@8.6.0: + resolution: {integrity: sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + '@babel/core': 7.16.7 + '@babel/eslint-parser': 7.16.5_@babel+core@7.16.7+eslint@8.6.0 + eslint: 8.6.0 + eslint-visitor-keys: 2.1.0 + esquery: 1.4.0 + multimap: 1.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-utils/2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + dependencies: + eslint-visitor-keys: 1.3.0 + dev: true + + /eslint-utils/3.0.0_eslint@8.6.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.6.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /eslint-visitor-keys/1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + dev: true + + /eslint-visitor-keys/2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint-visitor-keys/3.1.0: + resolution: {integrity: sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint/8.6.0: + resolution: {integrity: sha512-UvxdOJ7mXFlw7iuHZA4jmzPaUqIw54mZrv+XPYKNbKdLR0et4rf60lIZUU9kiNtnzzMzGWxMV+tQ7uG7JG8DPw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint/eslintrc': 1.0.5 + '@humanwhocodes/config-array': 0.9.2 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.3 + doctrine: 3.0.0 + enquirer: 2.3.6 + escape-string-regexp: 4.0.0 + eslint-scope: 7.1.0 + eslint-utils: 3.0.0_eslint@8.6.0 + eslint-visitor-keys: 3.1.0 + espree: 9.3.0 + esquery: 1.4.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 6.0.2 + globals: 13.12.0 + ignore: 4.0.6 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 4.1.0 + 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.3 + regexpp: 3.2.0 + semver: 7.3.5 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + v8-compile-cache: 2.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /esno/0.13.0_typescript@4.5.4: + resolution: {integrity: sha512-rgVOc/t+4QgAHTsQiFKX2olzJLIcBOYGYUb/moEDLXcz0pIf8NxwuFu5nOAMmOsNiFfhSrfgcLgVCOtmBIBeuQ==} + hasBin: true + dependencies: + cross-spawn: 7.0.3 + esbuild: 0.14.8 + esbuild-node-loader: 0.6.3_typescript@4.5.4 + esbuild-register: 3.3.0_esbuild@0.14.8 + import-meta-resolve: 1.1.1 + transitivePeerDependencies: + - typescript + dev: true + + /espree/9.3.0: + resolution: {integrity: sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.7.0 + acorn-jsx: 5.3.2_acorn@8.7.0 + eslint-visitor-keys: 3.1.0 + dev: true + + /esprima/4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esquery/1.4.0: + resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse/4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse/4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse/5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /esutils/2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /execa/5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.6 + strip-final-newline: 2.0.0 + dev: true + + /exit/0.1.2: + resolution: {integrity: sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=} + engines: {node: '>= 0.8.0'} + dev: true + + /expect/27.4.6: + resolution: {integrity: sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + jest-get-type: 27.4.0 + jest-matcher-utils: 27.4.6 + jest-message-util: 27.4.6 + dev: true + + /fast-deep-equal/3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob/3.2.7: + resolution: {integrity: sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==} + engines: {node: '>=8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.4 + dev: true + + /fast-json-stable-stringify/2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein/2.0.6: + resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} + dev: true + + /fastq/1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + dependencies: + reusify: 1.0.4 + dev: true + + /fb-watchman/2.0.1: + resolution: {integrity: sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==} + dependencies: + bser: 2.1.1 + dev: true + + /file-entry-cache/6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + dev: true + + /fill-range/7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /find-up/2.1.0: + resolution: {integrity: sha1-RdG35QbHF93UgndaK3eSCjwMV6c=} + engines: {node: '>=4'} + dependencies: + locate-path: 2.0.0 + dev: true + + /find-up/4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up/5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /find-versions/4.0.0: + resolution: {integrity: sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==} + engines: {node: '>=10'} + dependencies: + semver-regex: 3.1.3 + dev: true + + /flat-cache/3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.4 + rimraf: 3.0.2 + dev: true + + /flatted/3.2.4: + resolution: {integrity: sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==} + dev: true + + /form-data/3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.34 + dev: true + + /fs.realpath/1.0.0: + resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} + dev: true + + /fsevents/2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /functional-red-black-tree/1.0.1: + resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} + dev: true + + /gensync/1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-caller-file/2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-intrinsic/1.1.1: + resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.2 + dev: true + + /get-package-type/0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-set-props/0.1.0: + resolution: {integrity: sha1-mYR1wXhEVobQsyJG2l3428++jqM=} + engines: {node: '>=0.10.0'} + dev: true + + /get-stream/6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-symbol-description/1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.1 + dev: true + + /glob-parent/5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent/6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob/7.1.6: + resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.0.4 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob/7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.0.4 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals/11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals/13.12.0: + resolution: {integrity: sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globby/11.0.4: + resolution: {integrity: sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.2.7 + ignore: 5.2.0 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /graceful-fs/4.2.9: + resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==} + dev: true + + /grapheme-splitter/1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + + /has-bigints/1.0.1: + resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==} + dev: true + + /has-flag/3.0.0: + resolution: {integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=} + engines: {node: '>=4'} + dev: true + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-symbols/1.0.2: + resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag/1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.2 + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /hosted-git-info/2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /html-encoding-sniffer/2.0.1: + resolution: {integrity: sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==} + engines: {node: '>=10'} + dependencies: + whatwg-encoding: 1.0.5 + dev: true + + /html-escaper/2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /http-proxy-agent/4.0.1: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /https-proxy-agent/5.0.0: + resolution: {integrity: sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.3 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals/2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /husky/4.3.8: + resolution: {integrity: sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==} + engines: {node: '>=10'} + hasBin: true + requiresBuild: true + dependencies: + chalk: 4.1.2 + ci-info: 2.0.0 + compare-versions: 3.6.0 + cosmiconfig: 7.0.1 + find-versions: 4.0.0 + opencollective-postinstall: 2.0.3 + pkg-dir: 5.0.0 + please-upgrade-node: 3.2.0 + slash: 3.0.0 + which-pm-runs: 1.0.0 + dev: true + + /iconv-lite/0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /ignore/4.0.6: + resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} + engines: {node: '>= 4'} + dev: true + + /ignore/5.2.0: + resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} + engines: {node: '>= 4'} + dev: true + + /import-fresh/3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /import-local/3.0.3: + resolution: {integrity: sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + + /import-meta-resolve/1.1.1: + resolution: {integrity: sha512-JiTuIvVyPaUg11eTrNDx5bgQ/yMKMZffc7YSjvQeSMXy58DO2SQ8BtAf3xteZvmzvjYh14wnqNjL8XVeDy2o9A==} + dependencies: + builtins: 4.0.0 + dev: true + + /imurmurhash/0.1.4: + resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string/4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /internal-slot/1.0.3: + resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.1.1 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /is-alphabetical/1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + dev: true + + /is-alphanumerical/1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + dev: true + + /is-arrayish/0.2.1: + resolution: {integrity: sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=} + dev: true + + /is-bigint/1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.1 + dev: true + + /is-binary-path/2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-boolean-object/1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-builtin-module/3.1.0: + resolution: {integrity: sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.2.0 + dev: true + + /is-callable/1.2.4: + resolution: {integrity: sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module/2.8.0: + resolution: {integrity: sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==} + dependencies: + has: 1.0.3 + dev: true + + /is-date-object/1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-decimal/1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + dev: true + + /is-extglob/2.1.1: + resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point/3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-fullwidth-code-point/4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + + /is-generator-fn/2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + + /is-get-set-prop/1.0.0: + resolution: {integrity: sha1-JzGHfk14pqae3M5rudaLB3nnYxI=} + dependencies: + get-set-props: 0.1.0 + lowercase-keys: 1.0.1 + dev: true + + /is-glob/4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-hexadecimal/1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + dev: true + + /is-js-type/2.0.0: + resolution: {integrity: sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=} + dependencies: + js-types: 1.0.0 + dev: true + + /is-negative-zero/2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object/1.0.6: + resolution: {integrity: sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number/7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-obj-prop/1.0.0: + resolution: {integrity: sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=} + dependencies: + lowercase-keys: 1.0.1 + obj-props: 1.3.0 + dev: true + + /is-potential-custom-element-name/1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + dev: true + + /is-proto-prop/2.0.0: + resolution: {integrity: sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==} + dependencies: + lowercase-keys: 1.0.1 + proto-props: 2.0.0 + dev: true + + /is-regex/1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-shared-array-buffer/1.0.1: + resolution: {integrity: sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==} + dev: true + + /is-stream/2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-string/1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol/1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.2 + dev: true + + /is-typedarray/1.0.0: + resolution: {integrity: sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=} + dev: true + + /is-weakref/1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /isexe/2.0.0: + resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} + dev: true + + /istanbul-lib-coverage/3.2.0: + resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-instrument/5.1.0: + resolution: {integrity: sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.16.7 + '@babel/parser': 7.16.7 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-report/3.0.0: + resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} + engines: {node: '>=8'} + dependencies: + istanbul-lib-coverage: 3.2.0 + make-dir: 3.1.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps/4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.3 + istanbul-lib-coverage: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports/3.1.3: + resolution: {integrity: sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.0 + dev: true + + /jest-changed-files/27.4.2: + resolution: {integrity: sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + execa: 5.1.1 + throat: 6.0.1 + dev: true + + /jest-circus/27.4.6: + resolution: {integrity: sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.4.6 + '@jest/test-result': 27.4.6 + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + expect: 27.4.6 + is-generator-fn: 2.1.0 + jest-each: 27.4.6 + jest-matcher-utils: 27.4.6 + jest-message-util: 27.4.6 + jest-runtime: 27.4.6 + jest-snapshot: 27.4.6 + jest-util: 27.4.2 + pretty-format: 27.4.6 + slash: 3.0.0 + stack-utils: 2.0.5 + throat: 6.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-cli/27.4.7: + resolution: {integrity: sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 27.4.7 + '@jest/test-result': 27.4.6 + '@jest/types': 27.4.2 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.9 + import-local: 3.0.3 + jest-config: 27.4.7 + jest-util: 27.4.2 + jest-validate: 27.4.6 + prompts: 2.4.2 + yargs: 16.2.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /jest-config/27.4.7: + resolution: {integrity: sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + ts-node: '>=9.0.0' + peerDependenciesMeta: + ts-node: + optional: true + dependencies: + '@babel/core': 7.16.7 + '@jest/test-sequencer': 27.4.6 + '@jest/types': 27.4.2 + babel-jest: 27.4.6_@babel+core@7.16.7 + chalk: 4.1.2 + ci-info: 3.3.0 + deepmerge: 4.2.2 + glob: 7.2.0 + graceful-fs: 4.2.9 + jest-circus: 27.4.6 + jest-environment-jsdom: 27.4.6 + jest-environment-node: 27.4.6 + jest-get-type: 27.4.0 + jest-jasmine2: 27.4.6 + jest-regex-util: 27.4.0 + jest-resolve: 27.4.6 + jest-runner: 27.4.6 + jest-util: 27.4.2 + jest-validate: 27.4.6 + micromatch: 4.0.4 + pretty-format: 27.4.6 + slash: 3.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-diff/27.4.6: + resolution: {integrity: sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 27.4.0 + jest-get-type: 27.4.0 + pretty-format: 27.4.6 + dev: true + + /jest-docblock/27.4.0: + resolution: {integrity: sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each/27.4.6: + resolution: {integrity: sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + chalk: 4.1.2 + jest-get-type: 27.4.0 + jest-util: 27.4.2 + pretty-format: 27.4.6 + dev: true + + /jest-environment-jsdom/27.4.6: + resolution: {integrity: sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.4.6 + '@jest/fake-timers': 27.4.6 + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + jest-mock: 27.4.6 + jest-util: 27.4.2 + jsdom: 16.7.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-environment-node/27.4.6: + resolution: {integrity: sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.4.6 + '@jest/fake-timers': 27.4.6 + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + jest-mock: 27.4.6 + jest-util: 27.4.2 + dev: true + + /jest-get-type/27.4.0: + resolution: {integrity: sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dev: true + + /jest-haste-map/27.4.6: + resolution: {integrity: sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + '@types/graceful-fs': 4.1.5 + '@types/node': 17.0.8 + anymatch: 3.1.2 + fb-watchman: 2.0.1 + graceful-fs: 4.2.9 + jest-regex-util: 27.4.0 + jest-serializer: 27.4.0 + jest-util: 27.4.2 + jest-worker: 27.4.6 + micromatch: 4.0.4 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /jest-jasmine2/27.4.6: + resolution: {integrity: sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.4.6 + '@jest/source-map': 27.4.0 + '@jest/test-result': 27.4.6 + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + chalk: 4.1.2 + co: 4.6.0 + expect: 27.4.6 + is-generator-fn: 2.1.0 + jest-each: 27.4.6 + jest-matcher-utils: 27.4.6 + jest-message-util: 27.4.6 + jest-runtime: 27.4.6 + jest-snapshot: 27.4.6 + jest-util: 27.4.2 + pretty-format: 27.4.6 + throat: 6.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-leak-detector/27.4.6: + resolution: {integrity: sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + jest-get-type: 27.4.0 + pretty-format: 27.4.6 + dev: true + + /jest-matcher-utils/27.4.6: + resolution: {integrity: sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 27.4.6 + jest-get-type: 27.4.0 + pretty-format: 27.4.6 + dev: true + + /jest-message-util/27.4.6: + resolution: {integrity: sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@babel/code-frame': 7.16.7 + '@jest/types': 27.4.2 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.9 + micromatch: 4.0.4 + pretty-format: 27.4.6 + slash: 3.0.0 + stack-utils: 2.0.5 + dev: true + + /jest-mock/27.4.6: + resolution: {integrity: sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + dev: true + + /jest-pnp-resolver/1.2.2_jest-resolve@27.4.6: + resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 27.4.6 + dev: true + + /jest-regex-util/27.4.0: + resolution: {integrity: sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dev: true + + /jest-resolve-dependencies/27.4.6: + resolution: {integrity: sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + jest-regex-util: 27.4.0 + jest-snapshot: 27.4.6 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve/27.4.6: + resolution: {integrity: sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + chalk: 4.1.2 + graceful-fs: 4.2.9 + jest-haste-map: 27.4.6 + jest-pnp-resolver: 1.2.2_jest-resolve@27.4.6 + jest-util: 27.4.2 + jest-validate: 27.4.6 + resolve: 1.21.0 + resolve.exports: 1.1.0 + slash: 3.0.0 + dev: true + + /jest-runner/27.4.6: + resolution: {integrity: sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/console': 27.4.6 + '@jest/environment': 27.4.6 + '@jest/test-result': 27.4.6 + '@jest/transform': 27.4.6 + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + chalk: 4.1.2 + emittery: 0.8.1 + exit: 0.1.2 + graceful-fs: 4.2.9 + jest-docblock: 27.4.0 + jest-environment-jsdom: 27.4.6 + jest-environment-node: 27.4.6 + jest-haste-map: 27.4.6 + jest-leak-detector: 27.4.6 + jest-message-util: 27.4.6 + jest-resolve: 27.4.6 + jest-runtime: 27.4.6 + jest-util: 27.4.2 + jest-worker: 27.4.6 + source-map-support: 0.5.21 + throat: 6.0.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-runtime/27.4.6: + resolution: {integrity: sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.4.6 + '@jest/fake-timers': 27.4.6 + '@jest/globals': 27.4.6 + '@jest/source-map': 27.4.0 + '@jest/test-result': 27.4.6 + '@jest/transform': 27.4.6 + '@jest/types': 27.4.2 + chalk: 4.1.2 + cjs-module-lexer: 1.2.2 + collect-v8-coverage: 1.0.1 + execa: 5.1.1 + glob: 7.2.0 + graceful-fs: 4.2.9 + jest-haste-map: 27.4.6 + jest-message-util: 27.4.6 + jest-mock: 27.4.6 + jest-regex-util: 27.4.0 + jest-resolve: 27.4.6 + jest-snapshot: 27.4.6 + jest-util: 27.4.2 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-serializer/27.4.0: + resolution: {integrity: sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@types/node': 17.0.8 + graceful-fs: 4.2.9 + dev: true + + /jest-snapshot/27.4.6: + resolution: {integrity: sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@babel/core': 7.16.7 + '@babel/generator': 7.16.7 + '@babel/plugin-syntax-typescript': 7.16.7_@babel+core@7.16.7 + '@babel/traverse': 7.16.7 + '@babel/types': 7.16.7 + '@jest/transform': 27.4.6 + '@jest/types': 27.4.2 + '@types/babel__traverse': 7.14.2 + '@types/prettier': 2.4.2 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.16.7 + chalk: 4.1.2 + expect: 27.4.6 + graceful-fs: 4.2.9 + jest-diff: 27.4.6 + jest-get-type: 27.4.0 + jest-haste-map: 27.4.6 + jest-matcher-utils: 27.4.6 + jest-message-util: 27.4.6 + jest-util: 27.4.2 + natural-compare: 1.4.0 + pretty-format: 27.4.6 + semver: 7.3.5 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-util/27.4.2: + resolution: {integrity: sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + chalk: 4.1.2 + ci-info: 3.3.0 + graceful-fs: 4.2.9 + picomatch: 2.3.1 + dev: true + + /jest-validate/27.4.6: + resolution: {integrity: sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.4.2 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 27.4.0 + leven: 3.1.0 + pretty-format: 27.4.6 + dev: true + + /jest-watcher/27.4.6: + resolution: {integrity: sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/test-result': 27.4.6 + '@jest/types': 27.4.2 + '@types/node': 17.0.8 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + jest-util: 27.4.2 + string-length: 4.0.2 + dev: true + + /jest-worker/27.4.6: + resolution: {integrity: sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 17.0.8 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest/27.4.7: + resolution: {integrity: sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 27.4.7 + import-local: 3.0.3 + jest-cli: 27.4.7 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /joycon/3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + dev: true + + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-types/1.0.0: + resolution: {integrity: sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=} + engines: {node: '>=0.10.0'} + dev: true + + /js-yaml/3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /js-yaml/4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsdoctypeparser/9.0.0: + resolution: {integrity: sha512-jrTA2jJIL6/DAEILBEh2/w9QxCuwmvNXIry39Ay/HVfhE3o2yVV0U44blYkqdHA/OKloJEqvJy0xU+GSdE2SIw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /jsdom/16.7.0: + resolution: {integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==} + engines: {node: '>=10'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + dependencies: + abab: 2.0.5 + acorn: 8.7.0 + acorn-globals: 6.0.0 + cssom: 0.4.4 + cssstyle: 2.3.0 + data-urls: 2.0.0 + decimal.js: 10.3.1 + domexception: 2.0.1 + escodegen: 2.0.0 + form-data: 3.0.1 + html-encoding-sniffer: 2.0.1 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.0 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.0 + parse5: 6.0.1 + saxes: 5.0.1 + symbol-tree: 3.2.4 + tough-cookie: 4.0.0 + w3c-hr-time: 1.0.2 + w3c-xmlserializer: 2.0.0 + webidl-conversions: 6.1.0 + whatwg-encoding: 1.0.5 + whatwg-mimetype: 2.3.0 + whatwg-url: 8.7.0 + ws: 7.5.6 + xml-name-validator: 3.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /jsesc/2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-parse-even-better-errors/2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse/0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-stable-stringify-without-jsonify/1.0.1: + resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} + dev: true + + /json5/1.0.1: + resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + hasBin: true + dependencies: + minimist: 1.2.5 + dev: true + + /json5/2.2.0: + resolution: {integrity: sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==} + engines: {node: '>=6'} + hasBin: true + dependencies: + minimist: 1.2.5 + dev: true + + /jsonc-eslint-parser/2.0.4_eslint@8.6.0: + resolution: {integrity: sha512-a3ZRus4qea0tSRCW2qvF/spFt7iCpdeJbiDjxbFZRZ87JCF8sI8hbxpVvUBVyZ3fLB/RQnTi+Y/yZbMlqt1BCg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.7.0 + eslint-utils: 3.0.0_eslint@8.6.0 + eslint-visitor-keys: 3.1.0 + espree: 9.3.0 + semver: 7.3.5 + transitivePeerDependencies: + - eslint + dev: true + + /jsonc-parser/3.0.0: + resolution: {integrity: sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==} + dev: true + + /jsx-ast-utils/3.2.1: + resolution: {integrity: sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==} + engines: {node: '>=4.0'} + dependencies: + array-includes: 3.1.4 + object.assign: 4.1.2 + dev: true + + /kleur/3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + + /leven/3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + + /levn/0.3.0: + resolution: {integrity: sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + dev: true + + /levn/0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lilconfig/2.0.4: + resolution: {integrity: sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==} + engines: {node: '>=10'} + dev: true + + /lines-and-columns/1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /lint-staged/12.1.5: + resolution: {integrity: sha512-WyKb+0sNKDTd1LwwAfTBPp0XmdaKkAOEbg4oHE4Kq2+oQVchg/VAcjVQtSqZih1izNsTURjc2EkhG/syRQUXdA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + dependencies: + cli-truncate: 3.1.0 + colorette: 2.0.16 + commander: 8.3.0 + debug: 4.3.3_supports-color@9.2.1 + execa: 5.1.1 + lilconfig: 2.0.4 + listr2: 3.14.0 + micromatch: 4.0.4 + normalize-path: 3.0.0 + object-inspect: 1.12.0 + string-argv: 0.3.1 + supports-color: 9.2.1 + yaml: 1.10.2 + transitivePeerDependencies: + - enquirer + dev: true + + /listr2/3.14.0: + resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} + engines: {node: '>=10.0.0'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + dependencies: + cli-truncate: 2.1.0 + colorette: 2.0.16 + log-update: 4.0.0 + p-map: 4.0.0 + rfdc: 1.3.0 + rxjs: 7.5.1 + through: 2.3.8 + wrap-ansi: 7.0.0 + dev: true + + /locate-path/2.0.0: + resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=} + engines: {node: '>=4'} + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + dev: true + + /locate-path/5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path/6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.merge/4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /log-update/4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + dev: true + + /loose-envify/1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + + /lowercase-keys/1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + dev: true + + /lru-cache/6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /make-dir/3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: true + + /makeerror/1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + + /mdast-util-from-markdown/0.8.5: + resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + dependencies: + '@types/mdast': 3.0.10 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-to-string/2.0.0: + resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + dev: true + + /merge-stream/2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2/1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /micromark/2.11.4: + resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} + dependencies: + debug: 4.3.3 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /micromatch/4.0.4: + resolution: {integrity: sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mime-db/1.51.0: + resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types/2.1.34: + resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.51.0 + dev: true + + /mimic-fn/2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /min-indent/1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch/3.0.4: + resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimist/1.2.5: + resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} + dev: true + + /ms/2.0.0: + resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} + dev: true + + /ms/2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms/2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /multimap/1.1.0: + resolution: {integrity: sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==} + dev: true + + /mz/2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + + /natural-compare/1.4.0: + resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} + dev: true + + /node-int64/0.4.0: + resolution: {integrity: sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=} + dev: true + + /node-releases/2.0.1: + resolution: {integrity: sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==} + dev: true + + /normalize-package-data/2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.21.0 + semver: 5.7.1 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-path/3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path/4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /nwsapi/2.2.0: + resolution: {integrity: sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==} + dev: true + + /obj-props/1.3.0: + resolution: {integrity: sha512-k2Xkjx5wn6eC3537SWAXHzB6lkI81kS+icMKMkh4nG3w7shWG6MaWOBrNvhWVOszrtL5uxdfymQQfPUxwY+2eg==} + engines: {node: '>=0.10.0'} + dev: true + + /object-assign/4.1.1: + resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=} + engines: {node: '>=0.10.0'} + dev: true + + /object-inspect/1.12.0: + resolution: {integrity: sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==} + dev: true + + /object-keys/1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign/4.1.2: + resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + has-symbols: 1.0.2 + object-keys: 1.1.1 + dev: true + + /object.entries/1.1.5: + resolution: {integrity: sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + es-abstract: 1.19.1 + dev: true + + /object.fromentries/2.0.5: + resolution: {integrity: sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + es-abstract: 1.19.1 + dev: true + + /object.hasown/1.1.0: + resolution: {integrity: sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==} + dependencies: + define-properties: 1.1.3 + es-abstract: 1.19.1 + dev: true + + /object.values/1.1.5: + resolution: {integrity: sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + es-abstract: 1.19.1 + dev: true + + /once/1.4.0: + resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime/5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /opencollective-postinstall/2.0.3: + resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==} + hasBin: true + dev: true + + /optionator/0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.3 + dev: true + + /optionator/0.9.1: + resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.3 + dev: true + + /p-limit/1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + dependencies: + p-try: 1.0.0 + dev: true + + /p-limit/2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit/3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate/2.0.0: + resolution: {integrity: sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=} + engines: {node: '>=4'} + dependencies: + p-limit: 1.3.0 + dev: true + + /p-locate/4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate/5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map/4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /p-try/1.0.0: + resolution: {integrity: sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=} + engines: {node: '>=4'} + dev: true + + /p-try/2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /parent-module/1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-entities/2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + dev: true + + /parse-json/5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.16.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /parse5/6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + dev: true + + /path-exists/3.0.0: + resolution: {integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=} + engines: {node: '>=4'} + dev: true + + /path-exists/4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} + engines: {node: '>=0.10.0'} + dev: true + + /path-key/3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-type/4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /picocolors/1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch/2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pirates/4.0.4: + resolution: {integrity: sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==} + engines: {node: '>= 6'} + dev: true + + /pkg-dir/4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /pkg-dir/5.0.0: + resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} + engines: {node: '>=10'} + dependencies: + find-up: 5.0.0 + dev: true + + /please-upgrade-node/3.2.0: + resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==} + dependencies: + semver-compare: 1.0.0 + dev: true + + /pluralize/8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + + /postcss-load-config/3.1.1: + resolution: {integrity: sha512-c/9XYboIbSEUZpiD1UQD0IKiUe8n9WHYV7YFe7X7J+ZwCsEKkUJSFWjS9hBU1RR9THR7jMXst8sxiqP0jjo2mg==} + engines: {node: '>= 10'} + peerDependencies: + ts-node: '>=9.0.0' + peerDependenciesMeta: + ts-node: + optional: true + dependencies: + lilconfig: 2.0.4 + yaml: 1.10.2 + dev: true + + /prelude-ls/1.1.2: + resolution: {integrity: sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=} + engines: {node: '>= 0.8.0'} + dev: true + + /prelude-ls/1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /pretty-format/27.4.6: + resolution: {integrity: sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + dev: true + + /progress/2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + dev: true + + /prompts/2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /prop-types/15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + + /proto-props/2.0.0: + resolution: {integrity: sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==} + engines: {node: '>=4'} + dev: true + + /psl/1.8.0: + resolution: {integrity: sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==} + dev: true + + /punycode/2.1.1: + resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} + engines: {node: '>=6'} + dev: true + + /queue-microtask/1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /react-is/16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /react-is/17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + + /read-pkg-up/7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg/5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /readdirp/3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /refa/0.9.1: + resolution: {integrity: sha512-egU8LgFq2VXlAfUi8Jcbr5X38wEOadMFf8tCbshgcpVCYlE7k84pJOSlnvXF+muDB4igkdVMq7Z/kiNPqDT9TA==} + dependencies: + regexpp: 3.2.0 + dev: true + + /regexp-ast-analysis/0.2.4: + resolution: {integrity: sha512-8L7kOZQaKPxKKAwGuUZxTQtlO3WZ+tiXy4s6G6PKL6trbOXcZoumwC3AOHHFtI/xoSbNxt7jgLvCnP1UADLWqg==} + dependencies: + refa: 0.9.1 + regexpp: 3.2.0 + dev: true + + /regexp-ast-analysis/0.3.0: + resolution: {integrity: sha512-11PlbBSUxwWpdj6BdZUKfhDdV9g+cveqHB+BqBQDBD7ZermDBVgtyowUaXTvT0dO3tZYo2bDIr/GoED6X1aYSA==} + dependencies: + refa: 0.9.1 + regexpp: 3.2.0 + dev: true + + /regexp-tree/0.1.24: + resolution: {integrity: sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==} + hasBin: true + dev: true + + /regexp.prototype.flags/1.3.1: + resolution: {integrity: sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + dev: true + + /regexpp/3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /require-directory/2.1.1: + resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} + engines: {node: '>=0.10.0'} + dev: true + + /resolve-cwd/3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + + /resolve-from/4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from/5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve.exports/1.1.0: + resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} + engines: {node: '>=10'} + dev: true + + /resolve/1.21.0: + resolution: {integrity: sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==} + hasBin: true + dependencies: + is-core-module: 2.8.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /resolve/2.0.0-next.3: + resolution: {integrity: sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==} + dependencies: + is-core-module: 2.8.0 + path-parse: 1.0.7 + dev: true + + /restore-cursor/3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.6 + dev: true + + /reusify/1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rfdc/1.3.0: + resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.0 + dev: true + + /rollup/2.63.0: + resolution: {integrity: sha512-nps0idjmD+NXl6OREfyYXMn/dar3WGcyKn+KBzPdaLecub3x/LrId0wUcthcr8oZUAcZAR8NKcfGGFlNgGL1kQ==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /run-parallel/1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs/7.5.1: + resolution: {integrity: sha512-KExVEeZWxMZnZhUZtsJcFwz8IvPvgu4G2Z2QyqjZQzUGr32KDYuSxrEYO4w3tFFNbfLozcrKUTvTPi+E9ywJkQ==} + dependencies: + tslib: 2.3.1 + dev: true + + /safe-buffer/5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-regex/2.1.1: + resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} + dependencies: + regexp-tree: 0.1.24 + dev: true + + /safer-buffer/2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /saxes/5.0.1: + resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} + engines: {node: '>=10'} + dependencies: + xmlchars: 2.2.0 + dev: true + + /scslre/0.1.6: + resolution: {integrity: sha512-JORxVRlQTfjvlOAaiQKebgFElyAm5/W8b50lgaZ0OkEnKnagJW2ufDh3xRfU75UD9z3FGIu1gL1IyR3Poa6Qmw==} + dependencies: + refa: 0.9.1 + regexp-ast-analysis: 0.2.4 + regexpp: 3.2.0 + dev: true + + /semver-compare/1.0.0: + resolution: {integrity: sha1-De4hahyUGrN+nvsXiPavxf9VN/w=} + dev: true + + /semver-regex/3.1.3: + resolution: {integrity: sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==} + engines: {node: '>=8'} + dev: true + + /semver/5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + dev: true + + /semver/6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver/7.3.5: + resolution: {integrity: sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /shebang-command/2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex/3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /side-channel/1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.1 + object-inspect: 1.12.0 + dev: true + + /signal-exit/3.0.6: + resolution: {integrity: sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==} + dev: true + + /sisteransi/1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /slash/3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-ansi/3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi/4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi/5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.1.0 + is-fullwidth-code-point: 4.0.0 + dev: true + + /source-map-support/0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map/0.5.7: + resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=} + engines: {node: '>=0.10.0'} + dev: true + + /source-map/0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map/0.7.3: + resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==} + engines: {node: '>= 8'} + dev: true + + /spdx-correct/3.1.1: + resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.11 + dev: true + + /spdx-exceptions/2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse/3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.11 + dev: true + + /spdx-license-ids/3.0.11: + resolution: {integrity: sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==} + dev: true + + /sprintf-js/1.0.3: + resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=} + dev: true + + /stack-utils/2.0.5: + resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /string-argv/0.3.1: + resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} + engines: {node: '>=0.6.19'} + dev: true + + /string-length/4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + + /string-width/4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string-width/5.0.1: + resolution: {integrity: sha512-5ohWO/M4//8lErlUUtrFy3b11GtNOuMOU0ysKCDXFcfXuuvUXu95akgj/i8ofmaGdN0hCqyl6uu9i8dS/mQp5g==} + engines: {node: '>=12'} + dependencies: + emoji-regex: 9.2.2 + is-fullwidth-code-point: 4.0.0 + strip-ansi: 7.0.1 + dev: true + + /string.prototype.matchall/4.0.6: + resolution: {integrity: sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + es-abstract: 1.19.1 + get-intrinsic: 1.1.1 + has-symbols: 1.0.2 + internal-slot: 1.0.3 + regexp.prototype.flags: 1.3.1 + side-channel: 1.0.4 + dev: true + + /string.prototype.trimend/1.0.4: + resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + dev: true + + /string.prototype.trimstart/1.0.4: + resolution: {integrity: sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.3 + dev: true + + /strip-ansi/6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-ansi/7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + + /strip-bom/3.0.0: + resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=} + engines: {node: '>=4'} + dev: true + + /strip-bom/4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-final-newline/2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-indent/3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments/3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /sucrase/3.20.3: + resolution: {integrity: sha512-azqwq0/Bs6RzLAdb4dXxsCgMtAaD2hzmUr4UhSfsxO46JFPAwMnnb441B/qsudZiS6Ylea3JXZe3Q497lsgXzQ==} + engines: {node: '>=8'} + hasBin: true + dependencies: + commander: 4.1.1 + glob: 7.1.6 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.4 + ts-interface-checker: 0.1.13 + dev: true + + /supports-color/5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color/8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color/9.2.1: + resolution: {integrity: sha512-Obv7ycoCTG51N7y175StI9BlAXrmgZrFhZOb0/PyjHBher/NmsdBgbbQ1Inhq+gIhz6+7Gb+jWF2Vqi7Mf1xnQ==} + engines: {node: '>=12'} + dev: true + + /supports-hyperlinks/2.2.0: + resolution: {integrity: sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /symbol-tree/3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + dev: true + + /terminal-columns/1.4.0: + resolution: {integrity: sha512-Oh62O26xgOUjakUlGfjAEdgZmipNsqHPmvs8QQ8j6WH3c5iXhshCjr6yB6bW7CYXG5POoUrHLLLcKdRvv8LBZg==} + dev: false + + /terminal-link/2.1.1: + resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} + engines: {node: '>=8'} + dependencies: + ansi-escapes: 4.3.2 + supports-hyperlinks: 2.2.0 + dev: true + + /test-exclude/6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.0 + minimatch: 3.0.4 + dev: true + + /text-table/0.2.0: + resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} + dev: true + + /thenify-all/1.6.0: + resolution: {integrity: sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify/3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + + /throat/6.0.1: + resolution: {integrity: sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==} + dev: true + + /through/2.3.8: + resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=} + dev: true + + /tmpl/1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + + /to-fast-properties/2.0.0: + resolution: {integrity: sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=} + engines: {node: '>=4'} + dev: true + + /to-regex-range/5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /tough-cookie/4.0.0: + resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==} + engines: {node: '>=6'} + dependencies: + psl: 1.8.0 + punycode: 2.1.1 + universalify: 0.1.2 + dev: true + + /tr46/2.1.0: + resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==} + engines: {node: '>=8'} + dependencies: + punycode: 2.1.1 + dev: true + + /tree-kill/1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + dev: true + + /ts-interface-checker/0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: true + + /tsconfig-paths/3.12.0: + resolution: {integrity: sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.1 + minimist: 1.2.5 + strip-bom: 3.0.0 + dev: true + + /tslib/1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tslib/2.3.1: + resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} + dev: true + + /tsup/5.11.10_typescript@4.5.4: + resolution: {integrity: sha512-z8YzbPyF8Vvj37h+TY84AfvlmKZtBTRuWwRETWUbfckMj854WeLkuRQV8vRyoY8bLJQhnKWlLge/3fVbFZGERg==} + hasBin: true + peerDependencies: + typescript: ^4.1.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + bundle-require: 2.2.0_esbuild@0.14.10 + cac: 6.7.12 + chokidar: 3.5.2 + debug: 4.3.3 + esbuild: 0.14.10 + execa: 5.1.1 + globby: 11.0.4 + joycon: 3.1.1 + postcss-load-config: 3.1.1 + resolve-from: 5.0.0 + rollup: 2.63.0 + source-map: 0.7.3 + sucrase: 3.20.3 + tree-kill: 1.2.2 + typescript: 4.5.4 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + + /tsutils/3.21.0_typescript@4.5.4: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + dependencies: + tslib: 1.14.1 + typescript: 4.5.4 + dev: true + + /type-check/0.3.2: + resolution: {integrity: sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + dev: true + + /type-check/0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-detect/4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest/0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest/0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /type-fest/0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest/0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /type-flag/2.0.0: + resolution: {integrity: sha512-L0jgov26xVtNM23pL0Roh45Is/l8aIA6YyI9U8x8L8tcw2t+nwZHYzjBVB8CIJ2PFe3qb5hJSDynUmKP1GcHtw==} + dev: false + + /typedarray-to-buffer/3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + dependencies: + is-typedarray: 1.0.0 + dev: true + + /typescript/4.5.4: + resolution: {integrity: sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /unbox-primitive/1.0.1: + resolution: {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 + dev: true + + /unist-util-stringify-position/2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /universalify/0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + + /uri-js/4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.1.1 + dev: true + + /v8-compile-cache/2.3.0: + resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} + dev: true + + /v8-to-istanbul/8.1.0: + resolution: {integrity: sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==} + engines: {node: '>=10.12.0'} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 1.8.0 + source-map: 0.7.3 + dev: true + + /validate-npm-package-license/3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.1.1 + spdx-expression-parse: 3.0.1 + dev: true + + /vue-eslint-parser/8.0.1_eslint@8.6.0: + resolution: {integrity: sha512-lhWjDXJhe3UZw2uu3ztX51SJAPGPey1Tff2RK3TyZURwbuI4vximQLzz4nQfCv8CZq4xx7uIiogHMMoSJPr33A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.3 + eslint: 8.6.0 + eslint-scope: 6.0.0 + eslint-visitor-keys: 3.1.0 + espree: 9.3.0 + esquery: 1.4.0 + lodash: 4.17.21 + semver: 7.3.5 + transitivePeerDependencies: + - supports-color + dev: true + + /w3c-hr-time/1.0.2: + resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} + dependencies: + browser-process-hrtime: 1.0.0 + dev: true + + /w3c-xmlserializer/2.0.0: + resolution: {integrity: sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==} + engines: {node: '>=10'} + dependencies: + xml-name-validator: 3.0.0 + dev: true + + /walker/1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true + + /webidl-conversions/5.0.0: + resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} + engines: {node: '>=8'} + dev: true + + /webidl-conversions/6.1.0: + resolution: {integrity: sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==} + engines: {node: '>=10.4'} + dev: true + + /whatwg-encoding/1.0.5: + resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} + dependencies: + iconv-lite: 0.4.24 + dev: true + + /whatwg-mimetype/2.3.0: + resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} + dev: true + + /whatwg-url/8.7.0: + resolution: {integrity: sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==} + engines: {node: '>=10'} + dependencies: + lodash: 4.17.21 + tr46: 2.1.0 + webidl-conversions: 6.1.0 + dev: true + + /which-boxed-primitive/1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.6 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-pm-runs/1.0.0: + resolution: {integrity: sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=} + dev: true + + /which/2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /word-wrap/1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /wrap-ansi/6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi/7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy/1.0.2: + resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} + dev: true + + /write-file-atomic/3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.6 + typedarray-to-buffer: 3.1.5 + dev: true + + /ws/7.5.6: + resolution: {integrity: sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /xml-name-validator/3.0.0: + resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} + dev: true + + /xmlchars/2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + dev: true + + /y18n/5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist/4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yaml/1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yargs-parser/20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + dev: true + + /yargs/16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + dev: true + + /yocto-queue/0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 0000000..398eb4f --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,337 @@ +import typeFlag from 'type-flag'; +import type { + CallbackFunction, + HasHelpOrVersion, + CliOptions, + CliOptionsInternal, + ParseArgv, + parsedType, + HelpOptions, + HelpDocumentNode, +} from './types'; +import { Command } from './command'; +import { generateHelp, Renderers } from './render-help'; +import { camelCase } from './utils/convert-case'; +import { isScriptNamePattern } from './utils/is-script-name'; + +const { stringify } = JSON; + +const specialCharactersPattern = /[|\\{}()[\]^$+*?.]/; + +function parseParameters(parameters: string[]) { + const parsedParameters: { + name: string; + required: boolean; + spread: boolean; + }[] = []; + + let hasOptional: string | undefined; + let hasSpread: string | undefined; + + for (const parameter of parameters) { + if (hasSpread) { + throw new Error(`Invalid parameter: Spread parameter ${stringify(hasSpread)} must be last`); + } + + const firstCharacter = parameter[0]; + const lastCharacter = parameter[parameter.length - 1]; + + let required: boolean | undefined; + if (firstCharacter === '<' && lastCharacter === '>') { + required = true; + + if (hasOptional) { + throw new Error(`Invalid parameter: Required parameter ${stringify(parameter)} cannot come after optional parameter ${stringify(hasOptional)}`); + } + } + + if (firstCharacter === '[' && lastCharacter === ']') { + required = false; + hasOptional = parameter; + } + + if (required === undefined) { + throw new Error(`Invalid parameter: ${stringify(parameter)}. Must be wrapped in <> (required parameter) or [] (optional parameter)`); + } + + let name = parameter.slice(1, -1); + + const spread = name.slice(-3) === '...'; + + if (spread) { + hasSpread = parameter; + name = name.slice(0, -3); + } + + const invalidCharacter = name.match(specialCharactersPattern); + if (invalidCharacter) { + throw new Error(`Invalid parameter: ${stringify(parameter)}. Invalid character found ${stringify(invalidCharacter[0])}`); + } + + parsedParameters.push({ + name, + required, + spread, + }); + } + + return parsedParameters; +} + +function helpEnabled(help: false | undefined | HelpOptions): help is (HelpOptions | undefined) { + return ( + // Default + help === undefined + + // Configured + || help !== false + ); +} + +function cliBase< + CommandName extends string | undefined, + Options extends CliOptionsInternal, + Parameters extends string[], +>( + command: CommandName, + options: Options, + callback: CallbackFunction> | undefined, + argv: string[], +) { + const flags = { ...options.flags }; + const isVersionEnabled = options.version; + + // Expected to work even if flag is overwritten; add tests + if (isVersionEnabled) { + flags.version = { + type: Boolean, + description: 'Show version', + }; + } + + const { help } = options; + const isHelpEnabled = helpEnabled(help); + + // Expected to work even if overwritten; add tests + if (isHelpEnabled && !('help' in flags)) { + flags.help = { + type: Boolean, + alias: 'h', + description: 'Show help', + }; + } + + const parsed = typeFlag(flags as HasHelpOrVersion, argv); + + const showVersion = () => { + console.log(options.version); + }; + + if ( + isVersionEnabled + + // Can be overridden to different type + && parsed.flags.version === true + ) { + showVersion(); + return process.exit(0); + } + + const helpRenderers = new Renderers(); + const renderHelpFunction = ( + (isHelpEnabled && help?.render) + ? help.render + : (nodes: HelpDocumentNode | HelpDocumentNode[]) => helpRenderers.render(nodes) + ); + + const showHelp = (helpOptions?: HelpOptions) => { + const nodes = generateHelp({ + ...options, + ...(helpOptions ? { help: helpOptions } : {}), + flags, + }); + + console.log(renderHelpFunction(nodes, helpRenderers)); + }; + + if ( + isHelpEnabled + + // Can be overridden to different type + && parsed.flags.help === true + ) { + showHelp(); + return process.exit(0); + } + + if (options.parameters) { + const parsedParameters = parseParameters(options.parameters); + const _ = parsed._ as (string[] & Record); + + for (let i = 0; i < parsedParameters.length; i += 1) { + const { name, required, spread } = parsedParameters[i]; + const value = spread ? parsed._.slice(i) : parsed._[i]; + + if (spread) { + i = parsedParameters.length; + } + + if ( + required + && (!value || (spread && value.length === 0)) + ) { + console.error(`Error: Missing required parameter ${stringify(name)}\n`); + showHelp(); + return process.exit(1); + } + + _[camelCase(name)] = value; + } + } + + const parsedWithApi = { + ...parsed, + showVersion, + showHelp, + }; + + if (typeof callback === 'function') { + callback(parsedWithApi as any); + } + + // Already flattened + return { + command, + ...parsedWithApi, + }; +} + +function getCommand( + potentialCommand: string, + commands: [...Commands], +) { + const commandMap = new Map(); + for (const command of commands) { + const names = [command.options.name]; + + const { alias } = command.options; + if (alias) { + if (Array.isArray(alias)) { + names.push(...alias); + } else { + names.push(alias); + } + } + + for (const name of names) { + if (commandMap.has(name)) { + throw new Error(`Duplicate command name found: ${stringify(name)}`); + } + + commandMap.set(name, command); + } + } + + return commandMap.get(potentialCommand); +} + +function cli< + Options extends CliOptions, + Parameters extends string[], +>( + options: Options & CliOptions, + callback?: CallbackFunction>, + argv?: string[], +): { + [ + Key in keyof ParseArgv< + Options, + Parameters, + undefined + > + ]: ParseArgv< + Options, + Parameters, + undefined + >[Key]; +}; + +function cli< + Options extends CliOptions<[...Commands], [...Parameters]>, + Commands extends Command[], + Parameters extends string[], +>( + options: Options & CliOptions<[...Commands], [...Parameters]>, + callback?: CallbackFunction>, + argv?: string[], +):( + { + [ + Key in keyof ParseArgv< + Options, + Parameters, + undefined + > + ]: ParseArgv< + Options, + Parameters, + undefined + >[Key]; + } + | { + [KeyA in keyof Commands]: ( + Commands[KeyA] extends Command + ? ( + { + [ + KeyB in keyof Commands[KeyA][typeof parsedType] + ]: Commands[KeyA][typeof parsedType][KeyB]; + } + ) : never + ); + }[number] +); + +function cli< + Options extends CliOptions<[...Commands], [...Parameters]>, + Commands extends Command[], + Parameters extends string[], +>( + options: Options | (Options & CliOptions<[...Commands], [...Parameters]>), + callback?: CallbackFunction>, + argv = process.argv.slice(2), +) { + // Because if not configured, it's probably being misused or overlooked + if (!options) { + throw new Error('Options is required'); + } + + if ('name' in options && (!options.name || !isScriptNamePattern.test(options.name))) { + throw new Error(`Invalid script name: ${stringify(options.name)}`); + } + + const potentialCommand = argv[0]; + + if ( + options.commands + && isScriptNamePattern.test(potentialCommand) + ) { + const command = getCommand(potentialCommand, options.commands); + + if (command) { + return cliBase( + command.options.name, + { + ...command.options, + parent: options, + }, + command.callback, + argv.slice(1), + ); + } + } + + return cliBase(undefined, options, callback, argv); +} + +export { cli }; diff --git a/src/command.ts b/src/command.ts new file mode 100644 index 0000000..82bc457 --- /dev/null +++ b/src/command.ts @@ -0,0 +1,76 @@ +import type { + CallbackFunction, + Flags, + HelpOptions, + ParseArgv, + parsedType, +} from './types'; +import { isScriptNamePattern } from './utils/is-script-name'; + +export type CommandOptions = { + /** + Name of the command used to invoke it. Also displayed in `--help` output. + */ + name: string; + + /** + Aliases for the command used to invoke it. Also displayed in `--help` output. + */ + alias?: string | string[]; + + /** + Parameters accepted by the command. Parameters must be in the following formats: + + - Required parameter: `` + - Optional parameter: `[parameter name]` + - Required spread parameter: `` + - Optional spread parameter: `[parameter name...]` + */ + parameters?: Parameters; + + /** + Flags accepted by the command + */ + flags?: Flags; + + /** + Options to configure the help documentation. Pass in `false` to disable handling `--help, -h`. + */ + help?: false | HelpOptions; +}; + +export function command< + Options extends CommandOptions<[...Parameters]>, + Parameters extends string[], +>( + options: Readonly & CommandOptions<[...Parameters]>, + callback?: CallbackFunction>, +): Command> { + if (!options) { + throw new Error('Command options are required'); + } + + const { name } = options; + if (options.name === undefined) { + throw new Error('Command name is required'); + } + + if (!isScriptNamePattern.test(name)) { + throw new Error(`Invalid command name ${JSON.stringify(name)}. Command names must be one word.`); + } + + // @ts-expect-error Missing parsedType, a type only property + return { + options, + callback, + }; +} + +export type Command< + Options extends CommandOptions = CommandOptions, + ParsedType = any, +> = { + readonly options: Options; + readonly callback?: CallbackFunction; + [parsedType]: ParsedType; +}; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..696e51f --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +export { cli } from './cli'; +export { command } from './command'; diff --git a/src/render-help/generate-help.ts b/src/render-help/generate-help.ts new file mode 100644 index 0000000..d91eac0 --- /dev/null +++ b/src/render-help/generate-help.ts @@ -0,0 +1,245 @@ +import type { + CliOptionsInternal, + HelpDocumentNode, +} from '../types'; +import type { CommandOptions } from '../command'; +import type { Renderers } from './renderers'; +import { renderFlags } from './render-flags'; + +type Options = CliOptionsInternal | CommandOptions; + +const getVersion = (options?: CliOptionsInternal) => ( + !options || ( + options.version ?? ( + options.help + ? options.help.version + : undefined + ) + ) +); + +const getName = (options: Options) => { + const parentName = ('parent' in options) && options.parent?.name; + return (parentName ? `${parentName} ` : '') + options.name; +}; + +function getNameAndVersion(options: Options) { + const name = []; + + if (options.name) { + name.push(getName(options)); + } + + const version = getVersion(options) ?? (('parent' in options) && getVersion(options.parent)); + if (version) { + name.push(`v${version}`); + } + + if (name.length === 0) { + return; + } + + return { + id: 'name', + type: 'text', + data: `${name.join(' ')}\n`, + } as const; +} + +function getDescription(options: Options) { + const { help } = options; + if ( + !help + || !help.description + ) { + return; + } + + return { + id: 'description', + type: 'text', + data: `${help.description}\n`, + } as const; +} + +function getUsage(options: Options) { + const help = options.help || {}; + + if ('usage' in help) { + if (!help.usage) { + return; + } + + return { + id: 'usage', + type: 'section', + data: { + title: 'Usage:', + body: ( + Array.isArray(help.usage) + ? help.usage.join('\n') + : help.usage + ), + }, + } as const; + } if (options.name) { + const usages: string[] = []; + + const usage = [getName(options)]; + + if ( + options.flags + && Object.keys(options.flags).length > 0 + ) { + usage.push('[flags...]'); + } + + if ( + options.parameters + && options.parameters.length > 0 + ) { + usage.push(options.parameters.join(' ')); + } + + if (usage.length > 1) { + usages.push(usage.join(' ')); + } + + if ( + 'commands' in options + && options.commands?.length + ) { + usages.push(`${options.name} `); + } + + if (usages.length > 0) { + return { + id: 'usage', + type: 'section', + data: { + title: 'Usage:', + body: usages.join('\n'), + }, + } as const; + } + } +} + +function getCommands(options: Options) { + if ( + !('commands' in options) + || !options.commands?.length + ) { + return; + } + + const commands = options.commands.map( + command => [command.options.name, command.options.help ? command.options.help.description : ''], + ); + + const commandsTable = { + type: 'table', + data: { + tableData: commands, + tableOptions: [ + { + width: 'content-width', + paddingLeft: 2, + paddingRight: 8, + }, + ], + }, + }; + + return { + id: 'commands', + type: 'section', + data: { + title: 'Commands:', + body: commandsTable, + indentBody: 0, + }, + } as const; +} + +function getFlags(options: Options) { + if ( + !options.flags + || Object.keys(options.flags).length === 0 + ) { + return; + } + + return { + id: 'flags', + type: 'section', + data: { + title: 'Flags:', + body: renderFlags(options.flags), + indentBody: 0, + }, + } as const; +} + +function getExamples(options: Options) { + const { help } = options; + if ( + !help + || !help.examples + || help.examples.length === 0 + ) { + return; + } + + let { examples } = help; + + if (Array.isArray(examples)) { + examples = examples.join('\n'); + } + + if (examples) { + return { + id: 'examples', + type: 'section', + data: { + title: 'Examples:', + body: examples, + }, + } as const; + } +} + +function getAliases(options: Options) { + if ( + !('alias' in options) + || !options.alias + ) { + return; + } + + const { alias } = options; + const aliases = Array.isArray(alias) ? alias.join(', ') : alias; + + return { + id: 'aliases', + type: 'section', + data: { + title: 'Aliases:', + body: aliases, + }, + } as const; +} + +export const generateHelp = (options: Options): HelpDocumentNode[] => [ + getNameAndVersion, + getDescription, + getUsage, + getCommands, + getFlags, + getExamples, + getAliases, +].map( + helpSectionGenerator => helpSectionGenerator(options), +).filter( + (value: T): value is NonNullable => Boolean(value), +); diff --git a/src/render-help/index.ts b/src/render-help/index.ts new file mode 100644 index 0000000..5268080 --- /dev/null +++ b/src/render-help/index.ts @@ -0,0 +1,2 @@ +export { generateHelp } from './generate-help'; +export { Renderers } from './renderers'; diff --git a/src/render-help/render-flags.ts b/src/render-help/render-flags.ts new file mode 100644 index 0000000..5a557d0 --- /dev/null +++ b/src/render-help/render-flags.ts @@ -0,0 +1,104 @@ +import type { Flags } from '../types'; +import { kebabCase } from '../utils/convert-case'; + +const tableBreakpoints = { + '> 80': [ + { + width: 'content-width', + paddingLeft: 2, + paddingRight: 8, + }, + + // Flag alias to fill remaining line + { + width: 'auto', + }, + ], + + '> 40': [ + { + width: 'auto', + paddingLeft: 2, + paddingRight: 8, + + // Remove alias padding on smaller screens + preprocess: (text: string) => text.trim(), + }, + + // Flag description to be on own line + { + width: '100%', + paddingLeft: 2, + paddingBottom: 1, + }, + ], + + '> 0': { + // Remove responsiveness + stdoutColumns: 1000, + + columns: [ + { + width: 'content-width', + paddingLeft: 2, + paddingRight: 8, + }, + { + width: 'content-width', + }, + ], + }, +}; + +export type FlagData = { + name: string; + flag: Flags[string]; + flagFormatted: string; + aliasesEnabled: boolean; + aliasFormatted: string | undefined; +}; + +export function renderFlags(flags: Flags) { + let aliasesEnabled = false; + const flagsData = Object.keys(flags) + .sort((a, b) => a.localeCompare(b)) + .map((name): FlagData => { + const flag = flags[name]; + const hasAlias = ('alias' in flag); + + if (hasAlias) { + aliasesEnabled = true; + } + + return { + name, + flag, + flagFormatted: `--${kebabCase(name)}`, + aliasesEnabled, + aliasFormatted: hasAlias ? `-${flag.alias}` : undefined, + }; + }); + + const tableData = flagsData.map((flagData) => { + flagData.aliasesEnabled = aliasesEnabled; + + return [ + { + type: 'flagName', + data: flagData, + }, + { + type: 'flagDescription', + data: flagData, + }, + ]; + }); + + return { + type: 'table', + data: { + tableData, + tableBreakpoints, + }, + }; +} diff --git a/src/render-help/renderers.ts b/src/render-help/renderers.ts new file mode 100644 index 0000000..795e690 --- /dev/null +++ b/src/render-help/renderers.ts @@ -0,0 +1,176 @@ +import tty from 'tty'; +import terminalColumns, { + breakpoints, + Options as TerminalColumnsOptions, +} from 'terminal-columns'; +import type { HelpDocumentNode } from '../types'; +import type { FlagData } from './render-flags'; + +type TypeFunction = (value: any) => any; + +const stdoutHasColors = tty.WriteStream.prototype.hasColors(); + +type HelpDocumentNodeOrString = string | HelpDocumentNode; +export class Renderers { + // Useful for associating an id with data: + // { id: 'title', type: 'string' } + text(text: string) { + return text; + } + + bold(text: string) { + return `\u001B[1m${text}\u001B[22m`; + } + + indentText({ text, spaces }: { text: string; spaces: number }) { + return text.replace(/^/gm, ' '.repeat(spaces)); + } + + heading(text: string) { + return stdoutHasColors ? this.bold(text) : text.toLocaleUpperCase(); + } + + section({ + title, + body, + indentBody = 2, + }: { + title?: string; + body?: string; + indentBody?: number; + }) { + return ( + `${ + ( + title + ? `${this.heading(title)}\n` + : '' + ) + + ( + body + ? this.indentText({ + text: this.render(body), + spaces: indentBody, + }) + : '' + ) + }\n` + ); + } + + table({ + tableData, + tableOptions, + tableBreakpoints, + }: { + tableData: string[][]; + tableOptions?: TerminalColumnsOptions; + tableBreakpoints?: Record; + }) { + return terminalColumns( + tableData.map(row => row.map(cell => this.render(cell))), + tableBreakpoints ? breakpoints(tableBreakpoints) : tableOptions, + ); + } + + flagParameter( + typeFunction: TypeFunction | readonly [TypeFunction], + ): string { + if (typeFunction === Boolean) { + return ''; + } + + if (typeFunction === String) { + return ''; + } + + if (typeFunction === Number) { + return ''; + } + + if (Array.isArray(typeFunction)) { + return this.flagParameter(typeFunction[0]); + } + + return ''; + } + + flagOperator() { + return ' '; + } + + flagName({ + flag, + flagFormatted, + aliasesEnabled, + aliasFormatted, + }: FlagData) { + let flagText = ''; + + if (aliasFormatted) { + flagText += `${aliasFormatted}, `; + } else if (aliasesEnabled) { + flagText += ' '; + } + + flagText += flagFormatted; + + if ('placeholder' in flag && typeof flag.placeholder === 'string') { + flagText += `${this.flagOperator()}${flag.placeholder}`; + } else { + // Test: default flag for String type short-hand + const flagPlaceholder = this.flagParameter('type' in flag ? flag.type : flag); + if (flagPlaceholder) { + flagText += `${this.flagOperator()}${flagPlaceholder}`; + } + } + + return flagText; + } + + flagDefault(value: any) { + return JSON.stringify(value); + } + + flagDescription({ flag }: FlagData) { + let descriptionText = 'description' in flag ? (flag.description ?? '') : ''; + + if ('default' in flag) { + let { default: flagDefault } = flag; + + if (typeof flagDefault === 'function') { + flagDefault = flagDefault(); + } + + if (flagDefault) { + descriptionText += ` (default: ${this.flagDefault(flagDefault)})`; + } + } + + return descriptionText; + } + + render( + nodes: ( + HelpDocumentNodeOrString + | HelpDocumentNodeOrString[] + ), + ): string { + if (typeof nodes === 'string') { + return nodes; + } + + if (Array.isArray(nodes)) { + return nodes.map(node => this.render(node)).join('\n'); + } + + if ('type' in nodes && this[nodes.type]) { + const renderer = this[nodes.type]; + if (typeof renderer === 'function') { + return renderer.call(this, nodes.data); + } + } + + throw new Error(`Invalid node type: ${JSON.stringify(nodes)}`); + } +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..c42944b --- /dev/null +++ b/src/types.ts @@ -0,0 +1,187 @@ +import type { TypeFlag, Flags as BaseFlags } from 'type-flag'; +import { Command } from './command'; +import type { Renderers } from './render-help/renderers'; + +export declare const parsedType: unique symbol; + +export type Flags = BaseFlags<{ + + /** + Description to be used in help output + + @example + ``` + description: 'Unit of output (metric, imperial)', + ``` + */ + description?: string; + + /** + Placeholder label to be used in help output + + @example Required value + ``` + placeholder: '' + ``` + */ + placeholder?: string; +}>; + +export type CallbackFunction = (parsed: { + // This exposes the content of "TypeFlag" in type hints + [Key in keyof Parsed]: Parsed[Key]; +}) => void; + +type HasVersion = ( + Options extends { version: string } + ? Options['flags'] & { version: BooleanConstructor } + : Options['flags'] +); + +type HasHelp = ( + Options extends { help: false } + ? Options['flags'] + : Options['flags'] & { help: BooleanConstructor } +); + +export type HasHelpOrVersion = HasVersion & HasHelp; + +export type HelpDocumentNode = { + id?: string; + type: Types; + data: any; +}; + +export type HelpOptions = { + + /** + Version of the script displayed in `--help` output. Use to avoid enabling `--version` flag. + */ + version?: string; + + /** + Description of the script or command to display in `--help` output. + */ + description?: string; + + /** + Usage code examples to display in `--help` output. + */ + usage?: false | string | string[]; + + /** + Example code snippets to display in `--help` output. + */ + examples?: string | string[]; + + /** + Function to customize the help document before it is logged. + */ + render?: ( + nodes: HelpDocumentNode[], + renderers: Renderers, + ) => string; +}; + +export type CliOptions< + Commands = Command[], + Parameters extends string[] = string[], +> = { + /** + Name of the script displayed in `--help` output. + */ + name?: string; + + /** + Version of the script displayed in `--version` and `--help` outputs. + */ + version?: string; + + /** + Parameters accepted by the script. Parameters must be in the following formats: + + - Required parameter: `` + - Optional parameter: `[parameter name]` + - Required spread parameter: `` + - Optional spread parameter: `[parameter name...]` + */ + parameters?: Parameters; + + /** + Commands to register to the script. + */ + commands?: Commands; + + /** + Flags accepted by the script + */ + flags?: Flags; + + /** + Options to configure the help documentation. Pass in `false` to disable handling `--help, -h`. + */ + help?: false | HelpOptions; +}; + +export type CliOptionsInternal< + Commands = Command[], +> = CliOptions & { + parent?: CliOptions; +}; + +type kebabToCamel = ( + Word extends `${infer Prefix}-${infer Suffix}` | `${infer Prefix} ${infer Suffix}` + ? `${Prefix}${Capitalize>}` + : Word +); + +type StripBrackets = ( + Parameter extends `<${infer ParameterName}>` | `[${infer ParameterName}]` + ? ( + ParameterName extends `${infer SpreadName}...` + ? SpreadName + : ParameterName + ) + : never +); + +type ParameterType = ( + Parameter extends `<${infer _ParameterName}...>` | `[${infer _ParameterName}...]` + ? string[] + : Parameter extends `<${infer _ParameterName}>` + ? string + : Parameter extends `[${infer _ParameterName}]` + ? string | undefined + : never +); + +type WithCommand< + Options extends { flags?: Flags }, + Command extends string | undefined = undefined, +> = { + command: Command; +} & Options; + +type TypeFlagWrapper< + Options extends { flags?: Flags }, + Parameters extends string[], +> = TypeFlag> & { + _: { + [ + Parameter in Parameters[number] + as kebabToCamel> + ]: ParameterType; + }; + showHelp: (options?: HelpOptions) => void; + showVersion: () => void; +} + +export type ParseArgv< + Options extends { flags?: Flags }, + Parameters extends string[], + Command extends string | undefined = '', +> = ( + Command extends '' + ? TypeFlagWrapper + : WithCommand, Command> +); diff --git a/src/utils/convert-case.ts b/src/utils/convert-case.ts new file mode 100644 index 0000000..279d24e --- /dev/null +++ b/src/utils/convert-case.ts @@ -0,0 +1,3 @@ +export const camelCase = (word: string) => word.replace(/[-_ ](\w)/g, (_, c) => c.toUpperCase()); + +export const kebabCase = (word: string) => word.replace(/\B([A-Z])/g, '-$1').toLowerCase(); diff --git a/src/utils/is-script-name.ts b/src/utils/is-script-name.ts new file mode 100644 index 0000000..786fcc8 --- /dev/null +++ b/src/utils/is-script-name.ts @@ -0,0 +1 @@ +export const isScriptNamePattern = /^[\w-]+$/; diff --git a/tests/__snapshots__/help.spec.ts.snap b/tests/__snapshots__/help.spec.ts.snap new file mode 100644 index 0000000..be127db --- /dev/null +++ b/tests/__snapshots__/help.spec.ts.snap @@ -0,0 +1,215 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`help customization 1`] = ` +"USAGE: + esbuild [options...] [entry points] + +DOCUMENTATION: + https://esbuild.github.io/ + +SIMPLE OPTIONS: + --bundle Bundle all dependencies into the output files + --define=... Substitute K with V while parsing + +ADVANCED OPTIONS: + --allow-overwrite Allow output files to overwrite input files + --asset-names Path template to use for \\"file\\" loader files (default + \\"[name]-[hash]\\") + +EXAMPLES: + # Produces dist/entry_point.js and dist/entry_point.js.map + esbuild --bundle entry_point.js --outdir=dist --minify --sourcemap + +Received value: 123" +`; + +exports[`show help command help 1`] = ` +"my-cli test + +test command + +USAGE: + my-cli test [flags...] + +FLAGS: + -h, --help Show help +" +`; + +exports[`show help commands 1`] = ` +"my-cli + +USAGE: + my-cli [flags...] + my-cli + +COMMANDS: + test + +FLAGS: + -h, --help Show help +" +`; + +exports[`show help commands with description 1`] = ` +"my-cli + +USAGE: + my-cli [flags...] + my-cli + +COMMANDS: + test test command + +FLAGS: + -h, --help Show help +" +`; + +exports[`show help empty cli 1`] = ` +"FLAGS: + -h, --help Show help +" +`; + +exports[`show help empty commands 1`] = ` +"FLAGS: + -h, --help Show help +" +`; + +exports[`show help empty flags 1`] = ` +"FLAGS: + -h, --help Show help +" +`; + +exports[`show help empty help.examples 1`] = ` +"FLAGS: + -h, --help Show help +" +`; + +exports[`show help empty parameters 1`] = ` +"FLAGS: + -h, --help Show help +" +`; + +exports[`show help flags 1`] = ` +"FLAGS: + --flag + --flag-a + --flag-b + --flag-c (default: {}) + -h, --help Show help +" +`; + +exports[`show help help disabled but shown 1`] = ` +"my-cli v1.2.3 +" +`; + +exports[`show help help.description 1`] = ` +"test description + +FLAGS: + -h, --help Show help +" +`; + +exports[`show help help.usage array 1`] = ` +"USAGE: + usage string a + usage string b + usage string c + +FLAGS: + -h, --help Show help +" +`; + +exports[`show help help.usage string 1`] = ` +"USAGE: + usage string + +FLAGS: + -h, --help Show help +" +`; + +exports[`show help help.version with --help 1`] = ` +"v1.0.0 + +FLAGS: + -h, --help Show help +" +`; + +exports[`show help name 1`] = ` +"npm + +USAGE: + npm [flags...] + +FLAGS: + -h, --help Show help +" +`; + +exports[`show help parameters with name 1`] = ` +"my-cli + +USAGE: + my-cli [flags...] [arg-b] + +FLAGS: + -h, --help Show help +" +`; + +exports[`show help parameters with no name 1`] = ` +"FLAGS: + -h, --help Show help +" +`; + +exports[`show help undefined flags 1`] = ` +"FLAGS: + -h, --help Show help +" +`; + +exports[`show version 1`] = `"1.0.0"`; + +exports[`smoke test 1`] = ` +"my-cli v1.1.1 + +USAGE: + my-cli [flags...] + my-cli + +COMMANDS: + my-command my command description + +FLAGS: + -d, --dark-mode Show tweet in dark mode + -h, --help Show help + --locale Locale (default: \\"en\\") + -o, --output-dir Tweet screenshot output directory + -t, --show-tweet Show tweet thread + --version Show version + -w, --width Width of tweet (default: 550) + +EXAMPLES: + # Snapshot a tweet + snap-tweet https://twitter.com/jack/status/20 + + # Snapshot a tweet with Japanese locale + snap-tweet https://twitter.com/TwitterJP/status/578707432 --locale ja + + # Snapshot a tweet with dark mode and 900px width + snap-tweet https://twitter.com/Interior/status/463440424141459456 --width 900 --dark-mode +" +`; diff --git a/tests/arguments.spec.ts b/tests/arguments.spec.ts new file mode 100644 index 0000000..3e98ef2 --- /dev/null +++ b/tests/arguments.spec.ts @@ -0,0 +1,178 @@ +import { cli, command } from '../src'; + +describe('error handling', () => { + describe('parameters', () => { + test('invalid parameter format', () => { + expect(() => { + const parsed = cli( + { + parameters: ['value-a'], + }, + ); + + expect(parsed._).toStrictEqual([]); + }).toThrow('Invalid parameter: "value-a". Must be wrapped in <> (required parameter) or [] (optional parameter)'); + }); + + test('invalid parameter character', () => { + expect(() => { + const parsed = cli( + { + parameters: ['[value.a]'], + }, + ); + + expect(parsed._).toStrictEqual([]); + }).toThrow('Invalid parameter: "[value.a]". Invalid character found "."'); + }); + + test('optional parameter before required parameter', () => { + expect(() => { + const parsed = cli( + { + parameters: ['[value-a]', ''], + }, + ); + + expect(parsed._).toStrictEqual([]); + }).toThrow('Invalid parameter: Required parameter "" cannot come after optional parameter "[value-a]"'); + }); + + test('multiple spread not last', () => { + expect(() => { + const parsed = cli( + { + parameters: ['[value-a...]', ''], + }, + ); + + expect(parsed._).toStrictEqual([]); + }).toThrow('Invalid parameter: Spread parameter "[value-a...]" must be last'); + }); + + test('multiple spread parameters', () => { + expect(() => { + const parsed = cli( + { + parameters: ['[value-a...]', ''], + }, + ); + + expect(parsed._).toStrictEqual([]); + }).toThrow('Invalid parameter: Spread parameter "[value-a...]" must be last'); + }); + }); + + describe('arguments', () => { + let mockProcessExit: jest.SpyInstance; + let mockConsoleError: jest.SpyInstance; + let mockConsoleLog: jest.SpyInstance; + + beforeEach(() => { + mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); + mockConsoleError = jest.spyOn(console, 'error').mockImplementation(); + mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + }); + + afterEach(() => { + mockProcessExit.mockRestore(); + mockConsoleError.mockRestore(); + mockConsoleLog.mockRestore(); + }); + + test('missing parameter', () => { + cli( + { + parameters: [''], + }, + undefined, + [], + ); + + expect(mockConsoleError).toHaveBeenCalledWith('Error: Missing required parameter "value-a"\n'); + expect(mockProcessExit).toHaveBeenCalledWith(1); + }); + + test('missing spread parameter', () => { + cli( + { + parameters: [''], + }, + undefined, + [], + ); + + expect(mockConsoleError).toHaveBeenCalledWith('Error: Missing required parameter "value-a"\n'); + expect(mockProcessExit).toHaveBeenCalledWith(1); + }); + }); +}); + +describe('parses arguments', () => { + test('simple parsing', () => { + const callback = jest.fn(); + const parsed = cli( + { + parameters: ['', '[value-B]', '[value c]'], + }, + (callbackParsed) => { + expect(callbackParsed._.valueA).toBe('valueA'); + expect(callbackParsed._.valueB).toBe('valueB'); + expect(callbackParsed._.valueC).toBe('valueC'); + callback(); + }, + ['valueA', 'valueB', 'valueC'], + ); + + expect(parsed._.valueA).toBe('valueA'); + expect(parsed._.valueB).toBe('valueB'); + expect(parsed._.valueC).toBe('valueC'); + expect(callback).toHaveBeenCalled(); + }); + + test('spread', () => { + const callback = jest.fn(); + const parsed = cli( + { + parameters: [''], + }, + (callbackParsed) => { + expect(callbackParsed._.valueA).toStrictEqual(['valueA', 'valueB']); + callback(); + }, + ['valueA', 'valueB'], + ); + + expect(parsed._.valueA).toStrictEqual(['valueA', 'valueB']); + expect(callback).toHaveBeenCalled(); + }); + + test('command', () => { + const callback = jest.fn(); + + const testCommand = command({ + name: 'test', + parameters: [''], + }, (callbackParsed) => { + expect(callbackParsed._.argA).toStrictEqual(['valueA', 'valueB']); + callback(); + }); + + const parsed = cli( + { + parameters: [''], + + commands: [ + testCommand, + ], + }, + undefined, + ['test', 'valueA', 'valueB'], + ); + + if (parsed.command === 'test') { + expect(parsed._.argA).toStrictEqual(['valueA', 'valueB']); + } + expect(callback).toHaveBeenCalled(); + }); +}); diff --git a/tests/cli.spec.ts b/tests/cli.spec.ts new file mode 100644 index 0000000..77c2be3 --- /dev/null +++ b/tests/cli.spec.ts @@ -0,0 +1,26 @@ +import { cli } from '../src'; + +describe('error-handling', () => { + test('must pass in options', () => { + expect(() => { + // @ts-expect-error no options + cli(); + }).toThrow('Options is required'); + }); + + test('missing name', () => { + expect(() => { + cli({ + name: '', + }); + }).toThrow('Invalid script name: ""'); + }); + + test('invalid name format', () => { + expect(() => { + cli({ + name: 'a b', + }); + }).toThrow('Invalid script name: "a b"'); + }); +}); diff --git a/tests/command.spec.ts b/tests/command.spec.ts new file mode 100644 index 0000000..a8c85a7 --- /dev/null +++ b/tests/command.spec.ts @@ -0,0 +1,266 @@ +import { cli, command } from '../src'; + +describe('error handling', () => { + test('missing options', () => { + expect(() => { + // @ts-expect-error no options + command(); + }).toThrow('Command options are required'); + }); + + test('missing command name', () => { + expect(() => { + // @ts-expect-error no name + command({}); + }).toThrow('Command name is required'); + }); + + test('empty command name', () => { + expect(() => { + command({ + name: '', + }); + }).toThrow('Invalid command name ""'); + }); + + test('invalid command name', () => { + expect(() => { + command({ + name: 'a b c', + }); + }).toThrow('Invalid command name "a b c". Command names must be one word.'); + }); + + test('duplicate command name', () => { + expect(() => { + cli( + { + commands: [ + command({ + name: 'duplicate', + }), + command({ + name: 'duplicate', + }), + ], + }, + undefined, + ['commandA', '--flagA', 'valueA'], + ); + }).toThrow('Duplicate command name found: "duplicate"'); + }); + + test('duplicate command alias', () => { + expect(() => { + cli( + { + commands: [ + command({ + name: 'duplicate', + }), + command({ + name: 'command', + alias: 'duplicate', + }), + ], + }, + undefined, + ['commandA', '--flagA', 'valueA'], + ); + }).toThrow('Duplicate command name found: "duplicate"'); + }); +}); + +describe('command', () => { + test('invoking command', () => { + const callback = jest.fn(); + + const commandA = command({ + name: 'commandA', + flags: { + flagA: String, + }, + }, (parsed) => { + expect(parsed.flags.flagA); + expect(parsed.flags.help); + callback(); + }); + + const parsed = cli( + { + commands: [ + commandA, + ], + }, + undefined, + ['commandA', '--flagA', 'valueA'], + ); + + expect(parsed.command).toBe('commandA'); + + // Narrow type + if (parsed.command === 'commandA') { + expect(parsed.flags.flagA).toBe('valueA'); + + // @ts-expect-error non exixtent property + expect(parsed.flags.flagC); + } + + expect(callback).toHaveBeenCalled(); + }); + + test('invoking command via alias', () => { + const callback = jest.fn(); + + const commandA = command({ + name: 'commandA', + + alias: 'a', + + flags: { + flagA: String, + }, + }, (parsed) => { + expect(parsed.flags.flagA); + expect(parsed.flags.help); + callback(); + }); + + const parsed = cli( + { + commands: [ + commandA, + ], + }, + undefined, + ['a', '--flagA', 'valueA'], + ); + + expect(parsed.command).toBe('commandA'); + + // Narrow type + if (parsed.command === 'commandA') { + expect(parsed.flags.flagA).toBe('valueA'); + + // @ts-expect-error non exixtent property + expect(parsed.flags.flagC); + } + + expect(callback).toHaveBeenCalled(); + }); + + test('invoking command via alias array', () => { + const callback = jest.fn(); + + const commandA = command({ + name: 'commandA', + + alias: ['a', 'b'], + + flags: { + flagA: String, + }, + }, (parsed) => { + expect(parsed.flags.flagA); + expect(parsed.flags.help); + callback(); + }); + + const parsed = cli( + { + commands: [ + commandA, + ], + }, + undefined, + ['b', '--flagA', 'valueA'], + ); + + expect(parsed.command).toBe('commandA'); + + // Narrow type + if (parsed.command === 'commandA') { + expect(parsed.flags.flagA).toBe('valueA'); + + // @ts-expect-error non exixtent property + expect(parsed.flags.flagC); + } + + expect(callback).toHaveBeenCalled(); + }); + + test('smoke', () => { + const callback = jest.fn(); + + const commandA = command({ + name: 'commandA', + flags: { + flagA: String, + }, + }, (parsed) => { + expect(parsed.flags.flagA); + expect(parsed.flags.help); + }); + + const commandB = command({ + name: 'commandB', + version: '1.0.0', + parameters: ['', '[cmd-B]'], + flags: { + flagB: { + type: String, + default: 'true', + }, + }, + }, (parsed) => { + expect(parsed.flags.flagB); + expect(parsed.flags.help); + }); + + const argv = cli( + { + version: '1.0.0', + + parameters: ['[parsed-A]', '[valueB]'], + + flags: { + flagC: Number, + }, + + commands: [ + commandA, + commandB, + ], + }, + (parsed) => { + expect(parsed.flags.version); + expect(parsed.flags.help); + expect(parsed.flags.flagC); + callback(); + }, + ['--flagA', 'valueA', '--flagB', '123'], + ); + + if (argv.command === undefined) { + expect(argv.flags.flagC); + expect(argv._.parsedA); + expect(argv._.valueB); + } + + if (argv.command === 'commandA') { + expect(argv.flags.flagA); + + // @ts-expect-error non exixtent property + expect(argv.flags.flagC); + } + + if (argv.command === 'commandB') { + expect(argv.flags.flagB); + expect(argv.flags.version); + expect(argv._.cmdA); + expect(argv._.cmdB); + } + + expect(callback).toHaveBeenCalled(); + }); +}); diff --git a/tests/flags.spec.ts b/tests/flags.spec.ts new file mode 100644 index 0000000..f2ff46a --- /dev/null +++ b/tests/flags.spec.ts @@ -0,0 +1,135 @@ +import { cli } from '../src'; + +describe('flags', () => { + test('has return type & callback', () => { + const callback = jest.fn(); + const argv = cli( + { + parameters: ['', '[value-B]'], + flags: { + flagA: String, + flagB: { + type: Number, + }, + }, + }, + (parsed) => { + expect(parsed.flags.flagA).toBe('valueA'); + expect(parsed.flags.flagB).toBe(123); + callback(); + }, + ['--flagA', 'valueA', '--flagB', '123', 'valueA', 'valueB'], + ); + + if (!argv.command) { + expect(argv._.valueA).toBe('valueA'); + expect(argv._.valueB).toBe('valueB'); + expect(argv.flags.flagA).toBe('valueA'); + expect(argv.flags.flagB).toBe(123); + expect(callback).toHaveBeenCalled(); + } + }); + + describe('vearsion', () => { + test('disabled', () => { + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + const mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); + + const parsed = cli( + {}, + (p) => { + expect<{ + version?: undefined; + help: boolean | undefined; + }>(p.flags).toEqual({}); + }, + ['--version'], + ); + + expect(mockConsoleLog).not.toHaveBeenCalled(); + expect(mockProcessExit).not.toHaveBeenCalled(); + expect<{ + version?: undefined; + help: boolean | undefined; + }>(parsed.flags).toEqual({}); + + mockConsoleLog.mockRestore(); + mockProcessExit.mockRestore(); + }); + + test('enabled', () => { + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + const mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); + + cli( + { + version: '1.0.0', + flags: { + flagA: String, + }, + }, + ({ flags }) => { + expect(flags.version).toBe(true); + }, + ['--version'], + ); + + expect(mockConsoleLog).toHaveBeenCalled(); + expect(mockProcessExit).toHaveBeenCalledWith(0); + + mockConsoleLog.mockRestore(); + mockProcessExit.mockRestore(); + }); + }); + + describe('help', () => { + test('disabled', () => { + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + const mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); + + const parsed = cli( + { + help: false, + }, + (p) => { + expect<{ + help?: undefined; + }>(p.flags).toEqual({}); + }, + ['--help'], + ); + + expect(mockConsoleLog).not.toHaveBeenCalled(); + expect(mockProcessExit).not.toHaveBeenCalled(); + expect<{ + help?: undefined; + }>(parsed.flags).toEqual({}); + + mockConsoleLog.mockRestore(); + mockProcessExit.mockRestore(); + }); + + test('enabled', () => { + const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + const mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); + + cli( + { + flags: { + flagA: String, + }, + }, + ({ flags }) => { + expect(flags.help).toBe(true); + }, + ['--help'], + ); + + expect(mockConsoleLog).toHaveBeenCalled(); + expect(mockProcessExit).toHaveBeenCalledWith(0); + + mockConsoleLog.mockRestore(); + mockProcessExit.mockRestore(); + }); + }); +}); diff --git a/tests/help.spec.ts b/tests/help.spec.ts new file mode 100644 index 0000000..fefd337 --- /dev/null +++ b/tests/help.spec.ts @@ -0,0 +1,599 @@ +import { underline } from 'colorette'; +import { cli, command } from '../src'; + +let mockProcessExit: jest.SpyInstance; +let mockConsoleLog: jest.SpyInstance; + +beforeAll(() => { + process.stdout.columns = 90; + mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(); +}); + +beforeEach(() => { + mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(); + + mockProcessExit.mockClear(); +}); + +afterEach(() => { + mockConsoleLog.mockRestore(); +}); + +describe('show help', () => { + test('empty cli', () => { + cli( + {}, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('name', () => { + cli( + { + name: 'npm', + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('empty parameters', () => { + cli( + { + parameters: [], + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('parameters with no name', () => { + cli( + { + parameters: ['', '[arg-b]'], + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('parameters with name', () => { + cli( + { + name: 'my-cli', + parameters: ['', '[arg-b]'], + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('empty commands', () => { + cli( + { + commands: [], + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('commands', () => { + const testCommand = command({ + name: 'test', + }); + + cli( + { + name: 'my-cli', + commands: [ + testCommand, + ], + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('commands with description', () => { + const testCommand = command({ + name: 'test', + help: { + description: 'test command', + }, + }); + + cli( + { + name: 'my-cli', + commands: [ + testCommand, + ], + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('undefined flags', () => { + cli( + { + flags: undefined, + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('empty flags', () => { + cli( + { + flags: {}, + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('flags', () => { + cli( + { + flags: { + flag: Boolean, + flagA: String, + flagB: { + type: Number, + }, + flagC: { + type: RegExp, + default: /hello/, + }, + }, + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('help disabled', () => { + cli( + { + help: false, + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).not.toHaveBeenCalled(); + }); + + test('help disabled but shown', () => { + const argv = cli( + { + name: 'my-cli', + help: false, + }, + undefined, + ['--help'], + ); + + argv.showHelp({ + version: '1.2.3', + }); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('empty help.examples', () => { + cli( + { + help: { + examples: [], + }, + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('help.version with --help', () => { + cli( + { + help: { + version: '1.0.0', + }, + }, + undefined, + ['--help'], + ); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('help.version with --version', () => { + const parsed = cli( + { + help: { + version: '1.0.0', + }, + }, + undefined, + ['--version'], + ); + + expect(mockProcessExit).not.toHaveBeenCalled(); + + expect(parsed.unknownFlags).toStrictEqual({ + version: [true], + }); + }); + + test('help.usage string', () => { + cli( + { + help: { + usage: 'usage string', + }, + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('help.usage array', () => { + cli( + { + help: { + usage: [ + 'usage string a', + 'usage string b', + 'usage string c', + ], + }, + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('help.description', () => { + cli( + { + help: { + description: 'test description', + }, + }, + undefined, + ['--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('command help', () => { + const testCommand = command({ + name: 'test', + parameters: ['', ''], + help: { + description: 'test command', + }, + }); + + cli( + { + name: 'my-cli', + commands: [ + testCommand, + ], + }, + undefined, + ['test', '--help'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); + }); + + test('command help disabled', () => { + const testCommand = command({ + name: 'test', + help: false, + }); + + cli( + { + name: 'my-cli', + commands: [ + testCommand, + ], + }, + undefined, + ['test', '--help'], + ); + + expect(mockProcessExit).not.toHaveBeenCalled(); + }); +}); + +test('show version', () => { + cli( + { + version: '1.0.0', + }, + undefined, + ['--version'], + ); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); +}); + +test('smoke test', () => { + cli({ + name: 'my-cli', + + version: '1.1.1', + + commands: [ + command({ + name: 'my-command', + help: { + description: 'my command description', + }, + }), + ], + + parameters: [''], + + flags: { + outputDir: { + type: String, + alias: 'o', + description: 'Tweet screenshot output directory', + placeholder: '', + }, + width: { + type: Number, + alias: 'w', + description: 'Width of tweet', + default: 550, + placeholder: '', + }, + showTweet: { + type: Boolean, + alias: 't', + description: 'Show tweet thread', + }, + darkMode: { + type: Boolean, + alias: 'd', + description: 'Show tweet in dark mode', + }, + locale: { + type: String, + description: 'Locale', + default: 'en', + placeholder: '', + }, + }, + + help: { + examples: [ + '# Snapshot a tweet', + 'snap-tweet https://twitter.com/jack/status/20', + '', + '# Snapshot a tweet with Japanese locale', + 'snap-tweet https://twitter.com/TwitterJP/status/578707432 --locale ja', + '', + '# Snapshot a tweet with dark mode and 900px width', + 'snap-tweet https://twitter.com/Interior/status/463440424141459456 --width 900 --dark-mode', + ], + }, + }, undefined, ['--help']); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); +}); + +test('help customization', () => { + const simpleFlags = { + bundle: { + type: Boolean, + description: 'Bundle all dependencies into the output files', + }, + define: { + type: String, + description: 'Substitute K with V while parsing', + }, + }; + + const advancedFlags = { + allowOverwrite: { + type: Boolean, + description: 'Allow output files to overwrite input files', + }, + assetNames: { + type: Boolean, + description: 'Path template to use for "file" loader files (default "[name]-[hash]")', + }, + }; + + cli({ + name: 'esbuild', + + version: '1.0.0', + + parameters: ['[entry points]'], + + flags: { + ...simpleFlags, + ...advancedFlags, + + // Overwrite to remove alias + help: Boolean, + }, + + help: { + examples: [ + '# Produces dist/entry_point.js and dist/entry_point.js.map', + 'esbuild --bundle entry_point.js --outdir=dist --minify --sourcemap', + ], + + render(nodes, renderers) { + // Remove name + nodes.splice(0, 1); + + // Replace "flags" with "options" in Usage + nodes[0].data.body = nodes[0].data.body.replace('flags', 'options'); + + // Add Documentation & Repository + nodes.splice(1, 0, { + type: 'section', + data: { + title: 'Documentation:', + body: underline('https://esbuild.github.io/'), + }, + }); + + // Split Flags into "Simple options" and "Advanced options" + const flags = nodes[2].data.body.data; + nodes.splice(2, 1, { + type: 'section', + data: { + title: 'Simple options:', + body: { + type: 'table', + data: { + ...flags, + tableData: flags.tableData.filter( + ([flagName]: [{ data: { name: string }}]) => flagName.data.name in simpleFlags, + ), + }, + }, + indentBody: 0, + }, + }, { + type: 'section', + data: { + title: 'Advanced options:', + body: { + type: 'table', + data: { + ...flags, + tableData: flags.tableData.filter( + ([flagName]: [{ data: { name: string }}]) => flagName.data.name in advancedFlags, + ), + }, + }, + indentBody: 0, + }, + }); + + // Update renderer so flags that accept a value shows `=...` + renderers.flagOperator = () => '='; + renderers.flagParameter = flagType => (flagType === Boolean ? '' : '...'); + + const extendedRenderer = Object.assign(renderers, { + someRenderer(value: number) { + return `Received value: ${value}`; + }, + }); + + return extendedRenderer.render([ + ...nodes, + { + type: 'someRenderer', + data: 123, + }, + ]); + }, + }, + }, undefined, ['--help']); + + expect(mockProcessExit).toHaveBeenCalledWith(0); + + const { calls } = mockConsoleLog.mock; + expect(calls[0][0]).toMatchSnapshot(); +}); diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 0000000..d8e40f5 --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "..", + "include": ["."] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..62e35f2 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "isolatedModules": true, + "esModuleInterop": true, + "strict": true, + "declaration": true, + "outDir": "dist", + + // Node 12 + "lib": ["ES2019"], + "module": "commonjs", + "target": "ES2019", + }, + "include": [ + "src", + ], +}