diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..49dd2b7 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,8 @@ +!.* + +/build/** +/coverage/** +/dist/** +/test/** +/node_modules/** +!.eslintrc.json diff --git a/. eslintrc b/.eslintrc.json similarity index 78% rename from . eslintrc rename to .eslintrc.json index 8b9e49a..4817b1e 100644 --- a/. eslintrc +++ b/.eslintrc.json @@ -1,17 +1,15 @@ { "env": { - "browser": true, - "commonjs": true, - "es8": true, + "es6": true, "node": true }, + "extends": ["plugin:import/recommended"], + "parser": "@babel/eslint-parser", "parserOptions": { - "ecmaVersion": 2020, + "ecmaVersion": 2018, "sourceType": "module" }, - "extends": [ - "plugin:node/recommended" - ], + "plugins": ["import"], "rules": { "camelcase": [1, {"properties": "always"}], "comma-dangle": 0, @@ -24,7 +22,6 @@ "key-spacing": [2, {"beforeColon": false, "afterColon": true}], "keyword-spacing": 2, "linebreak-style": 0, - "node/file-extension-in-import": ["error", "never"], "no-console": 0, "no-irregular-whitespace": 2, "no-multi-str": 2, @@ -35,10 +32,10 @@ "no-unused-vars": 2, "no-use-before-define": [2, "nofunc"], "operator-linebreak": [2, "after"], - "quotes": [2, "single"], + "quotes": [2, "double"], "semi": [2, "always"], "space-before-blocks": [2, "always"], - "space-before-function-paren": [2, "always"], + "space-before-function-paren": [2, "never"], "space-infix-ops": 2, "strict": [2, "global"], "wrap-iife": [2, "inside"] diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e8ee096 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,10 @@ +# +# Main entry file needs lf only line endings so that bash shell doesn't barf. +# +src/bin/index.js text eol=lf +# +# Avoid crlf translation noise on npm written files +# +package.json text eol=lf +package-lock.json text eol=lf + diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 8a533f2..66375c6 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,11 +1,9 @@ # Contributing Thank you so much for wanting to contribute to the Password Generator! There are a couple ways to help out. - ## Evangelize Just tell people about the Password Generator. We believe that a bigger, more involved community makes for a better framework, and that better frameworks make the world a better place. We can always use more feedback. - ## How to Contribute Here are guides for submitting issues and pull requests. @@ -25,7 +23,6 @@ Warning us of a bug is possibly the single most valuable contribution you can ma ### Code Contributions Contributing code is one of the more difficult ways to contribute to the Password Generator. - #### Feature Requests Filing feature requests is one of the most popular ways to contribute to the Password Generator. @@ -33,7 +30,6 @@ Filing feature requests is one of the most popular ways to contribute to the Pas Is there some feature request that you'd like to code up yourself? Is there a feature you asked for yourself that you'd like to code? Here's how to contribute code for a new feature to the Password Generator. Pull Requests allow you to share your own code with us, and we can merge it into the main repo. - #### Adding Code - Fork the repo. @@ -41,7 +37,6 @@ Here's how to contribute code for a new feature to the Password Generator. Pull - Install Node.js if you haven't already, and run `npm install`. This installs the required dependencies for building the Password Generator. - Edit files in the `src/` folder. Don't edit any files in the `dist/` folder, this is only for distribution builds, which are automated. - Run `npm run build` to trigger builds, and the new distribution files will be in the `dist/` folder ready to go. - #### Fixing an Issue Have you found a solution to an issue? Here is how you can submit your code to the Password Generator. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug-report.md similarity index 57% rename from .github/ISSUE_TEMPLATE/bug_report.md rename to .github/ISSUE_TEMPLATE/bug-report.md index 5b301c6..7cd7e9c 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,10 +1,5 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' ---- +# Bug report +Create a report to help us improve ## Describe the bug @@ -14,10 +9,10 @@ A clear and concise description of what the bug is. Steps to reproduce the behavior: -- Go to '...' -- Click on '....' -- Scroll down to '....' -- See error +- Go to '...' +- Click on '....' +- Scroll down to '....' +- See error ## Expected behavior @@ -28,15 +23,15 @@ A clear and concise description of what you expected to happen. If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] +- OS +- Browser +- Version **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] +- Device +- OS +- Browser +- Version **Additional context** Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature-request.md similarity index 66% rename from .github/ISSUE_TEMPLATE/feature_request.md rename to .github/ISSUE_TEMPLATE/feature-request.md index bbcbbe7..6c46e1c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,20 +1,19 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' +# Feature request ---- +Suggest an idea for this project **Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +A clear and concise description of what the problem is. **Describe the solution you'd like** + A clear and concise description of what you want to happen. **Describe alternatives you've considered** + A clear and concise description of any alternative solutions or features you've considered. **Additional context** + Add any other context or screenshots about the feature request here. diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 7ee1af5..6e6227b 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -3,7 +3,6 @@ We take the security of our software products and services seriously, which includes all source code repositories managed through our GitHub repositories. If you believe you have found a security vulnerability in any of our repository, please report it to us as described below. - ## Reporting Security Issues Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 98d9de4..7183094 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,16 @@ +# +# ___ _ ___ _ +# | _ \__ _ _______ __ _____ _ _ __| | / __|___ _ _ ___ _ _ __ _| |_ ___ _ _ +# | _/ _` (_-<_-< V V / _ \ '_/ _` | | (_ / -_) ' \/ -_) '_/ _` | _/ _ \ '_| +# |_| \__,_/__/__/\_/\_/\___/_| \__,_| \___\___|_||_\___|_| \__,_|\__\___/_| +# +# Password Generator +# https://password-generator.pro/ +# +# Copyright (c) Sebastien Rousseau 2022. All rights reserved +# Licensed under the MIT license +# + version: 2 updates: - package-ecosystem: "npm" diff --git a/.gitignore b/.gitignore index c226d40..7110878 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,16 @@ coverage # Bower dependency directory (https://bower.io/) bower_components +# Mocha-specific +mocha.js +mocha.js.map +.karma/ +!bin/mocha.js +!lib/mocha.js + +# Bundle debugging +stats.html + # node-waf configuration .lock-wscript diff --git a/.npmignore b/.npmignore deleted file mode 100644 index f26cba1..0000000 --- a/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -*.* -!dist/* diff --git a/.remarkrc.json b/.remarkrc.json new file mode 100644 index 0000000..415fc06 --- /dev/null +++ b/.remarkrc.json @@ -0,0 +1,18 @@ +{ + "plugins": [ + "remark-preset-lint-recommended", + "remark-preset-lint-markdown-style-guide", + "remark-preset-lint-consistent", + ["remark-lint-list-item-spacing", false], + ["remark-lint-maximum-heading-length", false], + ["remark-lint-list-item-indent", false], + ["remark-lint-maximum-line-length", false], + [ + "remark-lint-fenced-code-flag", + { + "allowEmpty": true + } + ], + "validate-links" + ] +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1ce0106 --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +install: install-deps + +run: + npx babel-node 'src/bin/password-generator.js' production + +dev: + npx nodemon --delay 1 --exec babel-node 'src/bin/password-generator.js' developer + +install-deps: + npm ci + +build: + rm -rf dist + npm run build + +test: + npm test + +test-coverage: + nyc npm run test + +lint: + npx eslint . + +package: + npm pack + +publish: + npm publish + +update-deps: + npx npm-check-updates -u diff --git a/README.md b/README.md index 81293c0..df29c43 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# Password Generator +# Password Generator Tool -![Banner representing the Password Generator Library](https://raw.githubusercontent.com/sebastienrousseau/password-generator/master/images/password-generator-logo.svg) +![Banner representing the Password Generator Tool](https://raw.githubusercontent.com/sebastienrousseau/password-generator/master/images/password-generator-logo.svg) -A fast, simple and powerful utility library for generating unique passwords to streamline your digital and mobile web development needs. +A fast, simple and powerful open-source utility tool for generating strong, unique and random passwords. Password Generator is free to use as a secure password generator on any computer, phone, or tablet. [![Getting Started](https://raw.githubusercontent.com/sebastienrousseau/password-generator/master/images/button-primary.svg)](#installation) -[![Download the Password Generator Library v1.0.3](https://raw.githubusercontent.com/sebastienrousseau/password-generator/master/images/button-secondary.svg)](https://github.com/sebastienrousseau/password-generator/archive/refs/tags/1.0.4.zip) +[![Download the Password Generator Tool v1.0.5](https://raw.githubusercontent.com/sebastienrousseau/password-generator/master/images/button-secondary.svg)](https://github.com/sebastienrousseau/password-generator/archive/refs/tags/1.0.5.zip) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/0acb169c95e443729551979e0fd86eaf)](https://www.codacy.com?utm_source=github.com&utm_medium=referral&utm_content=sebastienrousseau/password-generator&utm_campaign=Badge_Grade) [![npm](https://img.shields.io/npm/v/@sebastienrousseau/password-generator.svg?style=flat&color=success)](https://www.npmjs.com/package/@sebastienrousseau/password-generator) @@ -14,35 +14,11 @@ A fast, simple and powerful utility library for generating unique passwords to s [![License: MIT](https://img.shields.io/badge/License-MIT-success.svg?style=flat)](https://opensource.org/licenses/MIT) [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fsebastienrousseau%2Fpassword-generator.svg?type=small)](https://app.fossa.com/projects/git%2Bgithub.com%2Fsebastienrousseau%2Fpassword-generator?ref=badge_small) -## Table of Contents - -- [Password Generator](#password-generator) - - [Table of Contents](#table-of-contents) - - [Installation](#installation) - - [From NPM or YARN](#from-npm-or-yarn) - - [From GitHub](#from-github) - - [What's included](#whats-included) - - [Usage](#usage) - - [From the CLI](#from-the-cli) - - [From Node.js](#from-nodejs) - - [From the Browser](#from-the-browser) - - [Password options](#password-options) - - [Generating a random base64 password](#generating-a-random-base64-password) - - [Generating a strong password](#generating-a-strong-password) - - [Generating a memorable password](#generating-a-memorable-password) - - [Versioning](#versioning) - - [Contributing](#contributing) - - [Code of Conduct](#code-of-conduct) - - [Our Values](#our-values) - - [Releases](#releases) - - [License](#license) - - [Acknowledgements](#acknowledgements) - -## Installation +## 🔧 Installation ### From NPM or YARN -To install the Password Generator, use either npm or yarn as follows: +To install the Password Generator Tool, use either npm or yarn as follows: - `npm i @sebastienrousseau/password-generator` - `yarn add @sebastienrousseau/password-generator` @@ -51,66 +27,80 @@ To install the Password Generator, use either npm or yarn as follows: Clone the main repository to get all source files including build scripts: `git clone https://github.com/sebastienrousseau/password-generator.git` -## What's included +## ✒️ What's included Within the download you'll find all the password generator source files grouped into the _dist_ folder. You'll see something like this: -```bash +```shell . ├── COPYRIGHT ├── LICENSE +├── Makefile ├── README.md -├── bin -│   └── password-generator.js +├── babel.config.js ├── bower.json -├── dictionaries -│   ├── adjectives.json -│   ├── adverbs.json -│   ├── animals.json -│   ├── cars.json -│   ├── cities.json -│   ├── common.json -│   ├── countries.json -│   ├── dinosaurs.json -│   ├── emoji.json -│   ├── encouraging.json -│   ├── ergative.json -│   ├── fruits.json -│   ├── gemstones.json -│   ├── hazards.json -│   ├── instruments.json -│   ├── lovecraft.json -│   ├── metals.json -│   ├── music.json -│   ├── nouns.json -│   ├── prepositions.json -│   ├── shakespeare.json -│   ├── sports.json -│   ├── strange.json -│   ├── vegetables.json -│   └── winds.json -├── dist -├── lib -│   ├── base64-password.js -│   ├── complex-password.js -│   ├── memorable-password.js -│   └── title-case.js ├── package-lock.json ├── package.json -└── test - └── test-title-case.js - -5 directories, 37 files +└── src + ├── bin + │   └── index.js + ├── dictionaries + │   ├── adjectives.json + │   ├── adverbs.json + │   ├── animals.json + │   ├── cars.json + │   ├── cities.json + │   ├── common.json + │   ├── countries.json + │   ├── dinosaurs.json + │   ├── emoji.json + │   ├── encouraging.json + │   ├── ergative.json + │   ├── fruits.json + │   ├── gemstones.json + │   ├── hazards.json + │   ├── instruments.json + │   ├── lovecraft.json + │   ├── metals.json + │   ├── music.json + │   ├── nouns.json + │   ├── prepositions.json + │   ├── shakespeare.json + │   ├── sports.json + │   ├── strange.json + │   ├── vegetables.json + │   └── winds.json + ├── images + │   ├── button-primary.svg + │   ├── button-secondary.svg + │   └── password-generator-logo.svg + ├── lib + │   ├── base64-password.js + │   ├── complex-password.js + │   ├── memorable-password.js + │   └── password-generator.js + └── utils + ├── README.md + ├── randomConsonant.js + ├── randomNumber.js + ├── randomSyllable.js + ├── randomVowel.js + ├── toCamelCase.js + ├── toKebabCase.js + ├── toSnakeCase.js + └── toTitleCase.js + +6 directories, 50 files ``` -## Usage +## 💿 Usage ### From the CLI ```shell -node ./bin/password-generator.js +node . ``` Displays the following help menu @@ -118,13 +108,15 @@ Displays the following help menu ```shell Usage: password-generator [options] +A fast, simple and powerful open-source utility tool for generating strong, unique and random passwords + Options: - \-V, --version output the version number - \-t, --type Specify a type (base64, complex, memorable) - \-l, --length Specify a length for each iteration - \-i, --iteration Specify a number of iteration - \-s, --separator Specify a character for the separator - \-h, --help display help for command + -v, --version output the current version + -t, --type specify a password type (default: "base64, complex or memorable") + -l, --length specify a length for each iteration + -i, --iteration specify a number of iteration + -s, --separator specify a character for the separator + -h, --help display help for command ``` ### From Node.js @@ -136,7 +128,7 @@ var generatePassword = require('password-generator'); ### From the Browser ```shell - + ``` ## Password options @@ -144,50 +136,56 @@ var generatePassword = require('password-generator'); ### Generating a random base64 password ```shell -node ./bin/password-generator.js -t base64 -l 8 -i 4 -s - +node . -t base64 -l 8 -i 4 -s - ``` ### Generating a strong password ```shell -node ./bin/password-generator.js -t complex -l 8 -i 4 -s - +node . -t complex -l 8 -i 4 -s - ``` ### Generating a memorable password ```shell -node ./bin/password-generator.js -t memorable -i 4 -s - +node . -t memorable -i 4 -s - ``` -## Versioning +## 🚥 Semantic Versioning Policy + +For transparency into our release cycle and in striving to maintain backward compatibility, `password-generator` follows [semantic versioning](http://semver.org/) and [ESLint's Semantic Versioning Policy](https://github.com/eslint/eslint#semantic-versioning-policy). + +## 📰 Changelog -For transparency into our release cycle and in striving to maintain backward compatibility, Password Generator is maintained under the [Semantic Versioning](https://semver.org/) guidelines. +- [GitHub Releases](https://github.com/sebastienrousseau/password-generator/releases) -## Contributing +## ❤️ Contributing Please read carefully through our [Contributing Guidelines](https://github.com/sebastienrousseau/password-generator/blob/master/.github/CONTRIBUTING.md) for further details on the process for submitting pull requests to us. -### Code of Conduct +Development Tools + +- `npm test` runs tests and measures coverage. +- `npm run coverage` shows the coverage result of npm test command. +- `npm run clean` removes the coverage result of npm test command. + +## 📖 Rules We are committed to preserving and fostering a diverse, welcoming community. Please read our [Code of Conduct](https://github.com/sebastienrousseau/password-generator/blob/master/.github/CODE-OF-CONDUCT.md). -### Our Values +## ⭐️ Our Values - We believe perfection must consider everything. - We take our passion beyond code into our daily practices. - We are just obsessed about creating and delivering exceptional solutions. -### Releases - -- See [Password Generator Release](https://github.com/sebastienrousseau/password-generator/releases) list. - ### License This project is licensed under the MIT License - see the [LICENSE](https://github.com/sebastienrousseau/password-generator/blob/master/LICENSE) file for details ### Acknowledgements -[The Password Generator Library](https://password-generator.pro) is beautifully crafted by these people and a bunch of awesome [contributors](https://github.com/sebastienrousseau/password-generator/graphs/contributors) +[The Password Generator Tool](https://password-generator.pro) is beautifully crafted by these people and a bunch of awesome [contributors](https://github.com/sebastienrousseau/password-generator/graphs/contributors) | Contributors | | ---------------------------------------------------------------------------------------------------------------- | diff --git a/babel.config.json b/babel.config.json new file mode 100644 index 0000000..394c543 --- /dev/null +++ b/babel.config.json @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "targets": { + "node": "current" + } + } + ] + ] +} diff --git a/bin/password-generator.js b/bin/password-generator.js deleted file mode 100644 index 9b1c385..0000000 --- a/bin/password-generator.js +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/*jshint esversion: 8 */ -import { base64Password } from "../lib/base64-password.js"; -import { Command as c } from "commander"; -import { complexPassword } from "../lib/complex-password.js"; -import { memorablePassword } from "../lib/memorable-password.js"; - -// Initializing Variables -const actions = { - base64: () => base64Password(), - complex: () => complexPassword(), - memorable: () => memorablePassword(), -}; -const args = process.argv.slice(2); -const bool = Object.prototype.hasOwnProperty.call(actions, args[1]); -const program = new c(); -(async () => { - program - .version("1.0.0") - .option("-t, --type ", "Specify a type (base64, complex, memorable)") - .option("-l, --length ", "Specify a length for each iteration") - .option("-i, --iteration ", "Specify a number of iteration") - .option("-s, --separator ", "Specify a character for the separator") - .parse(process.argv); - - if (bool) { - actions[args[1]](); - } else { - program.help(); - } -})(); diff --git a/lib/complex-password.js b/lib/complex-password.js deleted file mode 100644 index 62b4ba7..0000000 --- a/lib/complex-password.js +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/*jshint esversion: 8 */ - -import child_process from "child_process"; - -// Initializing Variables -const args = process.argv.slice(2); - -export async function complexPassword() { - // Runs a command in a shell and buffers the output. - child_process.exec( - // Generating a 256-bit cipher - "openssl rand -base64 256", - (err, stdout, stderr) => { - if (err) { - console.debug(`Exec: Fail to execute command`); - console.debug(err); - console.debug(stderr); - } - // Initializing a complex password - let complex = stdout.toString().match(new RegExp(`.{0,${args[3]}}`, "g")); - complex = complex.slice(0, args[5]).join(args[7]).toString(); - console.log(complex); - } - ); -} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 4c82fdf..0000000 --- a/package-lock.json +++ /dev/null @@ -1,2356 +0,0 @@ -{ - "name": "@sebastienrousseau/password-generator", - "version": "1.0.4", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "@sebastienrousseau/password-generator", - "version": "1.0.4", - "license": "MIT", - "dependencies": { - "commander": "^9.1.0" - }, - "bin": { - "password-generator": "bin/password-generator.js" - }, - "devDependencies": { - "chai": "^4.3.6", - "filesizes": "^0.1.2", - "jshint": "^2.13.4", - "mkdirp": "^1.0.4", - "mocha": "^9.2.2", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=12.22.0" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/cli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", - "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", - "dev": true, - "dependencies": { - "exit": "0.1.2", - "glob": "^7.1.1" - }, - "engines": { - "node": ">=0.2.5" - } - }, - "node_modules/cli-table": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz", - "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", - "dev": true, - "dependencies": { - "colors": "1.0.3" - }, - "engines": { - "node": ">= 0.2.0" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/commander": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz", - "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==", - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "dependencies": { - "date-now": "^0.1.4" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/dom-serializer/node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "node_modules/domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", - "dev": true, - "dependencies": { - "domelementtype": "1" - } - }, - "node_modules/domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/filesizes": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/filesizes/-/filesizes-0.1.2.tgz", - "integrity": "sha512-B7S28jvoR/mSmccYwh6jkZYvsmuXqULibMkT9rU4hYZfjHTk7bw8Zmygss9UNX49YbJirzvGb2MSh/CbSWKzzQ==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "cli-table": "^0.3.1", - "commander": "^4.1.1", - "gzip-size": "^5.1.1", - "pretty-bytes": "^5.3.0" - }, - "bin": { - "filesizes": "cli.js" - } - }, - "node_modules/filesizes/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/filesizes/node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", - "dev": true, - "dependencies": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", - "dev": true, - "dependencies": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jshint": { - "version": "2.13.4", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.4.tgz", - "integrity": "sha512-HO3bosL84b2qWqI0q+kpT/OpRJwo0R4ivgmxaO848+bo10rc50SkPnrtwSFXttW0ym4np8jbJvLwk5NziB7jIw==", - "dev": true, - "dependencies": { - "cli": "~1.0.0", - "console-browserify": "1.1.x", - "exit": "0.1.x", - "htmlparser2": "3.8.x", - "lodash": "~4.17.21", - "minimatch": "~3.0.2", - "strip-json-comments": "1.0.x" - }, - "bin": { - "jshint": "bin/jshint" - } - }, - "node_modules/jshint/node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/jshint/node_modules/strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", - "dev": true, - "bin": { - "strip-json-comments": "cli.js" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "4.2.1", - "ms": "2.1.3", - "nanoid": "3.3.1", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "chai": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", - "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "cli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", - "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", - "dev": true, - "requires": { - "exit": "0.1.2", - "glob": "^7.1.1" - } - }, - "cli-table": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz", - "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==", - "dev": true, - "requires": { - "colors": "1.0.3" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - }, - "commander": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz", - "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true - } - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "filesizes": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/filesizes/-/filesizes-0.1.2.tgz", - "integrity": "sha512-B7S28jvoR/mSmccYwh6jkZYvsmuXqULibMkT9rU4hYZfjHTk7bw8Zmygss9UNX49YbJirzvGb2MSh/CbSWKzzQ==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "cli-table": "^0.3.1", - "commander": "^4.1.1", - "gzip-size": "^5.1.1", - "pretty-bytes": "^5.3.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true - } - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", - "dev": true, - "requires": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jshint": { - "version": "2.13.4", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.4.tgz", - "integrity": "sha512-HO3bosL84b2qWqI0q+kpT/OpRJwo0R4ivgmxaO848+bo10rc50SkPnrtwSFXttW0ym4np8jbJvLwk5NziB7jIw==", - "dev": true, - "requires": { - "cli": "~1.0.0", - "console-browserify": "1.1.x", - "exit": "0.1.x", - "htmlparser2": "3.8.x", - "lodash": "~4.17.21", - "minimatch": "~3.0.2", - "strip-json-comments": "1.0.x" - }, - "dependencies": { - "minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", - "dev": true - } - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "loupe": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", - "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", - "dev": true, - "requires": { - "get-func-name": "^2.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "4.2.1", - "ms": "2.1.3", - "nanoid": "3.3.1", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/package.json b/package.json index 89071bc..d4e329a 100644 --- a/package.json +++ b/package.json @@ -1,99 +1,125 @@ { - "name": "@sebastienrousseau/password-generator", - "version": "1.0.4", - "description": "A fast, simple and powerful utility library for generating unique passwords to streamline your digital and mobile web development needs.", - "keywords": [ - "base64", - "complex", - "crypto", - "cryptography", - "dictionary", - "entropy", - "encryption", - "memorable", - "mit-license", - "open-source", - "openssl", - "pass", - "passgen", - "passphrase", - "password generator", - "password-generator", - "preprocessor", - "random", - "secure", - "security" - ], - "license": "MIT", - "main": "bin/password-generator.js", - "filename": "dist/bin/password-generator.js", - "repository": { - "type": "git", - "url": "git+https://github.com/sebastienrousseau/password-generator.git" - }, - "author": "Sebastien Rousseau (https://github.com/sebastienrousseau/password-generator)", - "license_URI": "http://www.opensource.org/licenses/mit-license.php", - "bugs": { - "url": "https://github.com/sebastienrousseau/password-generator/issues" - }, - "homepage": "https://password-generator.pro", - "publishConfig": { - "access": "public", - "registry": "https://npm.pkg.github.com" - }, - "autoupdate": { - "source": "git", - "target": "git://github.com/sebastienrousseau/password-generator.git", - "fileMap": [ - { - "basePath": "dist", - "files": [ - "**/*" - ] - } - ] - }, - "engines": { - "node": ">=12.22.0" - }, - "scripts": { - "// Build": " --- Build Scripts --- ", - "build": "npm run dev:generate:password:generator && cat ./package.json | grep -v '\"private\":' > dist/package.json && npm pack ./dist", - "// Password Generator": " --- Development Scripts --- ", - "dev:clean:directory": "rimraf \"dist/\"", - "dev:create:distribution": "mkdirp ./dist", - "dev:copy:bin": "cp -R ./bin dist/bin", - "dev:copy:dictionaries": "cp -R ./dictionaries dist/dictionaries/", - "dev:copy:images": "cp -R images/ dist/images/", - "dev:copy:lib": "cp -R ./lib dist/", - "dev:copy:readme": "cp README.md dist/", - "dev:copy:test": "cp -R ./lib test/", - "dev:filesizes:package": "filesizes dist/ > dist/package-report.txt", - "dev:generate:password:generator": "npm run dev:clean:directory && npm run dev:create:distribution && npm run dev:copy:bin && npm run dev:copy:dictionaries && npm run dev:copy:images && npm run dev:copy:lib && npm run dev:copy:readme && npm run dev:copy:test && npm run dev:filesizes:package", - "// Production": " --- Production Scripts --- ", - "postpublish": "npm run publish-npm", - "publish-npm": "npm publish --access public --ignore-scripts --@OWNER:registry='https://registry.npmjs.org'", - "prepare:password:generator": "npm run build", - "npm login": "npm publish $(node -p \"p=require('./package.json');p.name+'-'+p.version+'.tgz'\")", - "test": "echo \"Who need tests anyway? ¯\\_(ツ)_/¯ \" && exit 0" - }, - "type": "module", - "dependencies": { - "commander": "^9.1.0" - }, - "devDependencies": { - "chai": "^4.3.6", - "filesizes": "^0.1.2", - "jshint": "^2.13.4", - "mkdirp": "^1.0.4", - "mocha": "^9.2.2", - "rimraf": "^3.0.2" - }, - "bin": { - "password-generator": "bin/password-generator.js" - }, - "directories": { - "lib": "lib", - "test": "test" - } + "author": "Sebastien Rousseau (https://github.com/sebastienrousseau/password-generator)", + "autoupdate": { + "fileMap": [ + { + "basePath": "dist", + "files": [ + "**/*" + ] + } + ], + "source": "git", + "target": "git://github.com/sebastienrousseau/password-generator.git" + }, + "bin": { + "password-generator": "bin/password-generator.js" + }, + "bugs": { + "url": "https://github.com/sebastienrousseau/password-generator/issues" + }, + "description": "A fast, simple and powerful utility library for generating unique passwords to streamline your digital and mobile web development needs.", + "devDependencies": { + "@babel/cli": "^7.17.6", + "@babel/core": "^7.17.9", + "@babel/eslint-parser": "^7.17.0", + "@babel/preset-env": "^7.16.11", + "@babel/preset-typescript": "^7.16.7", + "chai": "^4.3.6", + "commander": "^9.2.0", + "eslint-plugin-import": "^2.26.0", + "filesizes": "^0.1.2", + "jest": "^28.0.0-alpha.9", + "jshint": "^2.13.4", + "mkdirp": "^1.0.4", + "mocha": "^9.2.2", + "nyc": "^15.1.0", + "prettier": "2.6.2", + "rimraf": "^3.0.2" + }, + "directories": { + "src": "src/", + "test": "test/" + }, + "engines": { + "node": ">=12.0.0" + }, + "filename": "src/index.js", + "files": [ + "src/", + "test/", + "COPYRIGHT", + "LICENSE", + "index.js", + "Makefile", + "README.md" + ], + "funding": "https://paypal.me/wwdseb", + "homepage": "https://password-generator.pro", + "keywords": [ + "base64", + "complex", + "crypto", + "cryptography", + "dictionary", + "entropy", + "encryption", + "memorable", + "mit-license", + "open-source", + "openssl", + "pass", + "passgen", + "passphrase", + "password generator", + "password-generator", + "preprocessor", + "random", + "secure", + "security" + ], + "license": "MIT", + "license_URI": "http://www.opensource.org/licenses/mit-license.php", + "main": "src/index.js", + "name": "@sebastienrousseau/password-generator", + "publishConfig": { + "access": "public", + "registry": "https://npm.pkg.github.com" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/sebastienrousseau/password-generator.git" + }, + "rules": { + "node/no-unpublished-import": ["error", { + "convertPath": [ + { + "include": ["src/**/*.js"], + "replace": ["^src/(.+)$", "lib/$1"] + } + ] + }] + }, + "scripts": { + "build": "npm run lint && npm run build:password:generator && cat ./package.json | grep -v '\"private\":' > dist/package.json && npm pack ./dist", + "build:password:generator": "npm run clean:directory && npm run create:directory && npm run copy:src && npm run copy:test && npm run copy:readme && npm run copy:license && npm run copy:copyright && npm run filesize:distribution", + "clean": "rimraf .nyc_output coverage", + "clean:directory": "rimraf \"dist/\"", + "copy:copyright": "cp COPYRIGHT dist/", + "copy:license": "cp LICENSE dist/", + "copy:readme": "cp README.md dist/", + "copy:src": "cp -R ./src dist/src", + "copy:test": "cp -R ./src dist/test", + "create:directory": "mkdirp ./dist", + "filesize:distribution": "filesizes dist/ > dist/report.txt", + "lint": "eslint \"./src/bin/**/*.js\" \"./src/**/*.js\"", + "npm login": "npm publish $(node -p \"p=require('./package.json');p.name+'-'+p.version+'.tgz'\")", + "postpublish": "npm run publish-npm", + "publish-npm": "npm publish --access public --ignore-scripts --@OWNER:registry='https://registry.npmjs.org'", + "start": "node src/bin/index.js", + "test": "mocha test/**/*.js", + "coverage": "nyc npm run test" + }, + "type": "module", + "version": "1.0.5" } diff --git a/src/bin/password-generator.js b/src/bin/password-generator.js new file mode 100644 index 0000000..e0f4be3 --- /dev/null +++ b/src/bin/password-generator.js @@ -0,0 +1,43 @@ +/*jshint esversion: 8 */ +import { base64Password } from "../lib/base64-password.js"; +import { Command } from "commander"; +import { complexPassword } from "../lib/complex-password.js"; +import { join } from "path"; +import { memorablePassword } from "../lib/memorable-password.js"; +import { readFileSync } from "fs"; + +// Initializing Variables +const actions = { + base64: () => base64Password(), + complex: () => complexPassword(), + memorable: () => memorablePassword(), +}; +const args = process.argv.slice(2); +const bool = Object.prototype.hasOwnProperty.call(actions, args[1]); +const pkg = JSON.parse( + readFileSync(join(process.cwd(), "/package.json"), "utf8") +); +const program = new Command(); +export function passwordGenerator() { + program + .name("password-generator") + .version(pkg.version, "-v, --version", "output the current version") + .description( + "A fast, simple and powerful open-source utility tool for generating strong, unique and random passwords" + ) + .option( + "-t, --type ", + "specify a password type", + "base64, complex or memorable" + ) + .option("-l, --length ", "specify a length for each iteration") + .option("-i, --iteration ", "specify a number of iteration") + .option("-s, --separator ", "specify a character for the separator") + .parse(process.argv); + + if (!bool) { + return program.help(); + } else if (bool) { + return actions[args[1]](); + } +} diff --git a/dictionaries/adjectives.json b/src/dictionaries/adjectives.json similarity index 100% rename from dictionaries/adjectives.json rename to src/dictionaries/adjectives.json diff --git a/dictionaries/adverbs.json b/src/dictionaries/adverbs.json similarity index 100% rename from dictionaries/adverbs.json rename to src/dictionaries/adverbs.json diff --git a/dictionaries/animals.json b/src/dictionaries/animals.json similarity index 100% rename from dictionaries/animals.json rename to src/dictionaries/animals.json diff --git a/dictionaries/cars.json b/src/dictionaries/cars.json similarity index 100% rename from dictionaries/cars.json rename to src/dictionaries/cars.json diff --git a/dictionaries/cities.json b/src/dictionaries/cities.json similarity index 100% rename from dictionaries/cities.json rename to src/dictionaries/cities.json diff --git a/dictionaries/common.json b/src/dictionaries/common.json similarity index 100% rename from dictionaries/common.json rename to src/dictionaries/common.json diff --git a/dictionaries/countries.json b/src/dictionaries/countries.json similarity index 100% rename from dictionaries/countries.json rename to src/dictionaries/countries.json diff --git a/dictionaries/dinosaurs.json b/src/dictionaries/dinosaurs.json similarity index 100% rename from dictionaries/dinosaurs.json rename to src/dictionaries/dinosaurs.json diff --git a/dictionaries/emoji.json b/src/dictionaries/emoji.json similarity index 100% rename from dictionaries/emoji.json rename to src/dictionaries/emoji.json diff --git a/dictionaries/encouraging.json b/src/dictionaries/encouraging.json similarity index 100% rename from dictionaries/encouraging.json rename to src/dictionaries/encouraging.json diff --git a/dictionaries/ergative.json b/src/dictionaries/ergative.json similarity index 100% rename from dictionaries/ergative.json rename to src/dictionaries/ergative.json diff --git a/dictionaries/fruits.json b/src/dictionaries/fruits.json similarity index 100% rename from dictionaries/fruits.json rename to src/dictionaries/fruits.json diff --git a/dictionaries/gemstones.json b/src/dictionaries/gemstones.json similarity index 100% rename from dictionaries/gemstones.json rename to src/dictionaries/gemstones.json diff --git a/dictionaries/hazards.json b/src/dictionaries/hazards.json similarity index 100% rename from dictionaries/hazards.json rename to src/dictionaries/hazards.json diff --git a/dictionaries/instruments.json b/src/dictionaries/instruments.json similarity index 100% rename from dictionaries/instruments.json rename to src/dictionaries/instruments.json diff --git a/dictionaries/lovecraft.json b/src/dictionaries/lovecraft.json similarity index 100% rename from dictionaries/lovecraft.json rename to src/dictionaries/lovecraft.json diff --git a/dictionaries/metals.json b/src/dictionaries/metals.json similarity index 100% rename from dictionaries/metals.json rename to src/dictionaries/metals.json diff --git a/dictionaries/music.json b/src/dictionaries/music.json similarity index 100% rename from dictionaries/music.json rename to src/dictionaries/music.json diff --git a/dictionaries/nouns.json b/src/dictionaries/nouns.json similarity index 100% rename from dictionaries/nouns.json rename to src/dictionaries/nouns.json diff --git a/dictionaries/prepositions.json b/src/dictionaries/prepositions.json similarity index 100% rename from dictionaries/prepositions.json rename to src/dictionaries/prepositions.json diff --git a/dictionaries/shakespeare.json b/src/dictionaries/shakespeare.json similarity index 100% rename from dictionaries/shakespeare.json rename to src/dictionaries/shakespeare.json diff --git a/dictionaries/sports.json b/src/dictionaries/sports.json similarity index 100% rename from dictionaries/sports.json rename to src/dictionaries/sports.json diff --git a/dictionaries/strange.json b/src/dictionaries/strange.json similarity index 100% rename from dictionaries/strange.json rename to src/dictionaries/strange.json diff --git a/dictionaries/vegetables.json b/src/dictionaries/vegetables.json similarity index 100% rename from dictionaries/vegetables.json rename to src/dictionaries/vegetables.json diff --git a/dictionaries/winds.json b/src/dictionaries/winds.json similarity index 100% rename from dictionaries/winds.json rename to src/dictionaries/winds.json diff --git a/images/button-primary.svg b/src/images/button-primary.svg similarity index 100% rename from images/button-primary.svg rename to src/images/button-primary.svg diff --git a/images/button-secondary.svg b/src/images/button-secondary.svg similarity index 100% rename from images/button-secondary.svg rename to src/images/button-secondary.svg diff --git a/images/password-generator-logo.svg b/src/images/password-generator-logo.svg similarity index 100% rename from images/password-generator-logo.svg rename to src/images/password-generator-logo.svg diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..28f8dd2 --- /dev/null +++ b/src/index.js @@ -0,0 +1,5 @@ +/*jshint esversion: 8 */ + +import { passwordGenerator } from "./bin/password-generator.js"; + +passwordGenerator(); diff --git a/lib/base64-password.js b/src/lib/base64-password.js similarity index 89% rename from lib/base64-password.js rename to src/lib/base64-password.js index 7f4c4c0..e6e9ef4 100644 --- a/lib/base64-password.js +++ b/src/lib/base64-password.js @@ -1,4 +1,3 @@ -/* eslint-disable node/no-unpublished-import */ /*jshint esversion: 8 */ import crypto from "crypto"; diff --git a/test/lib/complex-password.js b/src/lib/complex-password.js similarity index 78% rename from test/lib/complex-password.js rename to src/lib/complex-password.js index 62b4ba7..06ca0a1 100644 --- a/test/lib/complex-password.js +++ b/src/lib/complex-password.js @@ -1,22 +1,22 @@ -/* eslint-disable node/no-unpublished-import */ /*jshint esversion: 8 */ -import child_process from "child_process"; +import childProcess from "child_process"; // Initializing Variables const args = process.argv.slice(2); export async function complexPassword() { // Runs a command in a shell and buffers the output. - child_process.exec( + childProcess.exec( // Generating a 256-bit cipher "openssl rand -base64 256", (err, stdout, stderr) => { if (err) { - console.debug(`Exec: Fail to execute command`); + console.debug("Exec: Fail to execute command"); console.debug(err); console.debug(stderr); } + // Initializing a complex password let complex = stdout.toString().match(new RegExp(`.{0,${args[3]}}`, "g")); complex = complex.slice(0, args[5]).join(args[7]).toString(); diff --git a/lib/memorable-password.js b/src/lib/memorable-password.js similarity index 69% rename from lib/memorable-password.js rename to src/lib/memorable-password.js index 860d477..92f5842 100644 --- a/lib/memorable-password.js +++ b/src/lib/memorable-password.js @@ -1,24 +1,27 @@ -/* eslint-disable node/no-unpublished-import */ /*jshint esversion: 8 */ import { promises as fs } from "fs"; import { randomNumber } from "../utils/randomNumber.js"; -import { titleCase } from "../utils/titleCase.js"; +import { toTitleCase } from "../utils/toTitleCase.js"; // Initializing Variables const args = process.argv.slice(2); -let data, memorable = []; +const __dirname = process.cwd(); +let data, + memorable = []; export async function memorablePassword() { // Initializing variables - data = await fs.readFile("./dictionaries/common.json", "utf8"); + data = await fs.readFile(`${__dirname}/src/dictionaries/common.json`, "utf8"); // Read the JSON dictionary and store it as an array data = JSON.parse(data); // Picking random words from the JSON dictionary based on the data length data.entries.forEach(() => { - memorable.push(titleCase(data.entries[randomNumber(data.entries.length)])); + memorable.push( + toTitleCase(data.entries[randomNumber(data.entries.length)]) + ); return memorable; }); diff --git a/src/utils/README.md b/src/utils/README.md new file mode 100644 index 0000000..0e7f213 --- /dev/null +++ b/src/utils/README.md @@ -0,0 +1,101 @@ + +# Table of Contents + +- [Utils](#utils) + - [Table of Contents](#table-of-contents) + - [toCamelCase(): string](#tocamelcase-string) + - [toKebabCase(): string](#tokebabcase-string) + - [toSnakeCase(): string](#tosnakecase-string) + +## Utils + +### toCamelCase(): string + +[File: toCamelCase.js](./toCamelCase.js) + +Converts a string to camelcase. + +- Use `String.prototype.match()` to break the string into words using an appropriate regexp. +- Use `Array.prototype.map()`, `Array.prototype.slice()`, `Array.prototype.join()`, `String.prototype.toLowerCase()` and `String.prototype.toUpperCase()` to combine them, capitalizing the first letter of each one. + +```js +const toCamelCase = str => { + const s = + str && + str + .match( + /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g + ) + .map(x => x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase()) + .join(''); + return s.slice(0, 1).toLowerCase() + s.slice(1); +}; +``` + +```js +toCamelCase("passwordGenerator"); // should convert a camel case string to camelcase +toCamelCase("password.generator"); // should convert a dot case string to camelcase +toCamelCase("--PASSWORD-GENERATOR--"); // should convert a junk case string to camelcase +toCamelCase("password-generator"); // should convert a kebab case string to camelcase +toCamelCase("PasswordGenerator"); // should convert a pascal case string to camelcase +toCamelCase("Password generator"); // should convert a sentence case string to camelcase +toCamelCase("password_generator"); // should convert a snake case string to camelcase +toCamelCase("password generator"); // should convert a space case string to camelcase +toCamelCase("Password Generator"); // should convert a title case string to camelcase +toCamelCase("PASSWORD GENERATOR"); // should convert a uppercase case string to camelcase +``` + +Converts all the alphabetic characters in a string to camel case. + +### toKebabCase(): string + +[File: toKebabCase.js](./toKebabCase.js) + +Converts all the alphabetic characters in a string to kebab case. + +- Use `String.prototype.match()` to break the string into words using an appropriate regexp. +- Use `Array.prototype.map()`, `Array.prototype.join()` and `String.prototype.toLowerCase()` to combine them, adding `-` as a separator. + +```js +export function toKebabCase(str) { + return str + .match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g) + .map(x => x.toLowerCase()) + .join('-'); +} +``` + +```js +console.log(toKebabCase('kebabCase')); // 'kebab-case' +console.log(toKebabCase('some text')); // 'some-text' +console.log(toKebabCase('some-mixed_string With spaces_underscores-and-hyphens')); // 'some-mixed-string-with-spaces-underscores-and-hyphens' +console.log(toKebabCase('AllThe-small Things')); // 'all-the-small-things' +console.log(toKebabCase('IAmEditingSomeXMLAndHTML')); // 'i-am-editing-some-xml-and-html' +``` + +### toSnakeCase(): string + +[File: toSnakeCase.js](./toSnakeCase.js) + +Converts all the alphabetic characters in a snake case string. + +- Use `String.prototype.match()` to break the string into words using an appropriate regexp. +- Use `String.prototype.replace()` and `String.prototype.toLowerCase()` to combine them, adding `_` as a separator. + +```js +export function toSnakeCase(str) { + return str + .replace(/^[^A-Za-z0-9]*|[^A-Za-z0-9]*$/g, '') + .replace(/([a-z])([A-Z])/g, (_, a, b) => a + '_' + b.toLowerCase()) + .replace(/[^A-Za-z0-9]+|_+/g, '_') + .toLowerCase(); +} +``` + +```js +console.log(toSnakeCase('snakeCase')); // 'snake-case' +console.log(toSnakeCase('some text')); // 'some-text' +console.log(toSnakeCase('some-mixed_string With spaces_underscores-and-hyphens')); // 'some-mixed-string-with-spaces-underscores-and-hyphens' +console.log(toSnakeCase('AllThe-small Things')); // 'all-the-small-things' +console.log(toSnakeCase('IAmEditingSomeXMLAndHTML')); // 'i-am-editing-some-xml-and-html' +``` diff --git a/src/utils/randomConsonant.js b/src/utils/randomConsonant.js new file mode 100644 index 0000000..8bc2432 --- /dev/null +++ b/src/utils/randomConsonant.js @@ -0,0 +1,10 @@ +/*jshint esversion: 8 */ + +import { randomNumber } from "../../src/utils/randomNumber.js"; + +// There are 21 consonants (b, c, d, f, h, g, j, k, l, m, n, p, q, r, s, t, v, w, x, y, z) +let consonants = "bcdfhgjklmnpqrstvwxyz"; + +export function randomConsonant() { + return consonants[randomNumber(consonants.length)]; +} diff --git a/utils/randomNumber.js b/src/utils/randomNumber.js similarity index 53% rename from utils/randomNumber.js rename to src/utils/randomNumber.js index 741751f..6f62110 100644 --- a/utils/randomNumber.js +++ b/src/utils/randomNumber.js @@ -1,4 +1,4 @@ /*jshint esversion: 8 */ export function randomNumber(number) { - return (Math.floor(Math.random() * 2 ** 32) % number); + return Math.floor(Math.random() * 2 ** 32) % number; } diff --git a/src/utils/randomSyllable.js b/src/utils/randomSyllable.js new file mode 100644 index 0000000..4ade941 --- /dev/null +++ b/src/utils/randomSyllable.js @@ -0,0 +1,8 @@ +/*jshint esversion: 8 */ + +import { randomConsonant } from "../../src/utils/randomConsonant.js"; +import { randomVowel } from "../../src/utils/randomVowel.js"; + +export function randomSyllable() { + return randomConsonant() + randomVowel() + randomConsonant(); +} diff --git a/src/utils/randomVowel.js b/src/utils/randomVowel.js new file mode 100644 index 0000000..e34d824 --- /dev/null +++ b/src/utils/randomVowel.js @@ -0,0 +1,10 @@ +/*jshint esversion: 8 */ + +import { randomNumber } from "../../src/utils/randomNumber.js"; + +// There are 5 vowels (a, e, i, o, u) +let vowels = "aeiou"; + +export function randomVowel() { + return vowels[randomNumber(vowels.length)]; +} diff --git a/src/utils/toCamelCase.js b/src/utils/toCamelCase.js new file mode 100644 index 0000000..356db85 --- /dev/null +++ b/src/utils/toCamelCase.js @@ -0,0 +1,28 @@ +/*jshint esversion: 8 */ + +/** + * Converts all the alphabetic characters in a string to camel case. + * @param {String} str The text to be converted to camel case. + */ +export const toCamelCase = (str) => { + // Any of ((literally "/", uppercase, at least 2 times), (uppercase, optional, letter, once or more, literally "/g")) + const r = /[A-Z]{2,}|[A-Z]?[a-z]+/g; + const s = + str && + str + .match(r) + .map((x) => x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase()) + .join(""); + return s.slice(0, 1).toLowerCase() + s.slice(1); +}; + +// console.log(toCamelCase("passwordGenerator")); // ✔ should convert a camel case string to camelcase +// console.log(toCamelCase("password.generator")); // ✔ should convert a dot case string to camelcase +// console.log(toCamelCase("--PASSWORD-GENERATOR--")); // ✔ should convert a junk case string to camelcase +// console.log(toCamelCase("password-generator")); // ✔ should convert a kebab case string to camelcase +// console.log(toCamelCase("PasswordGenerator")); // ✔ should convert a pascal case string to camelcase +// console.log(toCamelCase("Password generator")); // ✔ should convert a sentence case string to camelcase +// console.log(toCamelCase("password_generator")); // ✔ should convert a snake case string to camelcase +// console.log(toCamelCase("password generator")); // ✔ should convert a space case string to camelcase +// console.log(toCamelCase("Password Generator")); // ✔ should convert a title case string to camelcase +// console.log(toCamelCase("PASSWORD GENERATOR")); // ✔ should convert a uppercase case string to camelcase diff --git a/src/utils/toKebabCase.js b/src/utils/toKebabCase.js new file mode 100644 index 0000000..0a85e12 --- /dev/null +++ b/src/utils/toKebabCase.js @@ -0,0 +1,22 @@ +/*jshint esversion: 8 */ + +/** + * Converts all the alphabetic characters in a string to kebab case. + * @param {String} str The text to be converted to kebab case. + */ +export const toKebabCase = (str) => + str + .match(/[A-Z]{2,}|[A-Z]?[a-z]+\d*|[A-Z]|\d+/g) + .map((x) => x.toLowerCase()) + .join("-"); + +// console.log(toKebabCase("passwordGenerator")); // ✔ should convert a camel case string to kebab case +// console.log(toKebabCase("password.generator")); // ✔ should convert a dot case string to kebab case +// console.log(toKebabCase("--PASSWORD-GENERATOR--")); // ✔ should convert a junk case string to kebab case +// console.log(toKebabCase("password-generator")); // ✔ should convert a kebab case string to kebab case +// console.log(toKebabCase("PasswordGenerator")); // ✔ should convert a pascal case string to kebab case +// console.log(toKebabCase("Password generator")); // ✔ should convert a sentence case string to kebab case +// console.log(toKebabCase("password_generator")); // ✔ should convert a snake case string to kebab case +// console.log(toKebabCase("password generator")); // ✔ should convert a space case string to kebab case +// console.log(toKebabCase("Password Generator")); // ✔ should convert a title case string to kebab case +// console.log(toKebabCase("PASSWORD GENERATOR")); // ✔ should convert a uppercase case string to kebab case diff --git a/src/utils/toSnakeCase.js b/src/utils/toSnakeCase.js new file mode 100644 index 0000000..5f47198 --- /dev/null +++ b/src/utils/toSnakeCase.js @@ -0,0 +1,23 @@ +/*jshint esversion: 8 */ + +/** + * Converts all the alphabetic characters in a snake case string. + * @param {String} str The text to be converted to snake case. + */ +export const toSnakeCase = (str) => + str + .replace(/^[^A-Za-z\d]*|[^A-Za-z\d]*$/g, "") + .replace(/([a-z])([A-Z])/g, (_, a, b) => a + "_" + b.toLowerCase()) + .replace(/[^A-Za-z\d]+/g, "_") + .toLowerCase(); + +// console.log(toSnakeCase("passwordGenerator")); // ✔ should convert a camel case string to snake case +// console.log(toSnakeCase("password.generator")); // ✔ should convert a dot case string to snake case +// console.log(toSnakeCase("--PASSWORD-GENERATOR--")); // ✔ should convert a junk case string to snake case +// console.log(toSnakeCase("password-generator")); // ✔ should convert a kebab case string to snake case +// console.log(toSnakeCase("PasswordGenerator")); // ✔ should convert a pascal case string to snake case +// console.log(toSnakeCase("Password generator")); // ✔ should convert a sentence case string to snake case +// console.log(toSnakeCase("password_generator")); // ✔ should convert a snake case string to snake case +// console.log(toSnakeCase("password generator")); // ✔ should convert a space case string to snake case +// console.log(toSnakeCase("Password Generator")); // ✔ should convert a title case string to snake case +// console.log(toSnakeCase("PASSWORD GENERATOR")); // ✔ should convert a uppercase case string to snake case diff --git a/src/utils/toTitleCase.js b/src/utils/toTitleCase.js new file mode 100644 index 0000000..c98b127 --- /dev/null +++ b/src/utils/toTitleCase.js @@ -0,0 +1,23 @@ +/*jshint esversion: 8 */ + +/** + * Converts all the alphabetic characters in a string to title case. + * @param {String} str The text to be converted to title case. + */ +export const toTitleCase = (str) => + str + .toLowerCase() + .match(/[A-Z]{2,}(?=[A-Z][a-z]|\b)|[A-Z]?[a-z]+|[A-Z]|\d+/g) + .map((x) => x.charAt(0).toUpperCase() + x.slice(1)) + .join(" "); + +// console.log(toTitleCase("passwordGenerator")); // ✔ should convert a camel case string to title case +// console.log(toTitleCase("password.generator")); // ✔ should convert a dot case string to title case +// console.log(toTitleCase("--PASSWORD-GENERATOR--")); // ✔ should convert a junk case string to title case +// console.log(toTitleCase("password-generator")); // ✔ should convert a kebab case string to title case +// console.log(toTitleCase("PasswordGenerator")); // ✔ should convert a pascal case string to title case +// console.log(toTitleCase("Password generator")); // ✔ should convert a sentence case string to title case +// console.log(toTitleCase("password_generator")); // ✔ should convert a snake case string to title case +// console.log(toTitleCase("password generator")); // ✔ should convert a space case string to title case +// console.log(toTitleCase("Password Generator")); // ✔ should convert a title case string to title case +// console.log(toTitleCase("PASSWORD GENERATOR")); // ✔ should convert a uppercase case string to title case diff --git a/test/lib/base64-password.js b/test/lib/base64-password.js deleted file mode 100644 index 7f4c4c0..0000000 --- a/test/lib/base64-password.js +++ /dev/null @@ -1,19 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/*jshint esversion: 8 */ - -import crypto from "crypto"; - -// Initializing Variables -const args = process.argv.slice(2); - -export async function base64Password() { - // Generating a base64 variable. - let base64 = crypto.randomBytes(256).toString("base64"); - - // Initializing a base64 password - base64 = base64 - .match(new RegExp(".{1," + args[3] + "}", "g")) - .slice(0, args[5]) - .join(args[7]); - console.log(base64); -} diff --git a/test/lib/memorable-password.js b/test/lib/memorable-password.js deleted file mode 100644 index 508d3af..0000000 --- a/test/lib/memorable-password.js +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable node/no-unpublished-import */ -/*jshint esversion: 8 */ - -import { promises as fs } from "fs"; -import { titleCase } from "./title-case.js"; - -// Initializing Variables -const args = process.argv.slice(2); - -export async function memorablePassword() { - // Initializing variables - let data = await fs.readFile("./dictionaries/common.json", "utf8"); - let memorable = []; - let random; - - // Read the JSON dictionary and store it as an array - data = JSON.parse([data]); - - // Picking random words from the JSON dictionary - data.entries.forEach(() => { - random = data.entries[Math.floor(Math.random() * data.entries.length)]; - memorable.push(titleCase(random)); - return memorable; - }); - - // Initializing a memorable password - memorable = memorable - .slice(0, args[3]) - .join(args[5]) - .toString() - .replace(/ /g, ""); - console.log(memorable); -} diff --git a/test/lib/title-case.js b/test/lib/title-case.js deleted file mode 100644 index e9ade3b..0000000 --- a/test/lib/title-case.js +++ /dev/null @@ -1,4 +0,0 @@ -/*jshint esversion: 8 */ -export function titleCase(str) { - return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase(); -} diff --git a/test/test-title-case.js b/test/test-title-case.js deleted file mode 100644 index 20e5868..0000000 --- a/test/test-title-case.js +++ /dev/null @@ -1,31 +0,0 @@ -/*jshint esversion: 8 */ -import { titleCase } from "../lib/title-case.js"; -import * as chai from "chai"; -let expect = chai.expect; - -// mocha() test -describe("mocha () ", function () { - it("should load mocha", function () { - expect(true); - }); -}); - -// titleCase() test -describe("titleCase (string) ", function () { - it("should return a string", function () { - let str = "HELLO"; - expect(titleCase(str)).to.be.a("string"); - }); - it("should return a titleized string for one lowercase word", function () { - let str = "hello"; - expect(titleCase(str)).equal("Hello"); - }); - it("should return a titleized string for one uppercase word", function () { - let str = "HELLO"; - expect(titleCase(str)).equal("Hello"); - }); - it("should return a titleized string for a sentence of words", function () { - let str = "hello world"; - expect(titleCase(str)).equal("Hello world"); - }); -}); diff --git a/test/utils/toCamelCase.test.js b/test/utils/toCamelCase.test.js new file mode 100644 index 0000000..ab6ac60 --- /dev/null +++ b/test/utils/toCamelCase.test.js @@ -0,0 +1,43 @@ +/*jshint esversion: 8 */ + +import { toCamelCase } from "../../src/utils/toCamelCase.js"; +import * as chai from "chai"; +let expect = chai.expect; +let assert = chai.assert; + +let strings = { + camel: "passwordGenerator", + dot: "password.generator", + junk: "--PASSWORD-GENERATOR--", + kebab: "password-generator", + pascal: "PasswordGenerator", + sentence: "Password generator", + snake: "password_generator", + space: "password generator", + title: "Password Generator", + uppercase: "PASSWORD GENERATOR", +}; + +// mocha() test +describe("Running mocha () function \n", function () { + it("should run mocha", function () { + expect(true); + }); +}); + +// toCamelCase() tests +describe("Running toCamelCase () function \n", function () { + for (let key in strings) test(key); +}); + +/** + * Create a test for a given case `key`. + * + * @param {String} key + */ + +function test(key) { + it("should convert a " + key + " case string to camelcase", function () { + assert.equal(toCamelCase(strings[key]), "passwordGenerator"); + }); +} diff --git a/test/utils/toSnakeCase.test.js b/test/utils/toSnakeCase.test.js new file mode 100644 index 0000000..8850d9a --- /dev/null +++ b/test/utils/toSnakeCase.test.js @@ -0,0 +1,39 @@ +/*jshint esversion: 8 */ + +import { toSnakeCase } from "../../src/utils/toSnakeCase.js"; +import * as chai from "chai"; +let expect = chai.expect; + +let snakeCaseArray = [ + "passwordGenerator", + "password-generator", + "PasswordGenerator", + "PASSWORD_GENERATOR", + "password_generator", + "password_generator", + "password generator", + "Password Generator", + "password.generator", + "--PASSWORD-GENERATOR--", +]; + +// mocha() test +describe("Running mocha () ", function () { + it("should run mocha", function () { + expect(true); + }); +}); + +// toSnakeCase() tests +describe("Running toSnakeCase (string) \n", function () { + it("should return a string \n", function () { + let str = "Password Generator"; + expect(toSnakeCase(str)).to.be.a("string"); + }); + it("should convert all the alphabetic characters in a snake case string.", function () { + for (let i = 0; i < snakeCaseArray.length; i++) { + // console.log(` → Test #${[i]} where string = "${snakeCaseArray[i]}"\n`); + expect(toSnakeCase(snakeCaseArray[i])).equal("password_generator"); + } + }); +}); diff --git a/test/utils/toTitleCase.test.js b/test/utils/toTitleCase.test.js new file mode 100644 index 0000000..47543fa --- /dev/null +++ b/test/utils/toTitleCase.test.js @@ -0,0 +1,34 @@ +/*jshint esversion: 8 */ +import { toTitleCase } from "../../src/utils/toTitleCase.js"; +import * as chai from "chai"; +let expect = chai.expect; + +let toTitleCaseArray = [ + "password Generator", + "password generator", + "Password Generator", + "PASSWORD GENERATOR", + "Password Generator", +]; + +// mocha() test +describe("Running mocha () ", function () { + it("should run mocha", function () { + expect(true); + }); +}); + +// toTitleCase() test +describe("Running toTitleCase (string) \n", function () { + it("should return a string", function () { + let str = "Password"; + expect(toTitleCase(str)).to.be.a("string"); + }); + + it("should convert all the alphabetic characters in a string to title case.", function () { + for (let i = 0; i < toTitleCaseArray.length; i++) { + //console.log(` → Test #${[i]} where string = "${toTitleCaseArray[i]}"\n`); + expect(toTitleCase(toTitleCaseArray[i])).equal("Password Generator"); + } + }); +}); diff --git a/utils/titleCase.js b/utils/titleCase.js deleted file mode 100644 index e9ade3b..0000000 --- a/utils/titleCase.js +++ /dev/null @@ -1,4 +0,0 @@ -/*jshint esversion: 8 */ -export function titleCase(str) { - return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase(); -}