diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index e93ba31..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,76 +0,0 @@ -version: 2 -jobs: - build: - working_directory: ~/repo - docker: - - image: circleci/node:8.11.3 - steps: - - checkout - - run: - name: authorize npm - command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - - restore_cache: - key: dependency-cache-{{ checksum "package.json" }} - - run: - name: run npm install - command: npm install - - save_cache: - key: dependency-cache-{{ checksum "package.json" }} - paths: - - ./node_modules - - run: mkdir ~/junit - - run: - name: build & test - command: npm run ci - when: always - - run: cp test-results.xml ~/junit/test-results.xml - - store_test_results: - path: ~/junit - - store_artifacts: - path: ~/junit - - build_deploy_npm: - working_directory: ~/repo - docker: - - image: circleci/node:8.11.3 - steps: - - checkout - - run: - name: authorize npm - command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - - restore_cache: - key: dependency-cache-{{ checksum "package.json" }} - - run: - name: run npm install - command: npm install - - save_cache: - key: dependency-cache-{{ checksum "package.json" }} - paths: - - ./node_modules - - run: mkdir ~/junit - - run: - name: build & test - command: npm run ci - when: always - - run: cp test-results.xml ~/junit/test-results.xml - - store_test_results: - path: ~/junit - - store_artifacts: - path: ~/junit - - run: - name: publish package to npm - command: npm publish - -workflows: - version: 2 - build_deploy: - jobs: - - build: - context: secrets - - build_deploy_npm: - context: secrets - filters: - tags: - only: /.*/ - branches: - ignore: /.*/ diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f4f6be7 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false + +[*.{js,json,ts,mts,yml,yaml}] +indent_size = 2 +indent_style = space diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..fc40c5a --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +/**/*.js diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 18c6d7d..0000000 --- a/.eslintrc +++ /dev/null @@ -1,72 +0,0 @@ -{ - "parserOptions": { - "sourceType": "module" - }, - "env": { - "node": true, - "browser": true - }, - "extends": "eslint:recommended", - "rules": { - "no-alert": 2, - "no-array-constructor": 2, - "no-caller": 2, - "no-catch-shadow": 2, - "no-eval": 2, - "no-extend-native": 2, - "no-extra-bind": 2, - "no-implied-eval": 2, - "no-iterator": 2, - "no-label-var": 2, - "no-labels": 2, - "no-lone-blocks": 2, - "no-loop-func": 2, - "no-multi-spaces": 2, - "no-multi-str": 2, - "no-native-reassign": 2, - "no-new": 2, - "no-new-func": 2, - "no-new-object": 2, - "no-new-wrappers": 2, - "no-octal-escape": 2, - "no-process-exit": 2, - "no-proto": 2, - "no-return-assign": 2, - "no-script-url": 2, - "no-sequences": 2, - "no-shadow": 2, - "no-shadow-restricted-names": 2, - "no-spaced-func": 2, - "no-trailing-spaces": 2, - "no-undef-init": 2, - "no-underscore-dangle": 0, - "no-unused-expressions": 2, - "no-use-before-define": 2, - "no-with": 2, - "camelcase": 1, - "comma-spacing": 2, - "consistent-return": 2, - "curly": [ 2, "all" ], - "dot-notation": [ 2, { "allowKeywords": true } ], - "eol-last": 2, - "no-extra-parens": [ 2, "functions" ], - "eqeqeq": 2, - "keyword-spacing": [ 2, { "before": true, "after": true } ], - "key-spacing": [ 2, { "beforeColon": false, "afterColon": true } ], - "new-cap": 2, - "new-parens": 2, - "quotes": [ 2, "single" ], - "semi": 2, - "semi-spacing": [ 2, { "before": false, "after": true } ], - "space-infix-ops": 2, - "space-unary-ops": [ 2, { "words": true, "nonwords": false } ], - "strict": [ 2, "global" ], - "yoda": [ 2, "never" ] - }, - "overrides": [ - { - "files": [ "*.js", "test/*.js" ], - "excludedFiles": "examples/*.js" - } - ] -} \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..b91213e --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,26 @@ +{ + "env": { + "browser": false, + "es6": true, + "node": true + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "tsconfig.json", + "sourceType": "module", + "ecmaVersion": 2020 + }, + "plugins": ["@typescript-eslint", "tap"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "rules": { + // The following rule is enabled only to supplement the inline suppression + // examples, and because it is not a recommended rule, you should either + // disable it, or understand what it enforces. + // https://typescript-eslint.io/rules/explicit-function-return-type/ + "@typescript-eslint/explicit-function-return-type": "warn" + } +} diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..9375379 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [jsynowiec] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml new file mode 100644 index 0000000..d495fd7 --- /dev/null +++ b/.github/workflows/nodejs.yml @@ -0,0 +1,17 @@ +name: Node.js CI + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: volta-cli/action@v1 + - run: npm ci --no-audit + - run: npm run lint --if-present + - run: npm test + - run: npm run build --if-present + env: + CI: true diff --git a/.gitignore b/.gitignore index 07d22d0..0c7c547 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,30 @@ +# Logs +logs +*.log +npm-debug.log* + +# Dependencies node_modules/ -coverage/ -test-results.xml + +# Coverage & Test output +coverage +.tap/ + +# Transpiled files +build/ + +# VS Code +.vscode/ +!.vscode/tasks.js + +# JetBrains IDEs +.idea/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Misc +.DS_Store diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 58bab04..0000000 --- a/.npmignore +++ /dev/null @@ -1 +0,0 @@ -test-results.xml \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..4c4a30c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,12 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "overrides": [ + { + "files": ["*.ts", "*.mts"], + "options": { + "parser": "typescript" + } + } + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json index 1763d31..20d60ad 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,24 +7,26 @@ { "type": "node", "request": "launch", - "name": "Launch Program", - "program": "${workspaceFolder}/examples/array-change.js" + "name": "tap (current file)", + "program": "${workspaceFolder}/node_modules/.bin/tap", + "args": ["${relativeFile}"], + "cwd": "${workspaceFolder}" }, { - "name": "Run mocha", + "name": "ts-node (current file)", "type": "node", "request": "launch", - "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", - "stopOnEntry": false, - "args": [ - "test/**/*.js", - "--no-timeouts" + "args": ["${relativeFile}"], + "runtimeArgs": [ + "-r", + "tsconfig-paths/register", + "-r", + "ts-node/register", + "--loader", + "ts-node/esm" ], "cwd": "${workspaceRoot}", - "runtimeExecutable": null, - "env": { - "NODE_ENV": "testing" - } + "internalConsoleOptions": "openOnSessionStart" } ] -} \ No newline at end of file +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 6017eb4..0000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "script": "build", - "problemMatcher": [] - } - ] -} \ No newline at end of file diff --git a/ChangeLog.md b/ChangeLog.md deleted file mode 100644 index 10069ab..0000000 --- a/ChangeLog.md +++ /dev/null @@ -1,63 +0,0 @@ -# deep-diff Change Log - -**deep-diff** is a javascript/node.js module providing utility functions for determining the structural differences between objects and includes some utilities for applying differences across objects. - -## Log - -`1.0.2` - 2018-08-10 - -* Support for react-native environment - Thanks @xanderberkein - -`1.0.0` - 2018-04-18 - -* reverted to [UMD style module](https://github.com/umdjs/umd) rather than the ES6 style, which evidently, broke lots of people's previously working code. -* fixed some bugs... see `examples/issue-XXx.js` for each issue I believe is fixed in this version. -* Closed: - * [#63 diff of equal objects should return empty array](https://github.com/flitbit/diff/issues/63) - * [#115 Remove second argument of applyChange from public api](https://github.com/flitbit/diff/issues/115) -* Resolved: - * [#78 FeatureRequest: change the diff of array elements (or add such an option)](https://github.com/flitbit/diff/issues/78) -* Fixed: - * [#47 Deleting Array elements](https://github.com/flitbit/diff/issues/47) - * [#111 Crash when comparing two undefined](https://github.com/flitbit/diff/issues/111) - -`0.3.8` - 2017-05-03 - -* reconciled recently introduced difference between `index.es.js` and `index.js` -* improved npm commands for more reliable contributions -* added a few notes to README regarding contributing. - -`0.3.7` - 2017-05-01 - -* fixed issue #98 by merging @sberan's pull request #99 — better handling of property with `undefined` value existing on either operand. Unit tests supplied. - -`0.3.6` - 2017-04-25 — Fixed, closed lingering issues: - -* fixed #74 — comparing objects with longer cycles -* fixed #70 — was not properly detecting a deletion when a property on the operand (lhs) had a value of `undefined` and was _undefined_ on the comparand (rhs). :o). -* WARNING! [Still broken when importing in Typescript](https://github.com/flitbit/diff/issues/97). - -`0.3.5` - 2017-04-23 — Rolled up recent fixes; patches: - -* @stevemao — #79, #80: now testing latest version of node4 -* @mortonfox — #85: referencing mocha's new home -* @tdebarochez — #90: fixed error when .toString not a function -* @thiamsantos — #92, #93: changed module system for improved es2015 modules. WARNING! [This PR broke importing `deep-diff` in Typescript as reported by @kgentes in #97](https://github.com/flitbit/diff/issues/97) - -`0.3.4` - Typescript users, reference this version until #97 is fixed! - -`0.3.3` - Thanks @SimenB: enabled npm script for release (alternate to the Makefile). Also linting as part of `npm test`. Thanks @joeldenning: Fixed issue #35; diffs of top level arrays now working. - -`0.3.3` - Thanks @SimenB: enabled npm script for release (alternate to the Makefile). Also linting as part of `npm test`. Thanks @joeldenning: Fixed issue #35; diffs of top level arrays now working. - -`0.3.2` - Resolves #46; support more robust filters by including `lhs` and `rhs` in the filter callback. By @Orlando80 - -`0.3.1` - Better type checking by @Drinks, UMD wrapper by @SimenB. Now certifies against nodejs 12 and iojs (Thanks @SimenB). - -`0.2.0` - [Fixes Bug #17](https://github.com/flitbit/diff/issues/17), [Fixes Bug #19](https://github.com/flitbit/diff/issues/19), [Enhancement #21](https://github.com/flitbit/diff/issues/21) Applying changes that are properly structured can now be applied as a change (no longer requires typeof Diff) - supports differences being applied after round-trip serialization to JSON format. Prefilter now reports the path of all changes - it was not showing a path for arrays and anything in the structure below (reported by @ravishvt). - -*Breaking Change* – The structure of change records for differences below an array element has changed. Array indexes are now reported as numeric elements in the `path` if the changes is merely edited (an `E` kind). Changes of kind `A` (array) are only reported for changes in the terminal array itself and will have a nested `N` (new) item or a nested `D` (deleted) item. - -`0.1.7` - [Enhancement #11](https://github.com/flitbit/diff/issues/11) Added the ability to filter properties that should not be analyzed while calculating differences. Makes `deep-diff` more usable with frameworks that attach housekeeping properties to existing objects. AngularJS does this, and the new filter ability should ease working with it. - -`0.1.6` - Changed objects within nested arrays can now be applied. They were previously recording the changes appropriately but `applyDiff` would error. Comparison of `NaN` works more sanely - comparison to number shows difference, comparison to another `Nan` does not. \ No newline at end of file diff --git a/LICENSE b/LICENSE index c323974..8dada3e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,201 @@ -Copyright (c) 2011-2018 Phillip Clark + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + 1. Definitions. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Readme.md b/Readme.md index 2a7335b..99b930f 100644 --- a/Readme.md +++ b/Readme.md @@ -1,288 +1,9 @@ # deep-diff -[![CircleCI](https://circleci.com/gh/flitbit/diff.svg?style=svg)](https://circleci.com/gh/flitbit/diff) - -[![NPM](https://nodei.co/npm/deep-diff.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/deep-diff/) - **deep-diff** is a javascript/node.js module providing utility functions for determining the structural differences between objects and includes some utilities for applying differences across objects. -## Install - -```bash -npm install deep-diff -``` - -Possible v1.0.0 incompatabilities: - -* elements in arrays are now processed in reverse order, which fixes a few nagging bugs but may break some users - * If your code relied on the order in which the differences were reported then your code will break. If you consider an object graph to be a big tree, then `deep-diff` does a [pre-order traversal of the object graph](https://en.wikipedia.org/wiki/Tree_traversal), however, when it encounters an array, the array is processed from the end towards the front, with each element recursively processed in-order during further descent. - -## Features - -* Get the structural differences between two objects. -* Observe the structural differences between two objects. -* When structural differences represent change, apply change from one object to another. -* When structural differences represent change, selectively apply change from one object to another. - -## Installation - -```bash -npm install deep-diff -``` - -### Importing - -#### nodejs - -```javascript -var diff = require('deep-diff') -// or: -// const diff = require('deep-diff'); -// const { diff } = require('deep-diff'); -// or: -// const DeepDiff = require('deep-diff'); -// const { DeepDiff } = require('deep-diff'); -// es6+: -// import diff from 'deep-diff'; -// import { diff } from 'deep-diff'; -// es6+: -// import DeepDiff from 'deep-diff'; -// import { DeepDiff } from 'deep-diff'; -``` - -#### browser - -```html - -``` - -> In a browser, `deep-diff` defines a global variable `DeepDiff`. If there is a conflict in the global namespace you can restore the conflicting definition and assign `deep-diff` to another variable like this: `var deep = DeepDiff.noConflict();`. - -## Simple Examples - -In order to describe differences, change revolves around an `origin` object. For consistency, the `origin` object is always the operand on the `left-hand-side` of operations. The `comparand`, which may contain changes, is always on the `right-hand-side` of operations. - -``` javascript -var diff = require('deep-diff').diff; - -var lhs = { - name: 'my object', - description: 'it\'s an object!', - details: { - it: 'has', - an: 'array', - with: ['a', 'few', 'elements'] - } -}; - -var rhs = { - name: 'updated object', - description: 'it\'s an object!', - details: { - it: 'has', - an: 'array', - with: ['a', 'few', 'more', 'elements', { than: 'before' }] - } -}; - -var differences = diff(lhs, rhs); -``` - -*v 0.2.0 and above* The code snippet above would result in the following structure describing the differences: - -``` javascript -[ { kind: 'E', - path: [ 'name' ], - lhs: 'my object', - rhs: 'updated object' }, - { kind: 'E', - path: [ 'details', 'with', 2 ], - lhs: 'elements', - rhs: 'more' }, - { kind: 'A', - path: [ 'details', 'with' ], - index: 3, - item: { kind: 'N', rhs: 'elements' } }, - { kind: 'A', - path: [ 'details', 'with' ], - index: 4, - item: { kind: 'N', rhs: { than: 'before' } } } ] -``` - -### Differences - -Differences are reported as one or more change records. Change records have the following structure: - -* `kind` - indicates the kind of change; will be one of the following: - * `N` - indicates a newly added property/element - * `D` - indicates a property/element was deleted - * `E` - indicates a property/element was edited - * `A` - indicates a change occurred within an array -* `path` - the property path (from the left-hand-side root) -* `lhs` - the value on the left-hand-side of the comparison (undefined if kind === 'N') -* `rhs` - the value on the right-hand-side of the comparison (undefined if kind === 'D') -* `index` - when kind === 'A', indicates the array index where the change occurred -* `item` - when kind === 'A', contains a nested change record indicating the change that occurred at the array index - -Change records are generated for all structural differences between `origin` and `comparand`. The methods only consider an object's own properties and array elements; those inherited from an object's prototype chain are not considered. - -Changes to arrays are recorded simplistically. We care most about the shape of the structure; therefore we don't take the time to determine if an object moved from one slot in the array to another. Instead, we only record the structural -differences. If the structural differences are applied from the `comparand` to the `origin` then the two objects will compare as "deep equal" using most `isEqual` implementations such as found in [lodash](https://github.com/bestiejs/lodash) or [underscore](http://underscorejs.org/). - -### Changes - -When two objects differ, you can observe the differences as they are calculated and selectively apply those changes to the origin object (left-hand-side). - -``` javascript -var observableDiff = require('deep-diff').observableDiff; -var applyChange = require('deep-diff').applyChange; - -var lhs = { - name: 'my object', - description: 'it\'s an object!', - details: { - it: 'has', - an: 'array', - with: ['a', 'few', 'elements'] - } -}; - -var rhs = { - name: 'updated object', - description: 'it\'s an object!', - details: { - it: 'has', - an: 'array', - with: ['a', 'few', 'more', 'elements', { than: 'before' }] - } -}; - -observableDiff(lhs, rhs, function (d) { - // Apply all changes except to the name property... - if (d.path[d.path.length - 1] !== 'name') { - applyChange(lhs, rhs, d); - } -}); -``` - -## API Documentation - -A standard import of `var diff = require('deep-diff')` is assumed in all of the code examples. The import results in an object having the following public properties: - -* `diff(lhs, rhs[, options, acc])` — calculates the differences between two objects, optionally using the specified accumulator. -* `observableDiff(lhs, rhs, observer[, options])` — calculates the differences between two objects and reports each to an observer function. -* `applyDiff(target, source, filter)` — applies any structural differences from a source object to a target object, optionally filtering each difference. -* `applyChange(target, source, change)` — applies a single change record to a target object. NOTE: `source` is unused and may be removed. -* `revertChange(target, source, change)` reverts a single change record to a target object. NOTE: `source` is unused and may be removed. - -### `diff` - -The `diff` function calculates the difference between two objects. - - -#### Arguments - -* `lhs` - the left-hand operand; the origin object. -* `rhs` - the right-hand operand; the object being compared structurally with the origin object. -* `options` - A configuration object that can have the following properties: - - `prefilter`: function that determines whether difference analysis should continue down the object graph. This function can also replace the `options` object in the parameters for backward compatibility. - - `normalize`: function that pre-processes every _leaf_ of the tree. -* `acc` - an optional accumulator/array (requirement is that it have a `push` function). Each difference is pushed to the specified accumulator. - -Returns either an array of changes or, if there are no changes, `undefined`. This was originally chosen so the result would be pass a truthy test: - -```javascript -var changes = diff(obja, objb); -if (changes) { - // do something with the changes. -} -``` - -#### Pre-filtering Object Properties - -The `prefilter`'s signature should be `function(path, key)` and it should return a truthy value for any `path`-`key` combination that should be filtered. If filtered, the difference analysis does no further analysis of on the identified object-property path. - -```javascript -const diff = require('deep-diff'); -const assert = require('assert'); - -const data = { - issue: 126, - submittedBy: 'abuzarhamza', - title: 'readme.md need some additional example prefilter', - posts: [ - { - date: '2018-04-16', - text: `additional example for prefilter for deep-diff would be great. - https://stackoverflow.com/questions/38364639/pre-filter-condition-deep-diff-node-js` - } - ] -}; - -const clone = JSON.parse(JSON.stringify(data)); -clone.title = 'README.MD needs additional example illustrating how to prefilter'; -clone.disposition = 'completed'; - -const two = diff(data, clone); -const none = diff(data, clone, - (path, key) => path.length === 0 && ~['title', 'disposition'].indexOf(key) -); - -assert.equal(two.length, 2, 'should reflect two differences'); -assert.ok(typeof none === 'undefined', 'should reflect no differences'); -``` -#### Normalizing object properties - -The `normalize`'s signature should be `function(path, key, lhs, rhs)` and it should return either a falsy value if no normalization has occured, or a `[lhs, rhs]` array to replace the original values. This step doesn't occur if the path was filtered out in the `prefilter` phase. - -```javascript -const diff = require('deep-diff'); -const assert = require('assert'); - -const data = { - pull: 149, - submittedBy: 'saveman71', -}; - -const clone = JSON.parse(JSON.stringify(data)); -clone.issue = 42; - -const two = diff(data, clone); -const none = diff(data, clone, { - normalize: (path, key, lhs, rhs) => { - if (lhs === 149) { - lhs = 42; - } - if (rhs === 149) { - rhs = 42; - } - return [lsh, rhs]; - } -}); - -assert.equal(two.length, 1, 'should reflect one difference'); -assert.ok(typeof none === 'undefined', 'should reflect no difference'); -``` - -### `observableDiff` - -The `observableDiff` function calculates the difference between two objects and reports each to an observer function. - -#### Argmuments - -* `lhs` - the left-hand operand; the origin object. -* `rhs` - the right-hand operand; the object being compared structurally with the origin object. -* `observer` - The observer to report to. -* `options` - A configuration object that can have the following properties: - - `prefilter`: function that determines whether difference analysis should continue down the object graph. This function can also replace the `options` object in the parameters for backward compatibility. - - `normalize`: function that pre-processes every _leaf_ of the tree. - -## Contributing - -When contributing, keep in mind that it is an objective of `deep-diff` to have no package dependencies. This may change in the future, but for now, no-dependencies. - -Please run the unit tests before submitting your PR: `npm test`. Hopefully your PR includes additional unit tests to illustrate your change/modification! +## Breaking Changes; v2.x IS NOT Backwards Compatible with v1.x -When you run `npm test`, linting will be performed and any linting errors will fail the tests... this includes code formatting. +> After more than 11 years, we chose to rebuild from scratch, the way we would code it today. If you've been around Node.js as long as we have, you've witnessed many great improvements in the way Javascript is written, and an evolution in the prevailing idioms. Since we chose to take on some of the more intense issues reported over the years, particularly how we report on array changes, we decided a rewrite was in order. Along the way, we purposely broke backward compatibility so we could grow the features. Github indicates this library is used by 300K projects... hopefully this new version also proves useful. -> Thanks to all those who have contributed so far! +... diff --git a/dist/deep-diff.min.js b/dist/deep-diff.min.js deleted file mode 100644 index 6172a98..0000000 --- a/dist/deep-diff.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){var n=function(e){var l=["N","E","A","D"];function t(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}function n(e,t){Object.defineProperty(this,"kind",{value:e,enumerable:!0}),t&&t.length&&Object.defineProperty(this,"path",{value:t,enumerable:!0})}function D(e,t,n){D.super_.call(this,"E",e),Object.defineProperty(this,"lhs",{value:t,enumerable:!0}),Object.defineProperty(this,"rhs",{value:n,enumerable:!0})}function k(e,t){k.super_.call(this,"N",e),Object.defineProperty(this,"rhs",{value:t,enumerable:!0})}function j(e,t){j.super_.call(this,"D",e),Object.defineProperty(this,"lhs",{value:t,enumerable:!0})}function O(e,t,n){O.super_.call(this,"A",e),Object.defineProperty(this,"index",{value:t,enumerable:!0}),Object.defineProperty(this,"item",{value:n,enumerable:!0})}function f(e,t,n){var r=e.slice((n||t)+1||e.length);return e.length=t<0?e.length+t:t,e.push.apply(e,r),e}function w(e){var t=typeof e;return"object"!==t?t:e===Math?"math":null===e?"null":Array.isArray(e)?"array":"[object Date]"===Object.prototype.toString.call(e)?"date":"function"==typeof e.toString&&/^\/.*\//.test(e.toString())?"regexp":"object"}function u(e){var t=0;if(0===e.length)return t;for(var n=0;n Phase2 - 'id': 'Phase2', - 'tasks': [ - { 'id': 'Task3' } - ] - }, { - 'id': 'Phase1', - 'tasks': [ - { 'id': 'Task1' }, - { 'id': 'Task2' } - ] - }] -}; - -var diff = deep.diff(lhs, rhs); -console.log(util.inspect(diff, false, 9)); // eslint-disable-line no-console - -deep.applyDiff(lhs, rhs); -console.log(util.inspect(lhs, false, 9)); // eslint-disable-line no-console - -expect(lhs).to.be.eql(rhs); - diff --git a/examples/capture_change_apply_elsewhere.js b/examples/capture_change_apply_elsewhere.js deleted file mode 100644 index 7a91084..0000000 --- a/examples/capture_change_apply_elsewhere.js +++ /dev/null @@ -1,53 +0,0 @@ -/*jshint indent:2, laxcomma:true, laxbreak:true*/ -var util = require('util') -, assert = require('assert') -, diff = require('..') -, data = require('./practice-data') -; - -var i = Math.floor(Math.random() * data.length) + 1; -var j = Math.floor(Math.random() * data.length) + 1; - -while (j === i) { - j = Math.floor(Math.random() * data.length) + 1; -} - -var source = data[i]; -var comparand = data[j]; - -// source and comparand are different objects -assert.notEqual(source, comparand); - -// source and comparand have differences in their structure -assert.notDeepEqual(source, comparand); - -// record the differences between source and comparand -var changes = diff(source, comparand); - -// apply the changes to the source -changes.forEach(function (change) { - diff.applyChange(source, true, change); -}); - -// source and copmarand are now deep equal -assert.deepEqual(source, comparand); - -// Simulate serializing to a remote copy of the object (we've already go a copy, copy the changes)... - -var remote = JSON.parse(JSON.stringify(source)); -var remoteChanges = JSON.parse(JSON.stringify(changes)); - -// source and remote are different objects -assert.notEqual(source, remote); - -// changes and remote changes are different objects -assert.notEqual(changes, remoteChanges); - -// remote and comparand are different objects -assert.notEqual(remote, comparand); - -remoteChanges.forEach(function (change) { - diff.applyChange(remote, true, change); -}); - -assert.deepEqual(remote, comparand); diff --git a/examples/diff-ignoring-fun.js b/examples/diff-ignoring-fun.js deleted file mode 100644 index d65781b..0000000 --- a/examples/diff-ignoring-fun.js +++ /dev/null @@ -1,88 +0,0 @@ -/*jshint indent:2, laxcomma:true, laxbreak:true*/ -var util = require('util') -, deep = require('..') -; - -function duckWalk() { - util.log('right step, left-step, waddle'); -} - -function quadrapedWalk() { - util.log('right hind-step, right fore-step, left hind-step, left fore-step'); -} - -var duck = { - legs: 2, - walk: duckWalk -}; - -var dog = { - legs: 4, - walk: quadrapedWalk -}; - -var diff = deep.diff(duck, dog); - -// The differences will include the legs, and walk. -util.log('Differences:\r\n' + util.inspect(diff, false, 9)); - - -// To ignore behavioral differences (functions); use observableDiff and your own accumulator: - -var observed = []; -deep.observableDiff(duck, dog, function (d) { - if (d && d.lhs && typeof d.lhs !== 'function') { - observed.push(d); - } -}); - -util.log('Observed without recording functions:\r\n' + util.inspect(observed, false, 9)); - -util.log(util.inspect(dog, false, 9) + ' walking: '); -dog.walk(); - -// The purpose of the observableDiff fn is to allow you to observe and apply differences -// that make sense in your scenario... - -// We'll make the dog act like a duck... -deep.observableDiff(dog, duck, function (d) { - deep.applyChange(dog, duck, d); -}); - -util.log(util.inspect(dog, false, 9) + ' walking: '); -dog.walk(); - -// Now there are no differences between the duck and the dog: -if (deep.diff(duck, dog)) { - util.log("Ooops, that prior statement seems to be wrong! (but it won't be)"); -} - -// Now assign an "equivalent" walk function... -dog.walk = function duckWalk() { - util.log('right step, left-step, waddle'); -}; - -if (diff = deep.diff(duck, dog)) { - // The dog's walk function is an equivalent, but different duckWalk function. - util.log('Hrmm, the dog walks differently: ' + util.inspect(diff, false, 9)); -} - -// Use the observableDiff fn to ingore based on behavioral equivalence... - -observed = []; -deep.observableDiff(duck, dog, function (d) { - // if the change is a function, only record it if the text of the fns differ: - if (d && typeof d.lhs === 'function' && typeof d.rhs === 'function') { - var leftFnText = d.lhs.toString(); - var rightFnText = d.rhs.toString(); - if (leftFnText !== rightFnText) { - observed.push(d); - } - } else { - observed.push(d); - } -}); - -if (observed.length === 0) { - util.log('Yay!, we detected that the walk functions are equivalent'); -} \ No newline at end of file diff --git a/examples/diff-scenarios.js b/examples/diff-scenarios.js deleted file mode 100644 index faa7e07..0000000 --- a/examples/diff-scenarios.js +++ /dev/null @@ -1,49 +0,0 @@ -var util = require('util'), -expect = require('expect.js'), -eql = require('deep-equal'), -deep = require('..') -extend = util._extend; -diff = deep.diff, -apply = deep.applyDiff; - -function f0() {}; -function f1() {}; - -var one = { it: 'be one', changed: false, with: { nested: 'data'}, f: f1}; -var two = { it: 'be two', updated: true, changed: true, with: {nested: 'data', and: 'other', plus: one} }; -var circ = {}; -var other = { it: 'be other', numero: 34.29, changed: [ { it: 'is the same' }, 13.3, 'get some' ], with: {nested: 'reference', plus: circ} }; -var circular = extend(circ, { it: 'be circ', updated: false, changed: [ { it: 'is not same' }, 13.3, 'get some!', {extra: 'stuff'}], with: { nested: 'reference', circular: other } }); - -util.log(util.inspect(diff(one, two), false, 99)); -util.log(util.inspect(diff(two, one), false, 99)); - -util.log(util.inspect(diff(other, circular), false, 99)); - -var clone = extend({}, one); -apply(clone, two); -util.log(util.inspect(clone, false, 99)); - -expect(eql(clone, two)).to.be(true); -expect(eql(clone, one)).to.be(false); - -clone = extend({}, circular); -apply(clone, other); -util.log(util.inspect(clone, false, 99)); -expect(eql(clone, other)).to.be(true); -expect(eql(clone, circular)).to.be(false); - - -var array = { name: 'array two levels deep', item: { arr: ['it', { has: 'data' }]}}; -var arrayChange = { name: 'array change two levels deep', item: { arr: ['it', { changes: 'data' }]}}; - -util.log(util.inspect(diff(array, arrayChange), false, 99)); -clone = extend({}, array); -apply(clone, arrayChange); -util.log(util.inspect(clone, false, 99)); -expect(eql(clone, arrayChange)).to.be(true); - -var one_prop = { one: 'property' }; -var d = diff(one_prop, {}); -expect(d.length).to.be(1); - diff --git a/examples/equality-dates.js b/examples/equality-dates.js new file mode 100644 index 0000000..70d213e --- /dev/null +++ b/examples/equality-dates.js @@ -0,0 +1,29 @@ +import { ok } from 'assert'; + +const subject = new Date(); +const equalComparand = new Date(subject.valueOf()); +const unequalComparand = new Date(subject.valueOf() + 1); + +/** + * Dates can be monkey patched, so modifications to structure are + * possible, even though doing so is suspect (probably an anti-pattern)! + */ +const monkeyPatched = new Date(subject.valueOf()); +monkeyPatched.foo = 'bar'; +monkeyPatched['patched'] = true; + +const equal = (left, right) => left.valueOf() === right.valueOf(); + +ok(equal(subject, equalComparand), 'should be equal'); +ok(!equal(subject, unequalComparand), 'should be unequal'); + +// The monkey patched date still shows equal, even though it is +// patched!! +ok(equal(subject, equalComparand), 'should be equal'); +ok(monkeyPatched.foo === 'bar', 'should be monkey patched'); +ok(monkeyPatched['patched'], 'should be monkey patched'); + +// Verify that the properties attached to a Date are +// discoverable as structure... +const props = Object.getOwnPropertyNames(monkeyPatched); +ok(props.length === 2, 'has our two patched properties'); diff --git a/examples/example1.js b/examples/example1.js deleted file mode 100644 index 169e9dc..0000000 --- a/examples/example1.js +++ /dev/null @@ -1,41 +0,0 @@ -var util = require('util') -, deep = require('..') -; - -var lhs = { - name: 'my object', - description: 'it\'s an object!', - details: { - it: 'has', - an: 'array', - with: ['a', 'few', 'elements'] - } -}; - -var rhs = { - name: 'updated object', - description: 'it\'s an object!', - details: { - it: 'has', - an: 'array', - with: ['a', 'few', 'more', 'elements', { than: 'before' }] - } -}; - -var differences = deep.diff(lhs, rhs); - -// Print the differences to the console... -util.log(util.inspect(differences, false, 99)); - -deep.observableDiff(lhs, rhs, function (d) { - // Apply all changes except those to the 'name' property... - if (d.path.length !== 1 || d.path.join('.') !== 'name') { - deep.applyChange(lhs, rhs, d); - } -}, function (path, key) { - var p = (path && path.length) ? path.join('/') : '' - util.log('prefilter: path = ' + p + ' key = ' + key); -} -); - -console.log(util.inspect(lhs, false, 99)); diff --git a/examples/issue-111.js b/examples/issue-111.js deleted file mode 100644 index 1653353..0000000 --- a/examples/issue-111.js +++ /dev/null @@ -1,6 +0,0 @@ -var diff = require('../'); - - -var differences = diff(undefined, undefined); -// eslint-disable-next-line no-console -console.log(differences); diff --git a/examples/issue-113-1.js b/examples/issue-113-1.js deleted file mode 100644 index 5f9662c..0000000 --- a/examples/issue-113-1.js +++ /dev/null @@ -1,14 +0,0 @@ -const { log, inspect } = require('util'); -const assert = require('assert'); -const diff = require('../'); - -const o1 = {}; -const o2 = {}; -o1.foo = o1; -o2.foo = o2; - -assert.notEqual(o1, o2, 'not same object'); -assert.notEqual(o1.foo, o2.foo, 'not same object'); - -const differences = diff(o1, o2); -log(inspect(differences, false, 9)); diff --git a/examples/issue-113-2.js b/examples/issue-113-2.js deleted file mode 100644 index 8a3030d..0000000 --- a/examples/issue-113-2.js +++ /dev/null @@ -1,11 +0,0 @@ -const { log, inspect } = require('util'); -const diff = require('../'); - -var o1 = {}; -var o2 = {}; -o1.foo = o1; -o2.foo = {foo: o2}; -const differences = diff(o1, o2); - -log(inspect(differences, false, 9)); - diff --git a/examples/issue-115.js b/examples/issue-115.js deleted file mode 100644 index c0d5dd0..0000000 --- a/examples/issue-115.js +++ /dev/null @@ -1,17 +0,0 @@ -var diff = require('../'); -var expect = require('expect.js'); - -var thing1 = 'this'; -var thing2 = 'that'; -var thing3 = 'other'; -var thing4 = 'another'; - -var oldArray = [thing1, thing2, thing3, thing4]; -var newArray = [thing1, thing2]; - -diff.observableDiff(oldArray, newArray, - function (d) { - diff.applyChange(oldArray, d); - }); - -expect(oldArray).to.eql(newArray); diff --git a/examples/issue-124.js b/examples/issue-124.js deleted file mode 100644 index 3d192ca..0000000 --- a/examples/issue-124.js +++ /dev/null @@ -1,8 +0,0 @@ -var diff = require('../'); - -var left = { key: [ {A: 0, B: 1}, {A: 2, B: 3} ] }; -var right = { key: [ {A: 9, B: 1}, {A: 2, B: 3} ] }; - -var differences = diff(left, right); -// eslint-disable-next-line no-console -console.log(differences); diff --git a/examples/issue-125.js b/examples/issue-125.js deleted file mode 100644 index c05da9c..0000000 --- a/examples/issue-125.js +++ /dev/null @@ -1,19 +0,0 @@ -var diff = require('../'); - -const left = { - nested: { - param1: null, - param2: null - } -}; - -const right = { - nested: { - param1: null, - param2: null - } -}; - -var differences = diff(left, right); -// eslint-disable-next-line no-console -console.log(differences); diff --git a/examples/issue-126.js b/examples/issue-126.js deleted file mode 100644 index c8cbc26..0000000 --- a/examples/issue-126.js +++ /dev/null @@ -1,33 +0,0 @@ -// This example shows how prefiltering can be used. - -const diff = require('../'); // deep-diff -const { log, inspect } = require('util'); -const assert = require('assert'); - -const data = { - issue: 126, - submittedBy: 'abuzarhamza', - title: 'readme.md need some additional example prefilter', - posts: [ - { - date: '2018-04-16', - text: `additional example for prefilter for deep-diff would be great. - https://stackoverflow.com/questions/38364639/pre-filter-condition-deep-diff-node-js` - } - ] -}; - -const clone = JSON.parse(JSON.stringify(data)); -clone.title = 'README.MD needs additional example illustrating how to prefilter'; -clone.disposition = 'completed'; - -const two = diff(data, clone); -const none = diff(data, clone, - (path, key) => path.length === 0 && ~['title', 'disposition'].indexOf(key) -); - -assert.equal(two.length, 2, 'should reflect two differences'); -assert.ok(typeof none === 'undefined', 'should reflect no differences'); - -log(inspect(two, false, 9)); -log(inspect(none, false, 9)); diff --git a/examples/issue-35.js b/examples/issue-35.js deleted file mode 100644 index 088916e..0000000 --- a/examples/issue-35.js +++ /dev/null @@ -1,11 +0,0 @@ -var deep = require('../'); - -var lhs = ['a', 'a']; -var rhs = ['a']; -var differences = deep.diff(lhs, rhs); -differences.forEach(function (change) { - deep.applyChange(lhs, true, change); -}); - -console.log(lhs); // eslint-disable-line no-console -console.log(rhs); // eslint-disable-line no-console diff --git a/examples/issue-47.js b/examples/issue-47.js deleted file mode 100644 index 28b18b1..0000000 --- a/examples/issue-47.js +++ /dev/null @@ -1,17 +0,0 @@ -var diff = require('../'); -var expect = require('expect.js'); - -var thing1 = 'this'; -var thing2 = 'that'; -var thing3 = 'other'; -var thing4 = 'another'; - -var oldArray = [thing1, thing2, thing3, thing4]; -var newArray = [thing1, thing2]; - -diff.observableDiff(oldArray, newArray, - function (d) { - diff.applyChange(oldArray, newArray, d); - }); - -expect(oldArray).to.eql(newArray); diff --git a/examples/issue-48.js b/examples/issue-48.js deleted file mode 100644 index 6daf94e..0000000 --- a/examples/issue-48.js +++ /dev/null @@ -1,48 +0,0 @@ - -var dd = require('../'); // deep-diff -var inspect = require('util').inspect; -var expect = require('expect.js'); - -var before = { - name: 'my object', - description: 'it\'s an object!', - details: { - it: 'has', - an: 'array', - with: ['a', 'few', 'elements'] - } -}; - -var after = { - name: 'updated object', - description: 'it\'s an object!', - details: { - it: 'has', - an: 'array', - with: ['a', 'few', 'more', 'elements', { than: 'before' }] - } -}; - -var revertDiff = function (src, d) { - d.forEach(function (change) { - dd.revertChange(src, true, change); - }); - return src; -}; - -var clone = function (src) { - return JSON.parse(JSON.stringify(src)); -}; - -var df = dd.diff(before, after); -var b1 = clone(before); -var a1 = clone(after); - -console.log(inspect(a1, false, 9)); // eslint-disable-line no-console - -var reverted = revertDiff(a1, df); -console.log(inspect(reverted, false, 9)); // eslint-disable-line no-console -console.log(inspect(b1, false, 9)); // eslint-disable-line no-console - -expect(reverted).to.eql(b1); - diff --git a/examples/issue-62.js b/examples/issue-62.js deleted file mode 100644 index 51b6e8d..0000000 --- a/examples/issue-62.js +++ /dev/null @@ -1,14 +0,0 @@ -var deep = require("../"); - -// https://github.com/flitbit/diff/issues/62#issuecomment-229549984 -// 3: appears to be fixed, probably in fixing #74. - -var a = {}; -var b = {}; -a.x = b; -b.x = b; -deep.diff(a, b); // True - -a.x = a; // Change to a -// No change to b -console.log(deep.diff(a, b)); // Still true... diff --git a/examples/issue-70.js b/examples/issue-70.js deleted file mode 100644 index 646343d..0000000 --- a/examples/issue-70.js +++ /dev/null @@ -1,6 +0,0 @@ -var deepDiff = require('../'); - -var left = {foo: undefined}; -var right = {}; - -console.log(deepDiff.diff(left, right)); // eslint-disable-line no-console diff --git a/examples/issue-71.js b/examples/issue-71.js deleted file mode 100644 index d030bc0..0000000 --- a/examples/issue-71.js +++ /dev/null @@ -1,15 +0,0 @@ -var diff = require('../'); - -var left = { - left: 'yes', - right: 'no', -}; - -var right = { - left: { - toString: true, - }, - right: 'no', -}; - -console.log(diff(left, right)); // eslint-disable-line no-console diff --git a/examples/issue-72.js b/examples/issue-72.js deleted file mode 100644 index 674e162..0000000 --- a/examples/issue-72.js +++ /dev/null @@ -1,21 +0,0 @@ -var diff = require('../'); - -var before = { - data: [1, 2, 3] -}; - -var after = { - data: [4, 5, 1] -}; - -var differences = diff(before, after); -console.log(differences); // eslint-disable-line no-console -differences.reduce( - (acc, change) => { - diff.revertChange(acc, true, change); - return acc; - }, - after -); - -console.log(after); // eslint-disable-line no-console diff --git a/examples/issue-74.js b/examples/issue-74.js deleted file mode 100644 index 55c5c1f..0000000 --- a/examples/issue-74.js +++ /dev/null @@ -1,9 +0,0 @@ -var deepDiff = require("../"); - -var a = {prop: {}}; -var b = {prop: {}}; - -a.prop.circ = a.prop; -b.prop.circ = b; - -console.log(deepDiff.diff(a, b)); diff --git a/examples/issue-78.js b/examples/issue-78.js deleted file mode 100644 index 86b6945..0000000 --- a/examples/issue-78.js +++ /dev/null @@ -1,24 +0,0 @@ - -const diff = require('../'); -const ptr = require('json-ptr'); - -const inspect = require('util').inspect; - - -const objA = { array: [{ a: 1 }] }; -const objB = { array: [{ a: 2 }] }; - -let changes = diff(objA, objB); -if (changes) { - // decorate the changes using json-pointers - for (let i = 0; i < changes.length; ++i) { - let change = changes[i]; - // get the parent path: - let pointer = ptr.create(change.path.slice(0, change.path.length - 1)); - if (change.kind === 'E') { - change.elementLeft = pointer.get(objA); - change.elementRight = pointer.get(objB); - } - } -} -console.log(inspect(changes, false, 9)); // eslint-disable-line no-console diff --git a/examples/issue-83.js b/examples/issue-83.js deleted file mode 100644 index e70736c..0000000 --- a/examples/issue-83.js +++ /dev/null @@ -1,11 +0,0 @@ -var deepDiff = require("../"); - -var left = { - date: null -}; - -var right = { - date: null -}; - -console.log(deepDiff(left, right)); diff --git a/examples/issue-88.js b/examples/issue-88.js deleted file mode 100644 index f74cbb3..0000000 --- a/examples/issue-88.js +++ /dev/null @@ -1,26 +0,0 @@ -var diff = require("../"); - -var before = { - length: 3, - data: [1, 2, 3] -}; - -var after = { - data: [4, 5, 1, 2, 3], - count: 5 -}; - -var differences = diff(before, after); -console.log(differences); - -function applyChanges(target, changes) { - return changes.reduce( - (acc, change) => { - diff.applyChange(acc, true, change); - return acc; - }, - target - ); -} - -console.log(applyChanges(before, differences)); diff --git a/examples/performance.js b/examples/performance.js deleted file mode 100644 index 760b567..0000000 --- a/examples/performance.js +++ /dev/null @@ -1,64 +0,0 @@ -var util = require('util') - , diff = require('..') - , data = require('./practice-data') - ; - -var cycle = -1 - , i - , len = data.length - , prior = {} - , comparand - , records - , roll = [] - , stat - , stats = [] - , mark, elapsed, avg = { diff: { ttl: 0 }, apply: { ttl: 0 } }, ttl = 0 - ; - -mark = process.hrtime(); -while (++cycle < 10) { - i = -1; - while (++i < len) { - stats.push(stat = { mark: process.hrtime() }); - - comparand = roll[i] || data[i]; - - stat.diff = { mark: process.hrtime() }; - records = diff(prior, comparand); - stat.diff.intv = process.hrtime(stat.diff.mark); - - if (records) { - stat.apply = { count: diff.length, mark: process.hrtime() }; - records.forEach(function (ch) { - diff.applyChange(prior, comparand, ch); - }); - stat.apply.intv = process.hrtime(stat.apply.mark); - - prior = comparand; - } - stat.intv = process.hrtime(stat.mark); - } -} - -function ms(intv) { - return (intv[0] * 1e9 + intv[1] / 1e6); -} -elapsed = ms(process.hrtime(mark)); - -stats.forEach(function (stat) { - stat.elapsed = ms(stat.intv); - stat.diff.elapsed = ms(stat.diff.intv); - avg.diff.ttl += stat.diff.elapsed; - if (stat.apply) { - stat.apply.elapsed = ms(stat.apply.intv); - ttl += stat.apply.count; - avg.apply.ttl += stat.apply.elapsed; - } -}); - -avg.diff.avg = avg.diff.ttl / ttl; -avg.apply.avg = avg.apply.ttl / ttl; - -console.log('Captured '.concat(stats.length, ' samples with ', ttl, ' combined differences in ', elapsed, 'ms')); -console.log('\tavg diff: '.concat(avg.diff.avg, 'ms or ', (1 / avg.diff.avg), ' per ms')); -console.log('\tavg apply: '.concat(avg.apply.avg, 'ms or ', (1 / avg.apply.avg), ' per ms')); diff --git a/examples/practice-data.json b/examples/practice-data.json deleted file mode 100644 index 99fddd6..0000000 --- a/examples/practice-data.json +++ /dev/null @@ -1,2501 +0,0 @@ -[ -{ "id": "9054949423", "owner": "81035653@N00", "secret": "b7bbe7d0cc", "server": "2862", "farm": 3, "title": "The green pearl - Lago d'Idro", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9079687571", "owner": "53731740@N07", "secret": "af4b8f43f6", "server": "7353", "farm": 8, "title": "Beautiful Swimsuit Bikini Model Goddess", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "6610177315", "owner": "97042891@N00", "secret": "29653ab1e9", "server": "7013", "farm": 8, "title": "Réveillon no Rio de Janeiro", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "5307511113", "owner": "97042891@N00", "secret": "4cbdb71883", "server": "5205", "farm": 6, "title": "Copacabana - Rio de Janeiro", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "4782392857", "owner": "97042891@N00", "secret": "d8d85c3f30", "server": "4095", "farm": 5, "title": "Copacabana - Corcovado - Pão de Açúcar - Brasil - Rio de Janeiro - Brazil", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9080427184", "owner": "47181226@N05", "secret": "a019bdfcc9", "server": "7310", "farm": 8, "title": "crabs on the run", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9077457107", "owner": "53731740@N07", "secret": "3ee900a5c5", "server": "5445", "farm": 6, "title": "Nikon D800E Photos Swimsuit Bikini Model Goddess! Pretty Green Eyes! 70-200mm F\/2.8 VR2 Nikkor Lens", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9079678790", "owner": "53731740@N07", "secret": "b64a41ee7c", "server": "3679", "farm": 4, "title": "Nikon D800E Photos Swimsuit Bikini Model Goddess! Pretty Green Eyes! 70-200mm F\/2.8 VR2 Nikkor Lens", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9078269539", "owner": "35935175@N04", "secret": "98c7d82d11", "server": "7313", "farm": 8, "title": "Red Knot", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9080223572", "owner": "81885676@N02", "secret": "7db667f866", "server": "3817", "farm": 4, "title": "The beach at Crammond", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9079434148", "owner": "16257364@N00", "secret": "24a576e406", "server": "5501", "farm": 6, "title": "~", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9071956136", "owner": "68313625@N04", "secret": "ca92d4837a", "server": "3692", "farm": 4, "title": "\"Oh the weather outside is frightful..\"", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9074880533", "owner": "92109112@N05", "secret": "497c4735bf", "server": "2829", "farm": 3, "title": "Sunrise clouds", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "5035221176", "owner": "27112342@N03", "secret": "15134354f7", "server": "4111", "farm": 5, "title": "A New Day is born, where there is no gender divide or generation gap...... All are here to play their game.....!", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9017742627", "owner": "36621592@N06", "secret": "d5af918c8c", "server": "7381", "farm": 8, "title": "Live", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9074391718", "owner": "10496603@N07", "secret": "c0861538af", "server": "7300", "farm": 8, "title": "Populuxe", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9071881751", "owner": "31714338@N07", "secret": "28086ea55d", "server": "7355", "farm": 8, "title": "pier reflection", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9073978544", "owner": "43500152@N03", "secret": "2c625172c1", "server": "2833", "farm": 3, "title": "Brutal", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9070839229", "owner": "51298252@N04", "secret": "430004787b", "server": "7283", "farm": 8, "title": "Evening at Cable Beach", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "8328505657", "owner": "97042891@N00", "secret": "3a4bb104f4", "server": "8216", "farm": 9, "title": "Show de fogos Copacabana - dicas para o Reveillon 2013", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "40296604", "owner": "97042891@N00", "secret": "f657fefda1", "server": 31, "farm": 1, "title": "Foto do Pão de Açúcar e Aterro - Rio de Janeiro - Brasil", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "7283042946", "owner": "97042891@N00", "secret": "cbaa09dc81", "server": "8017", "farm": 9, "title": "Foto da Praia da Barra da Tijuca", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "7517176676", "owner": "97042891@N00", "secret": "bf1ccfea2a", "server": "8293", "farm": 9, "title": "Reveillon em Copacabana 120 anos da Princesinha do Mar", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "7038965665", "owner": "97042891@N00", "secret": "11048fbc5d", "server": "7264", "farm": 8, "title": "Vista Chinesa RJ - Pão de Açúcar", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "3841805569", "owner": "97042891@N00", "secret": "b902b7a3a0", "server": "2623", "farm": 3, "title": "Parque da Cidade - Niterói - Morro da Viração - Rio de Janeiro - Brasil - Pão de Açúcar - Corcovado", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "2300837831", "owner": "97042891@N00", "secret": "a1bc05c959", "server": "2317", "farm": 3, "title": "Rio de Janeiro - Brasil - Rio - Brazil Rio 2016 - Cristo Redentor - Carnaval - samba - futebol - praia - carnival - football - beach", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "7881804566", "owner": "97042891@N00", "secret": "a817458766", "server": "8286", "farm": 9, "title": "Baia de Guanabara fotografada do Parque das Ruínas", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "8068824212", "owner": "97042891@N00", "secret": "520822b9e4", "server": "8459", "farm": 9, "title": "Crepúsculo dos Deuses - Twilight - Corcovado", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9067335291", "owner": "89311841@N04", "secret": "f468dfdac0", "server": "7417", "farm": 8, "title": "Sizzle", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "2836360729", "owner": "8398907@N02", "secret": "6500249fe6", "server": "3005", "farm": 4, "title": "California Sea Monster, Beware, Dangerous When Fed Cookies", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9066505445", "owner": "37414352@N02", "secret": "64d929d087", "server": "7338", "farm": 8, "title": "Spring reflection with trees [Explored]", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9066505955", "owner": "18481658@N00", "secret": "113aa0e954", "server": "2879", "farm": 3, "title": "No darkness.", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9059262373", "owner": "63583522@N00", "secret": "2c86a6deee", "server": "3701", "farm": 4, "title": "The sound of the sea helps me get back to me.", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9061831696", "owner": "16047105@N06", "secret": "48e60f29a3", "server": "7293", "farm": 8, "title": "Kiss", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9059432313", "owner": "31276818@N00", "secret": "4aacc2a146", "server": "7399", "farm": 8, "title": "Fort Lauderdale Sunrise", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9060254778", "owner": "24926969@N05", "secret": "2ccfb99596", "server": "7383", "farm": 8, "title": "Magic Hour at High Water", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9059948996", "owner": "9372441@N07", "secret": "951fb82dae", "server": "7453", "farm": 8, "title": "Pink Sands by Michael Anderson", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9059381276", "owner": "51038094@N04", "secret": "f09622043f", "server": "3816", "farm": 4, "title": "Clevedon Pier Panoramic", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "7827632540", "owner": "27112342@N03", "secret": "0883aa7aff", "server": "8429", "farm": 9, "title": "Sun Set Time....Nostalgia of Sun Rise Days....", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "3384971924", "owner": "29958169@N03", "secret": "f4a5637584", "server": "3589", "farm": 4, "title": "Kaos", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9055322469", "owner": "57866871@N03", "secret": "dd9d311f4b", "server": "5479", "farm": 6, "title": "Spectral Sennen", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9052241661", "owner": "47405810@N03", "secret": "e4aa29875b", "server": "3775", "farm": 4, "title": "One in~One out", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9054641866", "owner": "14838182@N00", "secret": "b0b8796c97", "server": "5468", "farm": 6, "title": "Good hair", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9052419229", "owner": "14838182@N00", "secret": "ddb492a3a2", "server": "7290", "farm": 8, "title": "Stranger portraits #14", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9050957778", "owner": "61348844@N07", "secret": "0cb4fa4554", "server": "5346", "farm": 6, "title": "Hot brazilian Ebony", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9047443891", "owner": "30725488@N00", "secret": "63b0cd3284", "server": "2877", "farm": 3, "title": "The stone collector", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9047234767", "owner": "20687176@N04", "secret": "d5b3217420", "server": "2832", "farm": 3, "title": "Cabrera, Dominican Republic - Playa Grande Beach", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9045745347", "owner": "76972962@N05", "secret": "0a9dfccf01", "server": "7424", "farm": 8, "title": "Twilight at Mile Rock", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9047059358", "owner": "63702571@N04", "secret": "3f64dd6ce3", "server": "7447", "farm": 8, "title": "Improving The View", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9044438287", "owner": "16234243@N04", "secret": "afaf8de5e5", "server": "3744", "farm": 4, "title": "Morning at Arran", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9044038979", "owner": "59847542@N07", "secret": "157dd6e123", "server": "5455", "farm": 6, "title": "Summer Nights", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9045069536", "owner": "75429033@N04", "secret": "418597b8b0", "server": "5540", "farm": 6, "title": "[Granular fluid]", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9044608692", "owner": "25804543@N05", "secret": "3369c5587e", "server": "2864", "farm": 3, "title": "", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9044545062", "owner": "67667390@N06", "secret": "04790f00fe", "server": "7415", "farm": 8, "title": "Tranquility @ Swanage Beach, Dorset", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9042214783", "owner": "79581571@N03", "secret": "81204e122d", "server": "7343", "farm": 8, "title": "Where Water Used to Be", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9043740430", "owner": "32489835@N06", "secret": "0cdee73d75", "server": "7397", "farm": 8, "title": "tranquility", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9041130127", "owner": "66907392@N08", "secret": "44ed2d0d9d", "server": "3716", "farm": 4, "title": "Suene Fernandes", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9040143583", "owner": "28192937@N04", "secret": "859389aa21", "server": "5514", "farm": 6, "title": "Memory Cove", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "6795895843", "owner": "55066757@N02", "secret": "8315d4bdc5", "server": "7175", "farm": 8, "title": "emergency", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9035411549", "owner": "10594243@N08", "secret": "82f499865d", "server": "5501", "farm": 6, "title": "BATHERS", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9039503906", "owner": "51919822@N05", "secret": "3b9b6bae82", "server": "7291", "farm": 8, "title": "Seaside Park at Okinawa 沖繩海博館濱海公園", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9038612386", "owner": "38175531@N06", "secret": "767cae0a5f", "server": "7326", "farm": 8, "title": "that life", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9036141477", "owner": "50987838@N06", "secret": "90a79070ed", "server": "7283", "farm": 8, "title": "June... at last", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9035941453", "owner": "30330906@N04", "secret": "3586dfbd65", "server": "3757", "farm": 4, "title": "Morro de Sao Paulo 34", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9038029538", "owner": "10822427@N04", "secret": "688a7dce38", "server": "2866", "farm": 3, "title": "night", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "6221748142", "owner": "25134615@N03", "secret": "36a3437a4b", "server": "6050", "farm": 7, "title": "Israel - The Past is Here", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9032192043", "owner": "10734133@N02", "secret": "e17ea45db8", "server": "7312", "farm": 8, "title": "the blue basket", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9033751885", "owner": "62590398@N07", "secret": "5ecce84c7e", "server": "7437", "farm": 8, "title": "On having fallen down the night", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9034301476", "owner": "75800169@N02", "secret": "14f189b3fe", "server": "7381", "farm": 8, "title": "Cloud Glow", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9034123038", "owner": "15778088@N00", "secret": "88d4d7986e", "server": "7322", "farm": 8, "title": "return to maui, part five", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9031535073", "owner": "64129555@N02", "secret": "e968f22ee6", "server": "5331", "farm": 6, "title": "edv13947", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9033602456", "owner": "39208733@N02", "secret": "4501f64401", "server": "5446", "farm": 6, "title": "Hook revisited", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9033059306", "owner": "29025436@N07", "secret": "fdf0765ece", "server": "5350", "farm": 6, "title": "1910 MODEL YACHT ON POND CLAPTON COMMON LONDON", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9027363202", "owner": "94046364@N00", "secret": "5cee1e8825", "server": "3693", "farm": 4, "title": "Ti Salverò, da ogni Malinconia", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9029600931", "owner": "57910711@N07", "secret": "6f09a449bb", "server": "2845", "farm": 3, "title": "Camille", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9031564334", "owner": "42918851@N00", "secret": "4d5d523116", "server": "2882", "farm": 3, "title": "Watching sunset on a swing. Do zoom in. This is a huge stitch!", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9025926747", "owner": "47181226@N05", "secret": "a7dff59da0", "server": "7417", "farm": 8, "title": "waiting at the edge of the world", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9028130741", "owner": "53731740@N07", "secret": "6534c845eb", "server": "7455", "farm": 8, "title": "Nikon D800 Photos of Tall Blonde Swimsuit Bikini Model Goddess (70-200mm VR2 Nikkor Lens)", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9030317792", "owner": "77514656@N07", "secret": "f586034695", "server": "8547", "farm": 9, "title": "Tunnel Girls", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9030162670", "owner": "42784242@N08", "secret": "fd6e788e3d", "server": "3758", "farm": 4, "title": "Garça-moura - Cocoi Heron", "ispublic": 1, "isfriend": 0, "isfamily": 0}, -{ "id": "9027146766", "owner": "16230743@N06", "secret": "1ffe836bc4", "server": "8542", "farm": 9, "title": "Miam,miam,seulement pour bibi?ha,ah 0) && stack[stack.length - 1].lhs && - Object.getOwnPropertyDescriptor(stack[stack.length - 1].lhs, key)); - var rdefined = rtype !== 'undefined' || - (stack && (stack.length > 0) && stack[stack.length - 1].rhs && - Object.getOwnPropertyDescriptor(stack[stack.length - 1].rhs, key)); - - if (!ldefined && rdefined) { - changes.push(new DiffNew(currentPath, rhs)); - } else if (!rdefined && ldefined) { - changes.push(new DiffDeleted(currentPath, lhs)); - } else if (realTypeOf(lhs) !== realTypeOf(rhs)) { - changes.push(new DiffEdit(currentPath, lhs, rhs)); - } else if (realTypeOf(lhs) === 'date' && (lhs - rhs) !== 0) { - changes.push(new DiffEdit(currentPath, lhs, rhs)); - } else if (ltype === 'object' && lhs !== null && rhs !== null) { - for (i = stack.length - 1; i > -1; --i) { - if (stack[i].lhs === lhs) { - other = true; - break; - } - } - if (!other) { - stack.push({ lhs: lhs, rhs: rhs }); - if (Array.isArray(lhs)) { - // If order doesn't matter, we need to sort our arrays - if (orderIndependent) { - lhs.sort(function (a, b) { - return getOrderIndependentHash(a) - getOrderIndependentHash(b); - }); - - rhs.sort(function (a, b) { - return getOrderIndependentHash(a) - getOrderIndependentHash(b); - }); - } - i = rhs.length - 1; - j = lhs.length - 1; - while (i > j) { - changes.push(new DiffArray(currentPath, i, new DiffNew(undefined, rhs[i--]))); - } - while (j > i) { - changes.push(new DiffArray(currentPath, j, new DiffDeleted(undefined, lhs[j--]))); - } - for (; i >= 0; --i) { - deepDiff(lhs[i], rhs[i], changes, prefilter, currentPath, i, stack, orderIndependent); - } - } else { - var akeys = Object.keys(lhs).concat(Object.getOwnPropertySymbols(lhs)); - var pkeys = Object.keys(rhs).concat(Object.getOwnPropertySymbols(rhs)); - for (i = 0; i < akeys.length; ++i) { - k = akeys[i]; - other = pkeys.indexOf(k); - if (other >= 0) { - deepDiff(lhs[k], rhs[k], changes, prefilter, currentPath, k, stack, orderIndependent); - pkeys[other] = null; - } else { - deepDiff(lhs[k], undefined, changes, prefilter, currentPath, k, stack, orderIndependent); - } - } - for (i = 0; i < pkeys.length; ++i) { - k = pkeys[i]; - if (k) { - deepDiff(undefined, rhs[k], changes, prefilter, currentPath, k, stack, orderIndependent); - } - } - } - stack.length = stack.length - 1; - } else if (lhs !== rhs) { - // lhs is contains a cycle at this element and it differs from rhs - changes.push(new DiffEdit(currentPath, lhs, rhs)); - } - } else if (lhs !== rhs) { - if (!(ltype === 'number' && isNaN(lhs) && isNaN(rhs))) { - changes.push(new DiffEdit(currentPath, lhs, rhs)); - } - } - } - - function observableDiff(lhs, rhs, observer, prefilter, orderIndependent) { - var changes = []; - deepDiff(lhs, rhs, changes, prefilter, null, null, null, orderIndependent); - if (observer) { - for (var i = 0; i < changes.length; ++i) { - observer(changes[i]); - } - } - return changes; - } - - function orderIndependentDeepDiff(lhs, rhs, changes, prefilter, path, key, stack) { - return deepDiff(lhs, rhs, changes, prefilter, path, key, stack, true); - } - - function accumulateDiff(lhs, rhs, prefilter, accum) { - var observer = (accum) ? - function (difference) { - if (difference) { - accum.push(difference); - } - } : undefined; - var changes = observableDiff(lhs, rhs, observer, prefilter); - return (accum) ? accum : (changes.length) ? changes : undefined; - } - - function accumulateOrderIndependentDiff(lhs, rhs, prefilter, accum) { - var observer = (accum) ? - function (difference) { - if (difference) { - accum.push(difference); - } - } : undefined; - var changes = observableDiff(lhs, rhs, observer, prefilter, true); - return (accum) ? accum : (changes.length) ? changes : undefined; - } - - function applyArrayChange(arr, index, change) { - if (change.path && change.path.length) { - var it = arr[index], - i, u = change.path.length - 1; - for (i = 0; i < u; i++) { - it = it[change.path[i]]; - } - switch (change.kind) { - case 'A': - applyArrayChange(it[change.path[i]], change.index, change.item); - break; - case 'D': - delete it[change.path[i]]; - break; - case 'E': - case 'N': - it[change.path[i]] = change.rhs; - break; - } - } else { - switch (change.kind) { - case 'A': - applyArrayChange(arr[index], change.index, change.item); - break; - case 'D': - arr = arrayRemove(arr, index); - break; - case 'E': - case 'N': - arr[index] = change.rhs; - break; - } - } - return arr; - } - - function applyChange(target, source, change) { - if (typeof change === 'undefined' && source && ~validKinds.indexOf(source.kind)) { - change = source; - } - if (target && change && change.kind) { - var it = target, - i = -1, - last = change.path ? change.path.length - 1 : 0; - while (++i < last) { - if (typeof it[change.path[i]] === 'undefined') { - it[change.path[i]] = (typeof change.path[i + 1] !== 'undefined' && typeof change.path[i + 1] === 'number') ? [] : {}; - } - it = it[change.path[i]]; - } - switch (change.kind) { - case 'A': - if (change.path && typeof it[change.path[i]] === 'undefined') { - it[change.path[i]] = []; - } - applyArrayChange(change.path ? it[change.path[i]] : it, change.index, change.item); - break; - case 'D': - delete it[change.path[i]]; - break; - case 'E': - case 'N': - it[change.path[i]] = change.rhs; - break; - } - } - } - - function revertArrayChange(arr, index, change) { - if (change.path && change.path.length) { - // the structure of the object at the index has changed... - var it = arr[index], - i, u = change.path.length - 1; - for (i = 0; i < u; i++) { - it = it[change.path[i]]; - } - switch (change.kind) { - case 'A': - revertArrayChange(it[change.path[i]], change.index, change.item); - break; - case 'D': - it[change.path[i]] = change.lhs; - break; - case 'E': - it[change.path[i]] = change.lhs; - break; - case 'N': - delete it[change.path[i]]; - break; - } - } else { - // the array item is different... - switch (change.kind) { - case 'A': - revertArrayChange(arr[index], change.index, change.item); - break; - case 'D': - arr[index] = change.lhs; - break; - case 'E': - arr[index] = change.lhs; - break; - case 'N': - arr = arrayRemove(arr, index); - break; - } - } - return arr; - } - - function revertChange(target, source, change) { - if (target && source && change && change.kind) { - var it = target, - i, u; - u = change.path.length - 1; - for (i = 0; i < u; i++) { - if (typeof it[change.path[i]] === 'undefined') { - it[change.path[i]] = {}; - } - it = it[change.path[i]]; - } - switch (change.kind) { - case 'A': - // Array was modified... - // it will be an array... - revertArrayChange(it[change.path[i]], change.index, change.item); - break; - case 'D': - // Item was deleted... - it[change.path[i]] = change.lhs; - break; - case 'E': - // Item was edited... - it[change.path[i]] = change.lhs; - break; - case 'N': - // Item is new... - delete it[change.path[i]]; - break; - } - } - } - - function applyDiff(target, source, filter) { - if (target && source) { - var onChange = function (change) { - if (!filter || filter(target, source, change)) { - applyChange(target, source, change); - } - }; - observableDiff(target, source, onChange); - } - } - - Object.defineProperties(accumulateDiff, { - - diff: { - value: accumulateDiff, - enumerable: true - }, - orderIndependentDiff: { - value: accumulateOrderIndependentDiff, - enumerable: true - }, - observableDiff: { - value: observableDiff, - enumerable: true - }, - orderIndependentObservableDiff: { - value: orderIndependentDeepDiff, - enumerable: true - }, - orderIndepHash: { - value: getOrderIndependentHash, - enumerable: true - }, - applyDiff: { - value: applyDiff, - enumerable: true - }, - applyChange: { - value: applyChange, - enumerable: true - }, - revertChange: { - value: revertChange, - enumerable: true - }, - isConflict: { - value: function () { - return typeof $conflict !== 'undefined'; - }, - enumerable: true - } - }); - - // hackish... - accumulateDiff.DeepDiff = accumulateDiff; - // ...but works with: - // import DeepDiff from 'deep-diff' - // import { DeepDiff } from 'deep-diff' - // const DeepDiff = require('deep-diff'); - // const { DeepDiff } = require('deep-diff'); - - if (root) { - root.DeepDiff = accumulateDiff; - } - - return accumulateDiff; -})); diff --git a/package-lock.json b/package-lock.json index f614907..988af90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,3678 +1,6704 @@ { - "name": "deep-diff", - "version": "1.0.2", - "lockfileVersion": 1, + "name": "node-typescript-boilerplate", + "version": "0.0.0", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "packages": { + "": { + "name": "node-typescript-boilerplate", + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "tslib": "~2.6" + }, + "devDependencies": { + "@faker-js/faker": "^8.3.1", + "@types/node": "~20", + "@types/tap": "^15.0.11", + "@typescript-eslint/eslint-plugin": "^6.16.0", + "@typescript-eslint/parser": "^6.16.0", + "chokidar-cli": "^3.0.0", + "deep-diff": "^1.0.2", + "eslint": "~8.56", + "eslint-config-prettier": "~9.1", + "eslint-plugin-tap": "^1.2.1", + "js-levenshtein": "^1.1.6", + "prettier": "~3.1", + "rimraf": "~5.0", + "tap": "^18.6.1", + "tap-parser": "^15.3.1", + "tap-xunit": "^2.4.1", + "ts-api-utils": "~1.0", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typescript": "~5.3", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">= 20.9 < 21" + } }, - "acorn": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", - "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", - "dev": true + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "node_modules/@alcalzone/ansi-tokenize": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.1.3.tgz", + "integrity": "sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==", "dev": true, - "requires": { - "acorn": "^3.0.4" - }, "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=14.13.1" } }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "node_modules/@alcalzone/ansi-tokenize/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, - "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "node_modules/@alcalzone/ansi-tokenize/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, - "requires": { - "string-width": "^2.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "node_modules/@base2/pretty-print-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz", + "integrity": "sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==", "dev": true }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "requires": { - "sprintf-js": "~1.0.2" + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, - "requires": { - "array-uniq": "^1.0.1" + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, - "atob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", - "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", - "dev": true + "node_modules/@eslint/js": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", + "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "node_modules/@faker-js/faker": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-8.3.1.tgz", + "integrity": "sha512-FdgpFxY6V6rLZE9mmIBb9hM0xpfvQOSNOLnzolzKwsE1DH+gC7lEKV1p1IbR0lAYyvYd5a4u3qWJzowUkw1bIw==", "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/fakerjs" } + ], + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0", + "npm": ">=6.14.13" } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" } }, - "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", - "dev": true + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, - "boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=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 - }, - "buffer-from": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, - "requires": { - "callsites": "^0.2.0" + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } }, - "capture-stack-trace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", - "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", - "dev": true + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } + "node_modules/@isaacs/ts-node-temp-fork-for-pr-2009": { + "version": "10.9.5", + "resolved": "https://registry.npmjs.org/@isaacs/ts-node-temp-fork-for-pr-2009/-/ts-node-temp-fork-for-pr-2009-10.9.5.tgz", + "integrity": "sha512-hEDlwpHhIabtB+Urku8muNMEkGui0LVGlYLS3KoB9QBDf0Pw3r7q0RrfoQmFuk8CvRpGzErO3/vLQd9Ys+/g4g==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node14": "*", + "@tsconfig/node16": "*", + "@tsconfig/node18": "*", + "@tsconfig/node20": "*", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=4.2" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } + "@swc/wasm": { + "optional": true } } }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "dev": true - }, - "chokidar": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", - "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.1.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.0" + "node_modules/@isaacs/ts-node-temp-fork-for-pr-2009/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" } }, - "ci-info": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.3.tgz", - "integrity": "sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg==", - "dev": true - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" } }, - "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, - "requires": { - "restore-cursor": "^2.0.0" + "engines": { + "node": ">=6.0.0" } }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "requires": { - "color-name": "^1.1.1" + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "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 - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "engines": { + "node": ">= 8" } }, - "configstore": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "node_modules/@npmcli/agent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.0.tgz", + "integrity": "sha512-2yThA1Es98orMkpSLVqlDZAMPK3jHJhifP2gnNUdk1754uZ8yI5c+ulCoVG+WlntQA6MzhrURMXjSd9Z7dJ2/Q==", "dev": true, - "requires": { - "capture-stack-trace": "^1.0.0" + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "engines": { + "node": "14 || >=16.14" } }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "dev": true - }, - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true - }, - "debug": { + "node_modules/@npmcli/fs": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.0.tgz", + "integrity": "sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==", "dev": true, - "requires": { - "ms": "2.0.0" + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-extend": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "node_modules/@npmcli/git": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.3.tgz", + "integrity": "sha512-UZp9NwK+AynTrKvHn5k3KviW/hA5eENmFsu3iAPe7sWRt0lFUdsY/wXIYjpDFe7cdSNwOIzbObfwgt6eL5/2zw==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" + "engines": { + "node": ">=16" } }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "dev": true, - "requires": { - "esutils": "^2.0.2" + "engines": { + "node": "14 || >=16.14" } }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "node_modules/@npmcli/git/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "requires": { - "is-obj": "^1.0.0" + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" } }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", - "dev": true, - "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", - "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", - "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", - "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", - "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" - } - }, - "eslint-plugin-mocha": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-5.0.0.tgz", - "integrity": "sha512-mpRWWsjxRco2bY4qE5DL8SmGoVF0Onb6DZrbgOjFoNo1YNN299K2voIozd8Kce3qC/neWNr2XF27E1ZDMl1yZg==", + "node_modules/@npmcli/installed-package-contents": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz", + "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==", "dev": true, - "requires": { - "ramda": "^0.25.0" + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "lib/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", - "dev": true + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.0.tgz", + "integrity": "sha512-wBqcGsMELZna0jDblGd7UXgOby45TQaMWmbFwWX+SEotk4HV6zG2t6rT9siyLhPk4P6YYqgfL1UO8nMWDBVJXQ==", + "dev": true, + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "engines": { + "node": ">=16" } }, - "esprima": { + "node_modules/@npmcli/promise-spawn/node_modules/which": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "node_modules/@npmcli/run-script": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-7.0.2.tgz", + "integrity": "sha512-Omu0rpA8WXvcGeY6DDzyRoY1i5DkCBkzyJ+m2u7PD6quzb0TvSqdIPOkTn8ZBOj7LbbcbMfZ3c5skwSu6m8y2w==", "dev": true, - "requires": { - "estraverse": "^4.0.0" + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "read-package-json-fast": "^3.0.0", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "requires": { - "estraverse": "^4.1.0" + "engines": { + "node": ">=16" } }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } }, - "event-stream": { - "version": "3.3.4", - "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "node_modules/@sigstore/bundle": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.1.0.tgz", + "integrity": "sha512-89uOo6yh/oxaU8AeOUnVrTdVMcGk9Q1hJa7Hkvalc6G3Z3CupWk4Xe9djSgJm9fMkH69s0P0cVHUoKSOemLdng==", "dev": true, - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "dependencies": { + "@sigstore/protobuf-specs": "^0.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "expect.js": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/expect.js/-/expect.js-0.3.1.tgz", - "integrity": "sha1-sKWaDS7/VDdUTr8M6qYBWEHQm1s=", - "dev": true + "node_modules/@sigstore/protobuf-specs": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz", + "integrity": "sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } + "node_modules/@sigstore/sign": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.2.0.tgz", + "integrity": "sha512-AAbmnEHDQv6CSfrWA5wXslGtzLPtAtHZleKOgxdQYvx/s76Fk6T6ZVt7w2IGV9j1UrFeBocTTQxaXG2oRrDhYA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.1.0", + "@sigstore/protobuf-specs": "^0.2.1", + "make-fetch-happen": "^13.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "external-editor": { + "node_modules/@sigstore/tuf": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.2.0.tgz", + "integrity": "sha512-KKATZ5orWfqd9ZG6MN8PtCIx4eevWSuGRKQvofnWXRpyMyUEpmrzg5M5BrCpjM+NfZ0RbNGOh5tCz/P2uoRqOA==", "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" + "dependencies": { + "@sigstore/protobuf-specs": "^0.2.1", + "tuf-js": "^2.1.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "node_modules/@tapjs/after": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@tapjs/after/-/after-1.1.17.tgz", + "integrity": "sha512-14qeP+mHZ8nIMDGtdCwTgvKclLlHxfARMTasb9fw//tmF/8ZDZhTemtCDxAP75wihxy5P7nzVZo/6TpVeOZrwg==", + "dev": true, + "dependencies": { + "is-actual-promise": "^1.0.0" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" } }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true + "node_modules/@tapjs/after-each": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@tapjs/after-each/-/after-each-1.1.17.tgz", + "integrity": "sha512-ia8sr00Wilni+2+wO4MKYCYikeRwUC41HamV8EPN63R2UmiBEOe/cMSf+KYADIh56JvxAiH7Xa0+GSFU+N2FQQ==", + "dev": true, + "dependencies": { + "function-loop": "^4.0.0" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true + "node_modules/@tapjs/asserts": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@tapjs/asserts/-/asserts-1.1.17.tgz", + "integrity": "sha512-eKmbWBORDXu9bUHtPTu7qFrXNj5UeeH2nABJeP9BGHIn2ydmTgMEWCO3E+ljf7tisHchY5/x672lr99+O/mbTQ==", + "dev": true, + "dependencies": { + "@tapjs/stack": "1.2.7", + "is-actual-promise": "^1.0.0", + "tcompare": "6.4.5", + "trivial-deferred": "^2.0.0" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "node_modules/@tapjs/before": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@tapjs/before/-/before-1.1.17.tgz", + "integrity": "sha512-pAmEAIMIqF9MPNUgEsnuWCM00iD/FJOX0P5eXSsWexWHjuZAkv5tIT/4qpXO9KYj+9c51Lh+7YSY2Xvk1Jjolw==", + "dev": true, + "dependencies": { + "is-actual-promise": "^1.0.0" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "node_modules/@tapjs/before-each": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@tapjs/before-each/-/before-each-1.1.17.tgz", + "integrity": "sha512-d2Um3Y2j0m563QNsSxczh+QeSg5sBngnBFGOelUtQVqmq91oNWU/7mY1pwN6ip8mMIQYD75CIhq5/Z57DGomWQ==", "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" + "dependencies": { + "function-loop": "^4.0.0" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" } }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "node_modules/@tapjs/config": { + "version": "2.4.14", + "resolved": "https://registry.npmjs.org/@tapjs/config/-/config-2.4.14.tgz", + "integrity": "sha512-dkjPVJGbLJC9BxCAxudAGiijnKc6XcQbpBSMAGJ/+VoRSqXlPkMWz0d8Ad3rNt7s+g2GBEWBx1kV7wcKtLlxmw==", "dev": true, - "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "dependencies": { + "@tapjs/core": "1.4.6", + "@tapjs/test": "1.3.17", + "chalk": "^5.2.0", + "jackspeak": "^2.3.6", + "polite-json": "^4.0.1", + "tap-yaml": "2.2.1", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6", + "@tapjs/test": "1.3.17" } }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "node_modules/@tapjs/config/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "node_modules/@tapjs/core": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@tapjs/core/-/core-1.4.6.tgz", + "integrity": "sha512-cAKtdGJslrziwi/RJBU7jF930P/eSsemv295t6yLekNVP0XUCNtLFYirxuS1Xwob0nt0g/k+94xXB7o1wdTQvA==", "dev": true, - "requires": { - "circular-json": "^0.3.1", - "del": "^2.0.2", - "graceful-fs": "^4.1.2", - "write": "^0.2.1" + "dependencies": { + "@tapjs/processinfo": "^3.1.6", + "@tapjs/stack": "1.2.7", + "@tapjs/test": "1.3.17", + "async-hook-domain": "^4.0.1", + "diff": "^5.1.0", + "is-actual-promise": "^1.0.0", + "minipass": "^7.0.3", + "signal-exit": "4.1", + "tap-parser": "15.3.1", + "tap-yaml": "2.2.1", + "tcompare": "6.4.5", + "trivial-deferred": "^2.0.0" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "node_modules/@tapjs/core/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "node_modules/@tapjs/error-serdes": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@tapjs/error-serdes/-/error-serdes-1.2.1.tgz", + "integrity": "sha512-/7eLEcrGo+Qz3eWrjkhDC+VSEOjabkkzr9eRADeU+OLFeZaik8L/GRk0SGhnp4YsQkv0jcNV00A42bEx2HIZcw==", "dev": true, - "requires": { - "map-cache": "^0.2.2" + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true + "node_modules/@tapjs/filter": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/@tapjs/filter/-/filter-1.2.17.tgz", + "integrity": "sha512-ytsqoPThV92ML1+M+cHlhAS7nOQpDNRBJiPqw20/GmNeoQXsDzVUlWR89DP3WNNUPrr/c1pCVr9XHVhCIeYk0w==", + "dev": true, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } }, - "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/@tapjs/fixture": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/@tapjs/fixture/-/fixture-1.2.17.tgz", + "integrity": "sha512-eOOQxtsEcQ/sBxaZhpqdF9DCNxXAvLuiE5HgyL6d1eB4eceu57uIUKK7NDtFVv+vlbQH/NoiSTxmN/IBRbKT8w==", + "dev": true, + "dependencies": { + "mkdirp": "^3.0.0", + "rimraf": "^5.0.5" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } }, - "fsevents": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.3.tgz", - "integrity": "sha512-X+57O5YkDTiEQGiw8i7wYc2nQgweIekqkepI8Q3y4wVlurgBt2SuwxTeYUYMZIGpLZH3r/TsMjczCMXE5ZOt7Q==", + "node_modules/@tapjs/intercept": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/@tapjs/intercept/-/intercept-1.2.17.tgz", + "integrity": "sha512-CNuYBxiFBMNALS1PxH3yGI10H8ObxOoD67C2xGWyzXeYrPJ/R4x31Sda9bqaoK3uf/vj28bC9kSECCFjRsNAEg==", "dev": true, - "optional": true, - "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.9.0" + "dependencies": { + "@tapjs/after": "1.1.17", + "@tapjs/stack": "1.2.7" }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } + }, + "node_modules/@tapjs/mock": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@tapjs/mock/-/mock-1.2.15.tgz", + "integrity": "sha512-uXfVNDAMAbCGOu46B9jbryTau2pLSQjCdWnkAm/OUgZh/OtO0i7OORz9HdEPfEF2tuy1tLo9+vsCZm3lPU5F7w==", + "dev": true, "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "2.2.4" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": "2.1.2" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "1.1.11" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "2.2.4" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.9.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.6", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true, - "dev": true - } + "@tapjs/after": "1.1.17", + "@tapjs/stack": "1.2.7", + "resolve-import": "^1.4.5", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "node_modules/@tapjs/node-serialize": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@tapjs/node-serialize/-/node-serialize-1.2.6.tgz", + "integrity": "sha512-xj1OJEsdTr0pQFlirfe/apN0dHUCMCx2Nm5H3SoiSOW4D1/FUKS65VZpWgo3mXMPxRyb/2T1DH3xON1eSGq4ww==", + "dev": true, + "dependencies": { + "@tapjs/error-serdes": "1.2.1", + "@tapjs/stack": "1.2.7", + "tap-parser": "15.3.1" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "node_modules/@tapjs/processinfo": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@tapjs/processinfo/-/processinfo-3.1.6.tgz", + "integrity": "sha512-ktDsaf79wJsLaoG1Pp+stHSRf6a1k/JydoRAaYVG5iJnd3DooL6yewZsciUi2yiN/WQc5tAXCIFTXL4uXGB8LA==", + "dev": true, + "dependencies": { + "pirates": "^4.0.5", + "process-on-spawn": "^1.0.0", + "signal-exit": "^4.0.2", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=16.17" + } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "node_modules/@tapjs/processinfo/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tapjs/processinfo/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@tapjs/reporter": { + "version": "1.3.15", + "resolved": "https://registry.npmjs.org/@tapjs/reporter/-/reporter-1.3.15.tgz", + "integrity": "sha512-us1vXd6TW1V8wJxxnP2a8DNSP1WFTpODyYukqWg7ym5nCalREYnz2MFsn65rRNu/xJlmqsmv+9P63rupud7Zlg==", + "dev": true, + "dependencies": { + "@tapjs/config": "2.4.14", + "@tapjs/stack": "1.2.7", + "chalk": "^5.2.0", + "ink": "^4.4.1", + "minipass": "^7.0.3", + "ms": "^2.1.3", + "patch-console": "^2.0.0", + "prismjs-terminal": "^1.2.3", + "react": "^18.2.0", + "string-length": "^6.0.0", + "tap-parser": "15.3.1", + "tap-yaml": "2.2.1", + "tcompare": "6.4.5" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } + }, + "node_modules/@tapjs/reporter/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@tapjs/reporter/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@tapjs/reporter/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 }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "node_modules/@tapjs/reporter/node_modules/string-length": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-6.0.0.tgz", + "integrity": "sha512-1U361pxZHEQ+FeSjzqRpV+cu2vTzYeWeafXFLykiFlv4Vc0n3njgU8HrMbyik5uwm77naWMuVG8fhEF+Ovb1Kg==", "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" + "dependencies": { + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@tapjs/reporter/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@tapjs/run": { + "version": "1.4.16", + "resolved": "https://registry.npmjs.org/@tapjs/run/-/run-1.4.16.tgz", + "integrity": "sha512-ZTESjBDj5SitZgWz2hQdzfBoxgaFs89jQjWzqobcdfro0iF7TVRpSrvpz9GTMdo2Tu9aeFfMNfmaAtwNWnDabw==", + "dev": true, + "dependencies": { + "@tapjs/after": "1.1.17", + "@tapjs/before": "1.1.17", + "@tapjs/config": "2.4.14", + "@tapjs/processinfo": "^3.1.6", + "@tapjs/reporter": "1.3.15", + "@tapjs/spawn": "1.1.17", + "@tapjs/stdin": "1.1.17", + "@tapjs/test": "1.3.17", + "c8": "^8.0.1", + "chalk": "^5.3.0", + "chokidar": "^3.5.3", + "foreground-child": "^3.1.1", + "glob": "^10.3.10", + "minipass": "^7.0.3", + "mkdirp": "^3.0.1", + "opener": "^1.5.2", + "pacote": "^17.0.3", + "resolve-import": "^1.4.5", + "rimraf": "^5.0.5", + "semver": "^7.5.4", + "signal-exit": "^4.1.0", + "tap-parser": "15.3.1", + "tap-yaml": "2.2.1", + "tcompare": "6.4.5", + "trivial-deferred": "^2.0.0", + "which": "^4.0.0" + }, + "bin": { + "tap-run": "dist/esm/index.js" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } + }, + "node_modules/@tapjs/run/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tapjs/run/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@tapjs/run/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tapjs/run/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@tapjs/run/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tapjs/run/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tapjs/run/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@tapjs/snapshot": { + "version": "1.2.17", + "resolved": "https://registry.npmjs.org/@tapjs/snapshot/-/snapshot-1.2.17.tgz", + "integrity": "sha512-xDHys854ZA8s/1uCkE5PgBz4H1vYKChD6a4xjLVkaoRxpBHVp/IJZCD+8d69DRGnyuA4x2MGh0JLClTA9bLGrA==", + "dev": true, + "dependencies": { + "is-actual-promise": "^1.0.0", + "tcompare": "6.4.5", + "trivial-deferred": "^2.0.0" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } + }, + "node_modules/@tapjs/spawn": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@tapjs/spawn/-/spawn-1.1.17.tgz", + "integrity": "sha512-Bbyxd91bgXEcglvXYKrRl2MaNHk00RajTZJ1kKe3Scr1ivaYv0maE6ZInAl4UE0a4SJl4Dskec+uKoZY3qGUYQ==", + "dev": true, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } + }, + "node_modules/@tapjs/stack": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@tapjs/stack/-/stack-1.2.7.tgz", + "integrity": "sha512-7qUDWDmd+y7ZQ0vTrDTvFlWnJ+ND32NemS5HVuT1ZggHtBwJ62PQHIyCx/B5RopETBb6NvFPfUE21yTiex9Jkw==", + "dev": true, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tapjs/stdin": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@tapjs/stdin/-/stdin-1.1.17.tgz", + "integrity": "sha512-mDutFFPDnlVM2oYDAfyYKA+fC+aEiyz5n08D8x6YAbwZNbTIVp+h6ucyp7ygJ04fshd4l3s1HUmCZLSmHb2xEw==", + "dev": true, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } + }, + "node_modules/@tapjs/test": { + "version": "1.3.17", + "resolved": "https://registry.npmjs.org/@tapjs/test/-/test-1.3.17.tgz", + "integrity": "sha512-yQ4uHC2GaDS+Gr5qwx9uMGxqvpYgnlVY+QexBReSeYZthWIN0KD8HDvnVt4An5Sx/Qhd7UlnNpNMBd6AkvPEew==", + "dev": true, + "dependencies": { + "@isaacs/ts-node-temp-fork-for-pr-2009": "^10.9.5", + "@tapjs/after": "1.1.17", + "@tapjs/after-each": "1.1.17", + "@tapjs/asserts": "1.1.17", + "@tapjs/before": "1.1.17", + "@tapjs/before-each": "1.1.17", + "@tapjs/filter": "1.2.17", + "@tapjs/fixture": "1.2.17", + "@tapjs/intercept": "1.2.17", + "@tapjs/mock": "1.2.15", + "@tapjs/node-serialize": "1.2.6", + "@tapjs/snapshot": "1.2.17", + "@tapjs/spawn": "1.1.17", + "@tapjs/stdin": "1.1.17", + "@tapjs/typescript": "1.3.6", + "@tapjs/worker": "1.1.17", + "glob": "^10.3.10", + "jackspeak": "^2.3.6", + "mkdirp": "^3.0.0", + "resolve-import": "^1.4.5", + "rimraf": "^5.0.5", + "sync-content": "^1.0.1", + "tap-parser": "15.3.1", + "tshy": "^1.2.2", + "typescript": "5.2" + }, + "bin": { + "generate-tap-test-class": "scripts/build.mjs" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } + }, + "node_modules/@tapjs/test/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tapjs/test/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tapjs/test/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tapjs/test/node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@tapjs/typescript": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@tapjs/typescript/-/typescript-1.3.6.tgz", + "integrity": "sha512-bHqQb06HcD1vFvSwElH0WK4cnCNthvA5OX/KBs5w1TNFHIeRHemp/hsSnGSNDwYwDETuOxD68rDZNTpNbzysBg==", + "dev": true, + "dependencies": { + "@isaacs/ts-node-temp-fork-for-pr-2009": "^10.9.5" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } + }, + "node_modules/@tapjs/worker": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/@tapjs/worker/-/worker-1.1.17.tgz", + "integrity": "sha512-DCRzEBT+OgP518rQqzlX6KawvGTegkeEjPVa/TB6Iifj8WOHJ+XtunkR7riIRGEoCEOMD49DCJXj70c+XP0jNw==", + "dev": true, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "peerDependencies": { + "@tapjs/core": "1.4.6" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-14.1.0.tgz", + "integrity": "sha512-VmsCG04YR58ciHBeJKBDNMWWfYbyP8FekWVuTlpstaUPlat1D0x/tXzkWP7yCMU0eSz9V4OZU0LBWTFJ3xZf6w==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-16.1.1.tgz", + "integrity": "sha512-+pio93ejHN4nINX4pXqfnR/fPLRtJBaT4ORaa5RH0Oc1zoYmo2B2koG+M328CQhHKn1Wj6FcOxCDFXAot9NhvA==", + "dev": true + }, + "node_modules/@tsconfig/node18": { + "version": "18.2.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.2.tgz", + "integrity": "sha512-d6McJeGsuoRlwWZmVIeE8CUA27lu6jLjvv1JzqmpsytOYYbVi1tHZEnwCNVOXnj4pyLvneZlFlpXUK+X9wBWyw==", + "dev": true + }, + "node_modules/@tsconfig/node20": { + "version": "20.1.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.2.tgz", + "integrity": "sha512-madaWq2k+LYMEhmcp0fs+OGaLFk0OenpHa4gmI4VEmCKX4PJntQ6fnnGADVFrVkBj0wIdAlQnK/MrlYTHsa1gQ==", + "dev": true + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.0.tgz", + "integrity": "sha512-c8nj8BaOExmZKO2DXhDfegyhSGcG9E/mPN3U13L+/PsoWm1uaGiHHjxqSHQiasDBQwDA3aHuw9+9spYAP1qvvg==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/semver": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", + "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "dev": true + }, + "node_modules/@types/tap": { + "version": "15.0.11", + "resolved": "https://registry.npmjs.org/@types/tap/-/tap-15.0.11.tgz", + "integrity": "sha512-QzbxIsrK6yX3iWC2PXGX/Ljz5cGISDEuOGISMcckeSUKIJXzbsfJLF4LddoncZ+ELVZpO0X87KfRem4h+yBFXQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.16.0.tgz", + "integrity": "sha512-O5f7Kv5o4dLWQtPX4ywPPa+v9G+1q1x8mz0Kr0pXUtKsevo+gIJHLkGc8RxaZWtP8RrhwhSNIWThnW42K9/0rQ==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/type-utils": "6.16.0", + "@typescript-eslint/utils": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.16.0.tgz", + "integrity": "sha512-H2GM3eUo12HpKZU9njig3DF5zJ58ja6ahj1GoHEHOgQvYxzoFJJEvC1MQ7T2l9Ha+69ZSOn7RTxOdpC/y3ikMw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/typescript-estree": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.16.0.tgz", + "integrity": "sha512-0N7Y9DSPdaBQ3sqSCwlrm9zJwkpOuc6HYm7LpzLAPqBL7dmzAUimr4M29dMkOP/tEwvOCC/Cxo//yOfJD3HUiw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.16.0.tgz", + "integrity": "sha512-ThmrEOcARmOnoyQfYkHw/DX2SEYBalVECmoldVuH6qagKROp/jMnfXpAU/pAIWub9c4YTxga+XwgAkoA0pxfmg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.16.0", + "@typescript-eslint/utils": "6.16.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.16.0.tgz", + "integrity": "sha512-hvDFpLEvTJoHutVl87+MG/c5C8I6LOgEx05zExTSJDEVU7hhR3jhV8M5zuggbdFCw98+HhZWPHZeKS97kS3JoQ==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.16.0.tgz", + "integrity": "sha512-VTWZuixh/vr7nih6CfrdpmFNLEnoVBF1skfjdyGnNwXOH1SLeHItGdZDHhhAIzd3ACazyY2Fg76zuzOVTaknGA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/visitor-keys": "6.16.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.16.0.tgz", + "integrity": "sha512-T83QPKrBm6n//q9mv7oiSvy/Xq/7Hyw9SzSEhMHJwznEmQayfBM87+oAlkNAMEO7/MjIwKyOHgBJbxB0s7gx2A==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.16.0", + "@typescript-eslint/types": "6.16.0", + "@typescript-eslint/typescript-estree": "6.16.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.16.0.tgz", + "integrity": "sha512-QSFQLruk7fhs91a/Ep/LqRdbJCZ1Rq03rqBdKT5Ky17Sz8zRLUksqIe9DW0pKtg/Z35/ztbLQ6qpOCN6rOC11A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.16.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", + "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aggregate-error/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "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/array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async-hook-domain": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-4.0.1.tgz", + "integrity": "sha512-bSktexGodAjfHWIrSrrqxqWzf1hWBZBpmPNZv+TYUMyWa2eoefFc6q6H1+KtdHYSz35lrhWdmXt/XK9wNEZvww==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/auto-bind": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-5.0.1.tgz", + "integrity": "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "dependencies": { + "semver": "^7.0.0" + } + }, + "node_modules/c8": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/c8/-/c8-8.0.1.tgz", + "integrity": "sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^2.0.0", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "rimraf": "^3.0.2", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/c8/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/c8/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/cacache": { + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.1.tgz", + "integrity": "sha512-g4Uf2CFZPaxtJKre6qr4zqLDOOPU7bNVhWjlNhvzc51xaTOx2noMOLhfFkTAqwtrAZAKQUuDfyjitzilpA8WsQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/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-cli": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chokidar-cli/-/chokidar-cli-3.0.0.tgz", + "integrity": "sha512-xVW+Qeh7z15uZRxHOkP93Ux8A0xbPzwK4GaqD8dQOYc34TlkqUhVSS59fK36DOp5WdJlrRzlYSy02Ht99FjZqQ==", + "dev": true, + "dependencies": { + "chokidar": "^3.5.2", + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1", + "yargs": "^13.3.0" + }, + "bin": { + "chokidar": "index.js" + }, + "engines": { + "node": ">= 8.10.0" + } + }, + "node_modules/chokidar-cli/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar-cli/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar-cli/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/chokidar-cli/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/chokidar-cli/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/chokidar-cli/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/chokidar-cli/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar-cli/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar-cli/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar-cli/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chokidar-cli/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar-cli/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/chokidar-cli/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar-cli/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar-cli/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar-cli/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/chokidar-cli/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/chokidar-cli/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "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/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/code-excerpt": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz", + "integrity": "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==", + "dev": true, + "dependencies": { + "convert-to-spaces": "^2.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.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/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/convert-to-spaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", + "integrity": "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "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/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-diff": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/deep-diff/-/deep-diff-1.0.2.tgz", + "integrity": "sha512-aWS3UIVH+NPGCD1kki+DCU9Dua032iSsO43LqQpcs4R3+dVv7tX0qBGjiVHJHjplsoUM2XRO/KB92glqc68awg==", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "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/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "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/eslint": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", + "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-tap": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-tap/-/eslint-plugin-tap-1.2.1.tgz", + "integrity": "sha512-1vYjRiZxqgY3qhDMmGUwg8rlRomFwFbXR+zMlSI76abWIrje/smT5CSaOdJTIYqpmm/DXGdzx4cNInpto1+YYA==", + "dev": true, + "dependencies": { + "espurify": "2.1.1", + "multimatch": "5.0.0", + "pkg-up": "3.1.0" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "eslint": ">=3" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/espurify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/espurify/-/espurify-2.1.1.tgz", + "integrity": "sha512-zttWvnkhcDyGOhSH4vO2qCBILpdCMv/MX8lp4cqgRkQoDRGK2oZxi2GfWhlP2dIXmk7BaKeOTuzbHhyC68o8XQ==", + "dev": true + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events-to-array": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-2.0.3.tgz", + "integrity": "sha512-f/qE2gImHRa4Cp2y1stEOSgw8wTFyUdVJX7G//bMwbaV9JqISFxg99NbmVQeP7YLnDUZ2un851jlaDrlpmGehQ==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/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/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "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-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flat-cache/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/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "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/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-loop": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-4.0.0.tgz", + "integrity": "sha512-f34iQBedYF3XcI93uewZZOnyscDragxgTK/eTvVB74k3fCD0ZorOi5BV9GS4M8rz/JoNi0Kl3qX5Y9MH3S/CLQ==", + "dev": true + }, + "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/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "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/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", + "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.4.tgz", + "integrity": "sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "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/ink": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/ink/-/ink-4.4.1.tgz", + "integrity": "sha512-rXckvqPBB0Krifk5rn/5LvQGmyXwCUpBfmTwbkQNBY9JY8RSl3b8OftBNEYxg4+SWUhEKcPifgope28uL9inlA==", + "dev": true, + "dependencies": { + "@alcalzone/ansi-tokenize": "^0.1.3", + "ansi-escapes": "^6.0.0", + "auto-bind": "^5.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "cli-cursor": "^4.0.0", + "cli-truncate": "^3.1.0", + "code-excerpt": "^4.0.0", + "indent-string": "^5.0.0", + "is-ci": "^3.0.1", + "is-lower-case": "^2.0.2", + "is-upper-case": "^2.0.2", + "lodash": "^4.17.21", + "patch-console": "^2.0.0", + "react-reconciler": "^0.29.0", + "scheduler": "^0.23.0", + "signal-exit": "^3.0.7", + "slice-ansi": "^6.0.0", + "stack-utils": "^2.0.6", + "string-width": "^5.1.2", + "type-fest": "^0.12.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0", + "ws": "^8.12.0", + "yoga-wasm-web": "~0.3.3" + }, + "engines": { + "node": ">=14.16" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "react": ">=18.0.0", + "react-devtools-core": "^4.19.1" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react-devtools-core": { + "optional": true + } + } + }, + "node_modules/ink/node_modules/ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, + "dependencies": { + "type-fest": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/ansi-escapes/node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ink/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ink/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ink/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/ink/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ink/node_modules/type-fest": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.12.0.tgz", + "integrity": "sha512-53RyidyjvkGpnWPMF9bQgFtWp+Sl8O2Rp13VavmJgfAP9WWG6q6TkrKU8iyJdnwnfgHI6k2hTlgqH4aSdjoTbg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", + "dev": true + }, + "node_modules/is-actual-promise": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-actual-promise/-/is-actual-promise-1.0.1.tgz", + "integrity": "sha512-PlsL4tNv62lx5yN2HSqaRSTgIpUAPW7U6+crVB8HfWm5161rZpeqWbl0ZSqH2MAfRKXWSZVPRNbE/r8qPcb13g==", + "dev": true, + "dependencies": { + "tshy": "^1.7.0" + } + }, + "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-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "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-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "node_modules/is-lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", + "integrity": "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "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-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz", + "integrity": "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "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/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "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/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "dev": true + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/make-fetch-happen": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz", + "integrity": "sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", + "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-json-stream/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/multimatch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", + "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-gyp": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.0.1.tgz", + "integrity": "sha512-gg3/bHehQfZivQVfqIyy8wTdSymF9yTyP4CJifK73imyNMU8AIGQE2pUa7dNWfmMeG9cDVF2eehiRMv0LC1iAg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/node-gyp/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/nopt": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", + "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", + "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "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/npm-bundled": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.0.tgz", + "integrity": "sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.1.tgz", + "integrity": "sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-packlist": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.1.tgz", + "integrity": "sha512-MQpL27ZrsJQ2kiAuQPpZb5LtJwydNRnI15QWXsf3WHERu4rzjRj6Zju/My2fov7tLuu3Gle/uoIX/DDZ3u4O4Q==", + "dev": true, + "dependencies": { + "ignore-walk": "^6.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.0.0.tgz", + "integrity": "sha512-VfvRSs/b6n9ol4Qb+bDwNGUXutpy76x6MARw/XssevE0TnctIKcmklJZM5Z7nqs5z5aW+0S63pgCNbpkUNNXBg==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-16.1.0.tgz", + "integrity": "sha512-PQCELXKt8Azvxnt5Y85GseQDJJlglTFM9L9U9gkv2y4e9s0k3GVDdOx3YoB6gm2Do0hlkzC39iCGXby+Wve1Bw==", + "dev": true, + "dependencies": { + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pacote": { + "version": "17.0.5", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.5.tgz", + "integrity": "sha512-TAE0m20zSDMnchPja9vtQjri19X3pZIyRpm2TJVeI+yU42leJBBDTRYhOcWFsPhaMxf+3iwQkFiKz16G9AEeeA==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^7.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^16.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^7.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^2.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/patch-console": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-2.0.0.tgz", + "integrity": "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } + "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" } }, - "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "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": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "requires": { - "ini": "^1.3.4" + "engines": { + "node": ">=0.10.0" } }, - "globals": { - "version": "11.5.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz", - "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==", - "dev": true + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", - "dev": true, - "requires": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", - "dev": true - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, - "requires": { - "ansi-regex": "^2.0.0" + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "engines": { + "node": ">=8" } }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "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" } }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "ignore": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", - "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", - "dev": true + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" + "engines": { + "node": ">=4" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "node_modules/polite-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/polite-json/-/polite-json-4.0.1.tgz", + "integrity": "sha512-8LI5ZeCPBEb4uBbcYKNVwk4jgqNx1yHReWoW4H4uUihWlSqZsUDfSITrRhjliuPgxsNPFhNSudGO2Zu4cbWinQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^2.0.4", - "figures": "^2.0.0", - "lodash": "^4.3.0", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", - "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", - "through": "^2.3.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "node_modules/prettier": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", "dev": true, - "requires": { - "binary-extensions": "^1.0.0" + "engines": { + "node": ">=6" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "node_modules/prismjs-terminal": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prismjs-terminal/-/prismjs-terminal-1.2.3.tgz", + "integrity": "sha512-xc0zuJ5FMqvW+DpiRkvxURlz98DdfDsZcFHdO699+oL+ykbFfgI7O4VDEgUyc07BSL2NHl3zdb8m/tZ/aaqUrw==", + "dev": true, + "dependencies": { + "chalk": "^5.2.0", + "prismjs": "^1.29.0", + "string-length": "^6.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "is-ci": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", - "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", + "node_modules/prismjs-terminal/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "requires": { - "ci-info": "^1.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "node_modules/prismjs-terminal/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "requires": { - "kind-of": "^3.0.2" + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/prismjs-terminal/node_modules/string-length": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-6.0.0.tgz", + "integrity": "sha512-1U361pxZHEQ+FeSjzqRpV+cu2vTzYeWeafXFLykiFlv4Vc0n3njgU8HrMbyik5uwm77naWMuVG8fhEF+Ovb1Kg==", "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "dependencies": { + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=16" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prismjs-terminal/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.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=", + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", "dev": true }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "dev": true, - "requires": { - "is-extglob": "^2.1.1" + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" } }, - "is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" + "engines": { + "node": ">=6" } }, - "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "dev": true + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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" + } + ] }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-odd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", - "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "dev": true, - "requires": { - "is-number": "^4.0.0" + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-element-to-jsx-string": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz", + "integrity": "sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==", + "dev": true, "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } + "@base2/pretty-print-object": "1.0.1", + "is-plain-object": "5.0.0", + "react-is": "18.1.0" + }, + "peerDependencies": { + "react": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0", + "react-dom": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0" } }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "node_modules/react-element-to-jsx-string/node_modules/react-is": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", + "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", "dev": true }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "node_modules/react-reconciler": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.0.tgz", + "integrity": "sha512-wa0fGj7Zht1EYMRhKWwoo1H9GApxYLBuhoAuXN0TlltESAjDssB+Apf0T/DngVqaMyPypDmabL37vw/2aRM98Q==", "dev": true, - "requires": { - "is-path-inside": "^1.0.0" + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^18.2.0" } }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "node_modules/read-package-json": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-7.0.0.tgz", + "integrity": "sha512-uL4Z10OKV4p6vbdvIXB+OzhInYtIozl/VxUBPgNkBuUi2DeRonnuspmaVAMcrkmfjKGNmRndyQAbE7/AmzGwFg==", "dev": true, - "requires": { - "path-is-inside": "^1.0.1" + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", "dev": true, - "requires": { - "isobject": "^3.0.1" + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", + "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true + "node_modules/read-package-json/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true + "node_modules/read-package-json/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "node_modules/read-package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", + "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "node_modules/read-package-json/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } }, - "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/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" + } }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "js-yaml": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", - "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "engines": { + "node": ">=4" } }, - "json": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/json/-/json-9.0.6.tgz", - "integrity": "sha1-eXLCpaSKQmeNsnMMfCxO5uTiRYU=", - "dev": true + "node_modules/resolve-import": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/resolve-import/-/resolve-import-1.4.5.tgz", + "integrity": "sha512-HXb4YqODuuXT7Icq1Z++0g2JmhgbUHSs3VT2xR83gqvAPUikYT2Xk+562KHQgiaNkbBOlPddYrDLsC44qQggzw==", + "dev": true, + "dependencies": { + "glob": "^10.3.3", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "json-ptr": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/json-ptr/-/json-ptr-1.1.0.tgz", - "integrity": "sha512-/5wyr0PEFeLk2jh88CBZZPJD6wqe/bJvqAIWXbkBOKxvgeHlM67Ilu8b0QKKyLhfSP+9uvA+NSAo2/n62q68aQ==", - "dev": true + "node_modules/resolve-import/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true + "node_modules/resolve-import/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true + "node_modules/resolve-import/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, - "requires": { - "package-json": "^4.0.0" + "engines": { + "node": ">= 4" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", - "dev": true - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "requires": { - "pify": "^3.0.0" - }, "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } + "balanced-match": "^1.0.0" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", - "dev": true + "node_modules/rimraf/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "node_modules/rimraf/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, - "requires": { - "object-visit": "^1.0.0" + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "md5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", - "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", - "dev": true, - "requires": { - "charenc": "~0.0.1", - "crypt": "~0.0.1", - "is-buffer": "~1.1.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "mimic-fn": { + "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "requires": { - "brace-expansion": "^1.1.7" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "dev": true, - "requires": { - "minimist": "0.0.8" + "dependencies": { + "loose-envify": "^1.1.0" } }, - "mocha": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.1.tgz", - "integrity": "sha512-kKKs/H1KrMMQIEsWNxGmb4/BGsmj0dkeyotEvbrAuQ01FcWRLssUNXCEUZk6SZtyJBi6EE7SL0zDDtItw1rGhw==", + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, "dependencies": { - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "dev": true, - "requires": { - "has-flag": "^2.0.0" - } - } + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "mocha-junit-reporter": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-1.17.0.tgz", - "integrity": "sha1-LlFJ7UD8XS48px5C21qx/snG2Fw=", + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "requires": { - "debug": "^2.2.0", - "md5": "^2.1.0", - "mkdirp": "~0.5.1", - "strip-ansi": "^4.0.0", - "xml": "^1.0.0" - }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "optional": true + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } }, - "nanomatch": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", - "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-odd": "^2.0.0", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "nodemon": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.17.4.tgz", - "integrity": "sha512-ZQcvYd8I4sWhbLoqImIiCPBTaHcq3YRRQXYwePchFK3Zk5+LT8HYQR4urf1UkSDiY/gSxjq6ao34RxJp7rRe1w==", + "node_modules/sigstore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.1.0.tgz", + "integrity": "sha512-kPIj+ZLkyI3QaM0qX8V/nSsweYND3W448pwkDgS6CQ74MfhEkIR8ToK5Iyx46KJYRjseVcD3Rp9zAmUAj6ZjPw==", "dev": true, - "requires": { - "chokidar": "^2.0.2", - "debug": "^3.1.0", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.0.4", - "pstree.remy": "^1.1.0", - "semver": "^5.5.0", - "supports-color": "^5.2.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.2", - "update-notifier": "^2.3.0" - }, "dependencies": { - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "@sigstore/bundle": "^2.1.0", + "@sigstore/protobuf-specs": "^0.2.1", + "@sigstore/sign": "^2.1.0", + "@sigstore/tuf": "^2.1.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "requires": { - "abbrev": "1" + "engines": { + "node": ">=8" } }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/slice-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-6.0.0.tgz", + "integrity": "sha512-6bn4hRfkTvDfUoEQYkERg0BVF1D0vrX9HEkMl08uDiNWvVvjylLHvZFZWkDo6wjT8tUctbYl1nCOuE66ZTaUtA==", "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", "dev": true, - "requires": { - "isobject": "^3.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, - "requires": { - "isobject": "^3.0.1" + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "node_modules/socks": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dev": true, - "requires": { - "wrappy": "1" + "dependencies": { + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" } }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "node_modules/socks-proxy-agent": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz", + "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==", "dev": true, - "requires": { - "mimic-fn": "^1.0.0" + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" } }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, - "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-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 - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "node_modules/spdx-license-ids": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", + "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", "dev": true }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "node_modules/ssri": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", + "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", "dev": true, - "requires": { - "through": "~2.3" + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "requires": { - "pinkie": "^2.0.0" + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "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" + } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true + "node_modules/string-width-cjs": { + "name": "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" + } }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "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" + } }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "node_modules/strip-ansi-cjs": { + "name": "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" + } }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true + "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" + } }, - "ps-tree": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", - "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", + "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, - "requires": { - "event-stream": "~3.3.0" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "pseudomap": { + "node_modules/sync-content": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "pstree.remy": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz", - "integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==", + "resolved": "https://registry.npmjs.org/sync-content/-/sync-content-1.0.2.tgz", + "integrity": "sha512-znd3rYiiSxU3WteWyS9a6FXkTA/Wjk8WQsOyzHbineeL837dLn3DA4MRhsIX3qGcxDMH6+uuFV4axztssk7wEQ==", "dev": true, - "requires": { - "ps-tree": "^1.1.0" + "dependencies": { + "glob": "^10.2.6", + "mkdirp": "^3.0.1", + "path-scurry": "^1.9.2", + "rimraf": "^5.0.1" + }, + "bin": { + "sync-content": "dist/mjs/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "ramda": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", - "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", - "dev": true - }, - "rc": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", - "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", + "node_modules/sync-content/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "balanced-match": "^1.0.0" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "node_modules/sync-content/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "node_modules/sync-content/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "node_modules/tap": { + "version": "18.6.1", + "resolved": "https://registry.npmjs.org/tap/-/tap-18.6.1.tgz", + "integrity": "sha512-5cBQhJ1gdbsrTR3tA5kZZTts0HyOML6bcM7pEF7GF8d6y1ajfRMjbInS1Ty7/x2Ip0ko3cY1dYjPJ9JFNPsm7w==", "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "dependencies": { + "@tapjs/after": "1.1.17", + "@tapjs/after-each": "1.1.17", + "@tapjs/asserts": "1.1.17", + "@tapjs/before": "1.1.17", + "@tapjs/before-each": "1.1.17", + "@tapjs/core": "1.4.6", + "@tapjs/filter": "1.2.17", + "@tapjs/fixture": "1.2.17", + "@tapjs/intercept": "1.2.17", + "@tapjs/mock": "1.2.15", + "@tapjs/node-serialize": "1.2.6", + "@tapjs/run": "1.4.16", + "@tapjs/snapshot": "1.2.17", + "@tapjs/spawn": "1.1.17", + "@tapjs/stdin": "1.1.17", + "@tapjs/test": "1.3.17", + "@tapjs/typescript": "1.3.6", + "@tapjs/worker": "1.1.17", + "resolve-import": "^1.4.5" + }, + "bin": { + "tap": "dist/esm/run.mjs" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", - "dev": true - }, - "registry-auth-token": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "node_modules/tap-parser": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-15.3.1.tgz", + "integrity": "sha512-hwAtXX5TBGt2MJeYvASc7DjP48PUzA7P8RTbLxQcgKCEH7ICD5IsRco7l5YvkzjHlZbUbeI9wzO8B4hw2sKgnQ==", "dev": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" + "dependencies": { + "events-to-array": "^2.0.3", + "tap-yaml": "2.2.1" + }, + "bin": { + "tap-parser": "bin/cmd.cjs" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" } }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "node_modules/tap-xunit": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tap-xunit/-/tap-xunit-2.4.1.tgz", + "integrity": "sha512-qcZStDtjjYjMKAo7QNiCtOW256g3tuSyCSe5kNJniG1Q2oeOExJq4vm8CwboHZURpkXAHvtqMl4TVL7mcbMVVA==", "dev": true, - "requires": { - "rc": "^1.0.1" + "dependencies": { + "duplexer": "~0.1.1", + "minimist": "~1.2.0", + "tap-parser": "~1.2.2", + "through2": "~2.0.0", + "xmlbuilder": "~4.2.0", + "xtend": "~4.0.0" + }, + "bin": { + "tap-xunit": "bin/tap-xunit", + "txunit": "bin/tap-xunit" } }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true + "node_modules/tap-xunit/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } }, - "repeat-element": { + "node_modules/tap-xunit/node_modules/events-to-array": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", + "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==", "dev": true }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "node_modules/tap-xunit/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "node_modules/tap-xunit/node_modules/tap-parser": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-1.2.2.tgz", + "integrity": "sha512-uXKcosa0qoSjeh73dhmX+OpJvpigDxUciOhBcbGUKtmwzEFJjUT1Ql5dpg4M9I1UjXT9b+6n1W05FB8QmKossA==", + "dev": true, + "dependencies": { + "events-to-array": "^1.0.1", + "inherits": "~2.0.1", + "js-yaml": "^3.2.7" + }, + "bin": { + "tap-parser": "bin/cmd.js" + }, + "optionalDependencies": { + "readable-stream": "^2" + } }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "node_modules/tap-yaml": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-2.2.1.tgz", + "integrity": "sha512-ovZuUMLAIH59jnFHXKEGJ+WyDYl6Cuduwg9qpvnqkZOUA1nU84q02Sry1HT0KXcdv2uB91bEKKxnIybBgrb6oA==", "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" + "dependencies": { + "yaml": "^2.3.0", + "yaml-types": "^0.3.0" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" } }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true + "node_modules/tar": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, - "requires": { - "glob": "^7.0.5" + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "requires": { - "is-promise": "^2.1.0" + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "requires": { - "rx-lite": "*" + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "node_modules/tcompare": { + "version": "6.4.5", + "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-6.4.5.tgz", + "integrity": "sha512-Whuz9xlKKI2XXICKDSDRKjXdBuC6gBNOgmEUtH7UFyQeYzfUMQ19DyjZULarGKDGFhgOg3CJ+IQUEfpkOPg0Uw==", "dev": true, - "requires": { - "ret": "~0.1.10" + "dependencies": { + "diff": "^5.1.0", + "react-element-to-jsx-string": "^15.0.0" + }, + "engines": { + "node": "16 >=16.17.0 || 18 >= 18.6.0 || >=20" } }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, - "requires": { - "semver": "^5.0.3" + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" } }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true + "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" + } }, - "set-value": { + "node_modules/trivial-deferred": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-2.0.0.tgz", + "integrity": "sha512-iGbM7X2slv9ORDVj2y2FFUq3cP/ypbtu2nQ8S38ufjL0glBABvmR9pTdsib1XtS2LUhhLMbelaBUaf/s5J3dSw==", + "dev": true, + "engines": { + "node": ">= 8" } }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "node_modules/ts-api-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", + "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", "dev": true, - "requires": { - "shebang-regex": "^1.0.0" + "engines": { + "node": ">=16.13.0" + }, + "peerDependencies": { + "typescript": ">=4.2.0" } }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "node_modules/ts-node/node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" } }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "node_modules/tshy": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/tshy/-/tshy-1.8.2.tgz", + "integrity": "sha512-aGlSY+jkZYAv0YDgtdv1U2vvbGTUdlXmhVP4uegujlJ/wuznmJqSu5cUV/6IW7N7a3HFRhofWvIS/FquYN9zgA==", "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "chalk": "^5.3.0", + "chokidar": "^3.5.3", + "foreground-child": "^3.1.1", + "mkdirp": "^3.0.1", + "resolve-import": "^1.4.4", + "rimraf": "^5.0.1", + "sync-content": "^1.0.2", + "typescript": "5.2", + "walk-up-path": "^3.0.1" + }, + "bin": { + "tshy": "dist/esm/index.js" + }, + "engines": { + "node": "16 >=16.17 || 18 >=18.15.0 || >=20.6.1" } }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "node_modules/tshy/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "node_modules/tshy/node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, - "requires": { - "through": "2" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/tuf-js": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.1.0.tgz", + "integrity": "sha512-eD7YPPjVlMzdggrOeE8zwoegUaG/rt6Bt3jwoQPunRiNVzgcCE009UDFJKJjG+Gk9wFu6W/Vi+P5d/5QpdD9jA==", "dev": true, - "requires": { - "extend-shallow": "^3.0.0" + "dependencies": { + "@tufjs/models": "2.0.0", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "requires": { - "duplexer": "~0.1.1" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "requires": { - "safe-buffer": "~5.1.0" + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "strip-ansi": { + "node_modules/unique-slug": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "requires": { - "ansi-regex": "^3.0.0" + "dependencies": { + "imurmurhash": "^0.1.4" }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } + "punycode": "^2.1.0" } }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, - "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" } }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { - "execa": "^0.7.0" + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "node_modules/validate-npm-package-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "dev": true, + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "node_modules/walk-up-path": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", + "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", "dev": true }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "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/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", "dev": true }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "node_modules/widest-line/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "requires": { - "kind-of": "^3.0.2" + "engines": { + "node": ">=12" }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "node_modules/widest-line/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "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, - "requires": { - "nopt": "~1.0.10" + "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" } }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "node_modules/wrap-ansi-cjs": { + "name": "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": { - "prelude-ls": "~1.1.2" + "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" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "uglify-js": { - "version": "3.3.25", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.25.tgz", - "integrity": "sha512-hobogryjDV36VrLK3Y69ou4REyrTApzUblVFmdQOYRe8cYaSmFJXMb4dR9McdvYDSbeNdzUgYr2YVukJaErJcA==", + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", "dev": true, - "requires": { - "commander": "~2.15.0", - "source-map": "~0.6.1" + "engines": { + "node": ">=10.0.0" }, - "dependencies": { - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "utf-8-validate": { + "optional": true } } }, - "undefsafe": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", - "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "node_modules/xmlbuilder": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", + "integrity": "sha512-oEePiEefhQhAeUnwRnIBLBWmk/fsWWbQ53EEWsRuzECbQ3m5o/Esmq6H47CYYwSLW+Ynt0rS9hd0pd2ogMAWjg==", "dev": true, - "requires": { - "debug": "^2.2.0" - }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "lodash": "^4.0.0" + }, + "engines": { + "node": ">=0.8.0" } }, - "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, - "requires": { - "crypto-random-string": "^1.0.0" - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } + "engines": { + "node": ">=0.4" } }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true - }, - "upath": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.5.tgz", - "integrity": "sha512-qbKn90aDQ0YEwvXoLqj0oiuUYroLX2lVHZ+b+xwjozFasAOC4GneDq5+OaIG5Zj+jFmbz/uO+f7a9qxjktJQww==", - "dev": true - }, - "update-notifier": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "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, - "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" + "engines": { + "node": ">=10" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "node_modules/yaml": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", + "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", "dev": true, - "requires": { - "prepend-http": "^1.0.1" + "engines": { + "node": ">= 14" } }, - "use": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", - "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "node_modules/yaml-types": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yaml-types/-/yaml-types-0.3.0.tgz", + "integrity": "sha512-i9RxAO/LZBiE0NJUy9pbN5jFz5EasYDImzRkj8Y81kkInTi1laia3P3K/wlMKzOxFQutZip8TejvQP/DwgbU7A==", "dev": true, - "requires": { - "kind-of": "^6.0.2" + "engines": { + "node": ">= 16", + "npm": ">= 7" + }, + "peerDependencies": { + "yaml": "^2.3.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "requires": { - "isexe": "^2.0.0" + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, - "widest-line": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz", - "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=", + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "requires": { - "string-width": "^2.1.1" + "engines": { + "node": ">=12" } }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "requires": { - "mkdirp": "^0.5.1" + "engines": { + "node": ">=6" } }, - "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "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, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", - "dev": true - }, - "xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "node_modules/yoga-wasm-web": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/yoga-wasm-web/-/yoga-wasm-web-0.3.3.tgz", + "integrity": "sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==", "dev": true } } diff --git a/package.json b/package.json index 105c380..d3b3926 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "deep-diff", "description": "Javascript utility for calculating deep difference, capturing changes, and applying changes across objects; for nodejs and the browser.", - "version": "1.0.2", + "version": "2.0-pre", "license": "MIT", "keywords": [ "diff", @@ -10,65 +10,56 @@ "change-tracking" ], "author": "Phillip Clark ", - "contributors": [ - "Simen Bekkhus ", - "Paul Pflugradt ", - "wooorm ", - "Nicholas Calugar ", - "Yandell ", - "Thiago Santos ", - "Steve Mao ", - "Mats Bryntse ", - "Phillip Clark ", - "ZauberNerd ", - "ravishivt ", - "Daniel Spangler ", - "Sam Beran ", - "Thomas de Barochez ", - "Morton Fox ", - "Amila Welihinda ", - "Will Biddy ", - "icesoar ", - "Serkan Serttop ", - "orlando ", - "Tom MacWright ", - "Denning ", - "Dan Drinkard ", - "Elad Efrat ", - "caasi Huang ", - "Tom Ashworth " - ], - "repository": { - "type": "git", - "url": "git://github.com/flitbit/diff.git" + "type": "module", + "devDependencies": { + "@faker-js/faker": "^8.3.1", + "@types/node": "~20", + "@types/tap": "^15.0.11", + "@typescript-eslint/eslint-plugin": "^6.16.0", + "@typescript-eslint/parser": "^6.16.0", + "chokidar-cli": "^3.0.0", + "deep-diff": "^1.0.2", + "eslint": "~8.56", + "eslint-config-prettier": "~9.1", + "eslint-plugin-tap": "^1.2.1", + "js-levenshtein": "^1.1.6", + "prettier": "~3.1", + "rimraf": "~5.0", + "tap": "^18.6.1", + "tap-parser": "^15.3.1", + "tap-xunit": "^2.4.1", + "ts-api-utils": "~1.0", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typescript": "~5.3", + "uuid": "^9.0.1" }, - "main": "./index.js", "scripts": { - "prerelease": "npm run clean && npm run test", - "release": "uglifyjs -c -m -o dist/deep-diff.min.js --source-map -r '$,require,exports,self,module,define,navigator' index.js", - "clean": "rimraf dist && mkdir dist", - "preversion": "npm run release", - "postversion": "git push && git push --tags", - "pretest": "npm run lint", - "test": "mocha test/**/*.js", - "test:watch": "nodemon --ext js,json --ignore dist/ --exec 'npm test'", - "preci": "npm run lint", - "ci": "mocha --reporter mocha-junit-reporter test/**/*.js", - "lint": "eslint index.js test" + "clean": "rimraf coverage dist tmp", + "prebuild": "npm run lint", + "build": "tsc -p tsconfig.json", + "build:watch": "tsc -w -p tsconfig.json", + "build:release": "npm run clean && tsc -p tsconfig.release.json", + "lint": "eslint . --ext .ts --ext .mts", + "test": "tap", + "test:watch": "chokidar test/**/*.ts src/**/*.ts **/*.json -i ./node_modules -i ./.tap -c 'npm run test' --polling", + "ts": "ts-node -r tsconfig-paths/register -r ts-node/register --loader ts-node/esm", + "prettier": "prettier --config .prettierrc --write ." }, - "devDependencies": { - "bluebird": "^3.5.1", - "deep-equal": "^1.0.1", - "eslint": "^4.19.1", - "eslint-plugin-mocha": "^5.0.0", - "expect.js": "^0.3.1", - "json": "^9.0.6", - "json-ptr": "^1.1.0", - "lodash": "^4.17.10", - "mocha": "^5.1.1", - "mocha-junit-reporter": "^1.17.0", - "nodemon": "^1.17.4", - "rimraf": "^2.6.2", - "uglify-js": "^3.3.25" + "dependencies": { + "tslib": "~2.6" + }, + "tap": { + "files": [ + "test/src", + "test/regression" + ], + "coverage-report": [ + "text", + "text-summary", + "json", + "json-summary" + ], + "timeout": 600 } } diff --git a/representation.md b/representation.md new file mode 100644 index 0000000..4ccc60a --- /dev/null +++ b/representation.md @@ -0,0 +1,10 @@ +# String Representation of Javascript Property Changes + +The primary string representation of Javascript entities is the JSON +representation provided by the language. We do not propose to change or +modify classic JSON, in fact, we encourage you to use JSON in contexts +where it suits your purpose. We offer another built in representation, +for preserving a record of change, in text form, that is concise and human +readable, as well as being easy to preserve, parse, process, and transmit. + +# Specification diff --git a/src/calculate-property-set.ts b/src/calculate-property-set.ts new file mode 100644 index 0000000..3424bed --- /dev/null +++ b/src/calculate-property-set.ts @@ -0,0 +1,179 @@ +export type PropertyOccurrence = [PropertyKey, number?, number?]; +export type PropertySet = PropertyOccurrence[]; + +/** + * Maps properties to their index. + * @param props list of properties + * @returns Map of property => index + */ +function indexProps(props: PropertyKey[]): Map { + const map = new Map(); + const len = props.length; + /** unroll loops up to 10 items */ + switch (len) { + case 0: { + break; + } + case 1: { + map.set(props[0], 0); + return map; + } + case 2: { + map.set(props[0], 0); + map.set(props[1], 1); + return map; + } + case 3: { + map.set(props[0], 0); + map.set(props[1], 1); + map.set(props[2], 2); + return map; + } + case 4: { + map.set(props[0], 0); + map.set(props[1], 1); + map.set(props[2], 2); + map.set(props[3], 3); + return map; + } + + case 5: { + map.set(props[0], 0); + map.set(props[1], 1); + map.set(props[2], 2); + map.set(props[3], 3); + map.set(props[4], 4); + return map; + } + case 6: { + map.set(props[0], 0); + map.set(props[1], 1); + map.set(props[2], 2); + map.set(props[3], 3); + map.set(props[4], 4); + map.set(props[5], 5); + return map; + } + case 7: { + map.set(props[0], 0); + map.set(props[1], 1); + map.set(props[2], 2); + map.set(props[3], 3); + map.set(props[4], 4); + map.set(props[5], 5); + map.set(props[6], 6); + return map; + } + case 8: { + map.set(props[0], 0); + map.set(props[1], 1); + map.set(props[2], 2); + map.set(props[3], 3); + map.set(props[4], 4); + map.set(props[5], 5); + map.set(props[6], 6); + map.set(props[7], 7); + return map; + } + case 9: { + map.set(props[0], 0); + map.set(props[1], 1); + map.set(props[2], 2); + map.set(props[3], 3); + map.set(props[4], 4); + map.set(props[5], 5); + map.set(props[6], 6); + map.set(props[7], 7); + map.set(props[8], 8); + return map; + } + case 10: { + map.set(props[0], 0); + map.set(props[1], 1); + map.set(props[2], 2); + map.set(props[3], 3); + map.set(props[4], 4); + map.set(props[5], 5); + map.set(props[6], 6); + map.set(props[7], 7); + map.set(props[8], 8); + map.set(props[9], 9); + return map; + } + } + // We have at-least 10 items, take them in chunks + let i = 0; + while (i < len - 10) { + map.set(props[i], i); + map.set(props[i + 1], i + 1); + map.set(props[i + 2], i + 2); + map.set(props[i + 3], i + 3); + map.set(props[i + 4], i + 4); + map.set(props[i + 5], i + 5); + map.set(props[i + 6], i + 6); + map.set(props[i + 7], i + 7); + map.set(props[i + 8], i + 8); + map.set(props[i + 9], i + 9); + i += 10; + } + while (i < len - 5) { + map.set(props[i], i); + map.set(props[i + 1], i + 1); + map.set(props[i + 2], i + 2); + map.set(props[i + 3], i + 3); + map.set(props[i + 4], i + 4); + i += 5; + } + while (i < len - 2) { + map.set(props[i], i); + map.set(props[i + 1], i + 1); + i += 2; + } + while (i < len) { + map.set(props[i], i++); + } + return map; +} + +/** + * Calculates the set of properties, and their locations + * in the specified objects. + * @param subject object the subject data object + * @param comparand object the comparand data object + * @returns the set of properties across both objects, + * and their locations relative to each + */ +export function calculatePropertySet( + subject: PropertyKey[], + comparand: PropertyKey[], +): PropertySet { + const leftLen = subject.length; + const rightLen = comparand.length; + const left = indexProps(subject); + const right = indexProps(comparand); + const leftProbe = Array(leftLen); + const props: PropertySet = []; + const len = Math.max(leftLen, rightLen); + let i = -1; + while (++i < len) { + if (i < rightLen) { + const p = comparand[i]; + const l = left.get(p); + if (l !== i && i < leftLen) { + const p = subject[i]; + const rr = right.get(p); + if (rr === undefined) { + props.push([p, i, rr]); + leftProbe[i] = true; + } + } + props.push([p, l, i]); + leftProbe[l] = true; + continue; + } + if (i < leftLen && !leftProbe[i]) { + props.push([subject[i], i, undefined]); + } + } + return props; +} diff --git a/src/changes/change-record.ts b/src/changes/change-record.ts new file mode 100644 index 0000000..3439680 --- /dev/null +++ b/src/changes/change-record.ts @@ -0,0 +1,166 @@ +import { decodePathPointer } from '../path-pointers/index.js'; +import { PathPointer } from '../path-pointers/types.js'; +import { StringTransform } from '../transforms/string-transform.js'; +import { + BasicPropertyChange, + PathSegments, + PropertyChange, + PropertyChangeKind, + Accessor, + Mutator, + Factory, +} from '../types.js'; + +const STRING_TRANSFORM_SYMBOL = Symbol('string-transform'); +const REGISTRY_SYMBOL = Symbol('registry'); + +export class ChangeRecord implements BasicPropertyChange { + static [REGISTRY_SYMBOL]: Map = new Map(); + static [STRING_TRANSFORM_SYMBOL]: StringTransform; + + static set stringTransform(transform: StringTransform) { + ChangeRecord[STRING_TRANSFORM_SYMBOL] = transform; + } + + static get stringTransform(): StringTransform { + if (!ChangeRecord[STRING_TRANSFORM_SYMBOL]) { + ChangeRecord[STRING_TRANSFORM_SYMBOL] = new StringTransform( + ChangeRecord.from, + { audit: true }, + ); + } + return ChangeRecord[STRING_TRANSFORM_SYMBOL]; + } + + static register(kind: PropertyChangeKind, factory: Factory): void { + ChangeRecord[REGISTRY_SYMBOL].set(kind, factory); + } + + static from(change: PropertyChange): PropertyChange { + if (change instanceof ChangeRecord) + return change as unknown as PropertyChange; + const factory = ChangeRecord[REGISTRY_SYMBOL].get(change.kind); + if (factory) return factory(change); + throw new Error(`Unrecognized change kind: ${change.kind}.`); + } + + get [Symbol.toStringTag](): string { + return 'ChangeRecord'; + } + + public readonly kind: PropertyChangeKind; + public readonly path: PathSegments; + public readonly pointer: string; + + constructor(kind: PropertyChangeKind, pathPointer: PathPointer) { + this.kind = kind; + const { path, pointer } = decodePathPointer(pathPointer); + this.path = path; + this.pointer = pointer; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + compact(_audit: boolean): Record { + const { kind, pointer } = this; + return { kind, pointer }; + } + + descendPath( + target: unknown, + accessor: Accessor, + mutator: Mutator, + createDuringDescent = true, + ): [unknown, PropertyKey] { + if (typeof target !== 'object') throw Error("Don't know how to do that!"); + const path = this.path; + let descent: object | unknown = target; + const last = path.length - 1; + let i = -1; + while (++i < last) { + const key = path[i]; + const subpath = path.slice(0, i + 1); + let prop = accessor(subpath, key, descent); + if (prop === undefined || (prop === null && createDuringDescent)) { + // If creating during descent, we infer the structure as either an + // object in the case of a string or symbol key, otherwise an array. + prop = mutator( + subpath, + key, + descent, + typeof path[i + 1] === 'number' ? [] : {}, + ); + } + descent = prop; + } + return [descent, path[last]]; + } + + apply( + target: unknown, + descend: boolean, + offset: number, + accessor: Accessor, + mutator: Mutator, + ): number { + if (descend) { + const [descent, key] = this.descendPath(target, accessor, mutator); + return this.performApply(descent, key, offset, mutator); + } else { + return this.performApply( + target, + this.path[this.path.length - 1], + offset, + mutator, + ); + } + } + + revert( + target: unknown, + descend: boolean, + offset: number, + accessor: Accessor, + mutator: Mutator, + ): number { + if (descend) { + const [descent, key] = this.descendPath(target, accessor, mutator); + return this.performRevert(descent, key, offset, mutator); + } else { + return this.performRevert( + target, + this.path[this.path.length - 1], + offset, + mutator, + ); + } + } + + protected performApply( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _target: unknown, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _key: PropertyKey, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _offset: number, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _mutator: Mutator, + ): number { + throw new Error('not implemented'); + } + protected performRevert( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _target: unknown, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _key: PropertyKey, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _offset: number, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _mutator: Mutator, + ): number { + throw new Error('not implemented'); + } + + public toString(): string { + const transform = ChangeRecord.stringTransform; + return transform.to(this as unknown as PropertyChange); + } +} diff --git a/src/changes/change-set.ts b/src/changes/change-set.ts new file mode 100644 index 0000000..3c29afe --- /dev/null +++ b/src/changes/change-set.ts @@ -0,0 +1,52 @@ +import { decodePathPointer } from '../path-pointers/index.js'; +import { PathPointer } from '../path-pointers/types.js'; +import { Accessor, Mutator, PathSegments, PropertyChanges } from '../types.js'; + +export class ChangeSet { + static from({ path, target, changes }): ChangeSet { + return Array.isArray(target) + ? new ArrayChangeSet(path, target, changes) + : new ObjectChangeSet(path, target, changes); + } + + public readonly path: PathSegments; + public readonly pointer: string; + public readonly target: unknown; + public readonly changes: PropertyChanges; + + constructor(path: PathPointer, target: unknown, changes: PropertyChanges) { + const p = decodePathPointer(path); + this.path = p.path; + this.pointer = p.pointer; + this.target = target; + this.changes = changes; + } + + apply(accessor: Accessor, mutator: Mutator): void { + for (const change of this.changes) { + change.apply(this.target, false, 0, accessor, mutator); + } + } + revert(accessor: Accessor, mutator: Mutator): void { + for (const change of this.changes) { + change.revert(this.target, false, 0, accessor, mutator); + } + } +} + +export class ArrayChangeSet extends ChangeSet { + apply(accessor: Accessor, mutator: Mutator): void { + let offset = 0; + for (const change of this.changes) { + offset = change.apply(this.target, false, offset, accessor, mutator); + } + } + revert(accessor: Accessor, mutator: Mutator): void { + let offset = 0; + for (const change of this.changes) { + offset = change.revert(this.target, false, offset, accessor, mutator); + } + } +} + +export class ObjectChangeSet extends ChangeSet {} diff --git a/src/changes/index.ts b/src/changes/index.ts new file mode 100644 index 0000000..90ca350 --- /dev/null +++ b/src/changes/index.ts @@ -0,0 +1,6 @@ +export * from './change-record.js'; +export * from './property-added-record.js'; +export * from './property-edited-record.js'; +export * from './property-moved-record.js'; +export * from './property-removed-record.js'; +export * from './types.js'; diff --git a/src/changes/property-added-record.ts b/src/changes/property-added-record.ts new file mode 100644 index 0000000..7422409 --- /dev/null +++ b/src/changes/property-added-record.ts @@ -0,0 +1,57 @@ +import { ChangeRecord } from './change-record.js'; +import { PathPointer } from '../path-pointers/types.js'; +import { PropertyAdded, PropertyChangeKinds, Mutator } from '../types.js'; + +export class PropertyAddedRecord extends ChangeRecord implements PropertyAdded { + get [Symbol.toStringTag](): string { + return 'PropertyAddedRecord'; + } + + public readonly comparand: unknown; + + constructor(path: PathPointer, comparand: unknown) { + super(PropertyChangeKinds.add, path); + this.comparand = comparand; + } + + compact(audit: boolean): Record { + return { + ...super.compact(audit), + comparand: this.comparand, + }; + } + + protected performApply( + target: unknown, + key: PropertyKey, + offset: number, + mutator: Mutator, + ): number { + if (Array.isArray(target) && typeof key === 'number') { + (target as unknown[]).splice(key + offset, 0, this.comparand); + } else { + mutator(this.path, key, target, this.comparand); + } + return offset + 1; + } + + protected performRevert( + target: unknown, + key: PropertyKey, + offset: number, + ): number { + if (Array.isArray(target) && typeof key === 'number') { + (target as unknown[]).splice(key + offset, 1); + } else { + delete target[key]; + } + return offset - 1; + } +} + +ChangeRecord.register(PropertyChangeKinds.add, (change) => { + const added = change as unknown as PropertyAdded; + return added instanceof PropertyAddedRecord + ? (added as PropertyAddedRecord) + : new PropertyAddedRecord(added.path || added.pointer, added.comparand); +}); diff --git a/src/changes/property-edited-record.ts b/src/changes/property-edited-record.ts new file mode 100644 index 0000000..1d937cb --- /dev/null +++ b/src/changes/property-edited-record.ts @@ -0,0 +1,69 @@ +import { ChangeRecord } from './change-record.js'; +import { PathPointer } from '../path-pointers/types.js'; +import { PropertyChangeKinds, PropertyEdited, Mutator } from '../types.js'; + +export class PropertyEditedRecord + extends ChangeRecord + implements PropertyEdited +{ + get [Symbol.toStringTag](): string { + return 'PropertyEditedRecord'; + } + + public readonly subject: unknown; + public readonly comparand: unknown; + + constructor(path: PathPointer, subject: unknown, comparand: unknown) { + super(PropertyChangeKinds.edit, path); + this.subject = subject; + this.comparand = comparand; + } + + compact(audit: boolean): Record { + const { subject, comparand } = this; + return { + ...super.compact(audit), + ...(audit ? { subject } : null), + comparand, + }; + } + + protected performApply( + target: unknown, + key: PropertyKey, + offset: number, + mutator: Mutator, + ): number { + if (Array.isArray(target) && typeof key === 'number') { + target[key + offset] = this.comparand; + } else { + mutator(this.path, key, target, this.comparand); + } + return offset; + } + + protected performRevert( + target: unknown, + key: PropertyKey, + offset: number, + mutator: Mutator, + ): number { + if (Array.isArray(target) && typeof key === 'number') { + target[key + offset] = this.subject; + } else { + mutator(this.path, key, target, this.subject); + } + return offset; + } +} + +ChangeRecord.register(PropertyChangeKinds.edit, (change) => { + const edited = change as unknown as PropertyEdited; + return edited instanceof PropertyEditedRecord + ? (edited as PropertyEditedRecord) + : new PropertyEditedRecord( + edited.path || edited.pointer, + edited.subject, + edited.comparand, + ); +}); diff --git a/src/changes/property-moved-record.ts b/src/changes/property-moved-record.ts new file mode 100644 index 0000000..f44682e --- /dev/null +++ b/src/changes/property-moved-record.ts @@ -0,0 +1,78 @@ +import { ChangeRecord } from './change-record.js'; +import { PathPointer } from '../path-pointers/types.js'; +import { PropertyChangeKinds, PropertyMoved } from '../types.js'; + +export class PropertyMovedRecord extends ChangeRecord implements PropertyMoved { + get [Symbol.toStringTag](): string { + return 'PropertyMovedRecord'; + } + + public readonly subject: unknown; + public readonly comparand: unknown; + public readonly origin: number; + + constructor( + path: PathPointer, + subject: unknown, + comparand: unknown, + origin: number, + ) { + super(PropertyChangeKinds.move, path); + this.subject = subject; + this.comparand = comparand; + this.origin = origin; + } + + compact(audit: boolean): Record { + const { subject, comparand, origin } = this; + return { + ...super.compact(audit), + ...(audit ? { subject, origin } : null), + comparand, + }; + } + + protected performApply( + target: unknown, + key: PropertyKey, + offset: number, + ): number { + // Moves are only supported in arrays + if (!Array.isArray(target) || typeof key !== 'number') + throw new Error(`Object path '${this.pointer}' must be an array`); + + // 1.) change new location to comparand + // 2.) remove old location (subject) + target[key + offset] = this.comparand; + (target as unknown[]).splice(this.origin + offset, 1); + return this.origin < key ? offset - 1 : 0; + } + + protected performRevert( + target: unknown, + key: PropertyKey, + offset: number, + ): number { + // Moves are only supported in arrays + if (!Array.isArray(target) || typeof key !== 'number') + throw new Error(`Object path '${this.pointer}' must be an array`); + + // 1.) restore subject at new location + // 2.) restore old location to comparand + target[key + offset] = this.subject; + (target as unknown[]).splice(this.origin, 0, this.comparand); + return this.origin < key ? offset + 1 : 0; + } +} + +ChangeRecord.register(PropertyChangeKinds.move, (change) => { + const moved = change as unknown as PropertyMoved; + return moved instanceof PropertyMovedRecord + ? (moved as PropertyMovedRecord) + : new PropertyMovedRecord( + moved.path || moved.pointer, + moved.subject, + moved.comparand, + moved.origin, + ); +}); diff --git a/src/changes/property-removed-record.ts b/src/changes/property-removed-record.ts new file mode 100644 index 0000000..38ac165 --- /dev/null +++ b/src/changes/property-removed-record.ts @@ -0,0 +1,61 @@ +import { ChangeRecord } from './change-record.js'; +import { PathPointer } from '../path-pointers/types.js'; +import { PropertyChangeKinds, PropertyRemoved, Mutator } from '../types.js'; + +export class PropertyRemovedRecord + extends ChangeRecord + implements PropertyRemoved +{ + get [Symbol.toStringTag](): string { + return 'PropertyMovedRecord'; + } + + public readonly subject: unknown; + + constructor(path: PathPointer, subject: unknown) { + super(PropertyChangeKinds.remove, path); + this.subject = subject; + } + + compact(audit: boolean): Record { + const { subject } = this; + return { + ...super.compact(audit), + ...(audit ? { subject } : null), + }; + } + + protected performApply( + target: unknown, + key: PropertyKey, + offset: number, + mutator: Mutator, + ): number { + if (Array.isArray(target) && typeof key === 'number') { + (target as unknown[]).splice(key + offset, 1); + } else { + mutator(this.path, key, target, undefined); + } + return offset - 1; + } + + protected performRevert( + target: unknown, + key: PropertyKey, + offset: number, + ): number { + if (Array.isArray(target) && typeof key === 'number') { + (target as unknown[]).splice(key, offset, this.subject); + } else { + target[key] = this.subject; + } + return offset + 1; + } +} + +ChangeRecord.register(PropertyChangeKinds.remove, (change) => { + const edited = change as unknown as PropertyRemoved; + return edited instanceof PropertyRemovedRecord + ? (edited as PropertyRemovedRecord) + : new PropertyRemovedRecord(edited.path || edited.pointer, edited.subject); +}); diff --git a/src/changes/types.ts b/src/changes/types.ts new file mode 100644 index 0000000..fdf3e97 --- /dev/null +++ b/src/changes/types.ts @@ -0,0 +1,12 @@ +import { PropertyAddedRecord } from './property-added-record.js'; +import { PropertyEditedRecord } from './property-edited-record.js'; +import { PropertyMovedRecord } from './property-moved-record.js'; +import { PropertyRemovedRecord } from './property-removed-record.js'; + +export type PropertyChangeRecord = + | PropertyAddedRecord + | PropertyEditedRecord + | PropertyRemovedRecord + | PropertyMovedRecord; + +export type PropertyChangeRecords = PropertyChangeRecord[]; diff --git a/src/compare-paths.ts b/src/compare-paths.ts new file mode 100644 index 0000000..7b535d5 --- /dev/null +++ b/src/compare-paths.ts @@ -0,0 +1,97 @@ +import { PathSegments } from './types.js'; + +function compareSegment(a: PropertyKey, b: PropertyKey): number { + if (typeof a === 'number' && typeof b === 'number') { + return a - b; + } + a = String(a); + b = String(b); + if (a === b) return 0; + return a > b ? 1 : -1; +} + +export function comparePaths(a: PathSegments, b: PathSegments): number { + if (a.length === b.length) { + const len = a.length; + switch (len) { + case 0: + return 0; + case 1: + return compareSegment(a[0], b[0]); + case 2: + return compareSegment(a[0], b[0]) || compareSegment(a[1], b[1]); + case 3: + return ( + compareSegment(a[0], b[0]) || + compareSegment(a[1], b[1]) || + compareSegment(a[2], b[2]) + ); + + case 4: + return ( + compareSegment(a[0], b[0]) || + compareSegment(a[1], b[1]) || + compareSegment(a[2], b[2]) || + compareSegment(a[3], b[3]) + ); + case 5: + return ( + compareSegment(a[0], b[0]) || + compareSegment(a[1], b[1]) || + compareSegment(a[2], b[2]) || + compareSegment(a[3], b[3]) || + compareSegment(a[4], b[4]) + ); + + case 6: + return ( + compareSegment(a[0], b[0]) || + compareSegment(a[1], b[1]) || + compareSegment(a[2], b[2]) || + compareSegment(a[3], b[3]) || + compareSegment(a[4], b[4]) || + compareSegment(a[5], b[5]) + ); + case 7: + return ( + compareSegment(a[0], b[0]) || + compareSegment(a[1], b[1]) || + compareSegment(a[2], b[2]) || + compareSegment(a[3], b[3]) || + compareSegment(a[4], b[4]) || + compareSegment(a[5], b[5]) || + compareSegment(a[6], b[6]) + ); + case 8: + return ( + compareSegment(a[0], b[0]) || + compareSegment(a[1], b[1]) || + compareSegment(a[2], b[2]) || + compareSegment(a[3], b[3]) || + compareSegment(a[4], b[4]) || + compareSegment(a[5], b[5]) || + compareSegment(a[6], b[6]) || + compareSegment(a[7], b[7]) + ); + default: { + let c = + compareSegment(a[0], b[0]) || + compareSegment(a[1], b[1]) || + compareSegment(a[2], b[2]) || + compareSegment(a[3], b[3]) || + compareSegment(a[4], b[4]) || + compareSegment(a[5], b[5]) || + compareSegment(a[6], b[6]) || + compareSegment(a[7], b[7]) || + compareSegment(a[8], b[8]); + + let i = 8; + while (++i < len && !c) { + c = compareSegment(a[i], b[i]); + } + return c; + } + } + } + return a.length > b.length ? 1 : -1; +} diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..ef46631 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,21 @@ +import { Accessor, Mutator } from './types.js'; + +export const DEFAULT_ACCESSOR: Accessor = (_, key, target): unknown => + target[key]; + +export const DEFAULT_MUTATOR: Mutator = (_, key, target, value): unknown => { + if (typeof value === 'undefined') { + // Our default is to delete properties that are set to undefined + // since simply setting it to undefined leaves the structure intact + delete target[key]; + return value; + } + return (target[key] = value); +}; + +export const DEFAULT_INCLUDE_NON_ENUMERABLE = false; +export const DEFAULT_INCLUDE_SYMBOLS = false; +export const DEFAULT_INCLUDE_FUNCTIONS = false; +export const DEFAULT_IGNORE_ARRAY_ORDER = false; +export const DEFAULT_REPORT_TYPE_CHANGES = false; +export const DEFAULT_REPORT_PROPERTY_ORDER_CHANGES = false; diff --git a/src/deep-diff.ts b/src/deep-diff.ts new file mode 100644 index 0000000..8d6ceab --- /dev/null +++ b/src/deep-diff.ts @@ -0,0 +1,933 @@ +import { calculatePropertySet } from './calculate-property-set.js'; +import { + ExtendedTypeOf, + PropertyAssignable, + extendedTypeOf, +} from './extended-type-of.js'; +import { murmur3Hash32 } from './murmur3-32.js'; +import { + Accessor, + Changes, + Deserializer, + Mutator, + Normalize, + PathSegments, + PropertyChange, + PropertyChangeKinds, + PropertyChangeWithComparand, + PropertyChangeWithSubject, + PropertyFilter, + Serializer, +} from './types.js'; +import { comparePaths } from './compare-paths.js'; +import { + DEFAULT_ACCESSOR, + DEFAULT_IGNORE_ARRAY_ORDER, + DEFAULT_INCLUDE_FUNCTIONS, + DEFAULT_INCLUDE_NON_ENUMERABLE, + DEFAULT_INCLUDE_SYMBOLS, + DEFAULT_MUTATOR, + DEFAULT_REPORT_PROPERTY_ORDER_CHANGES, + DEFAULT_REPORT_TYPE_CHANGES, +} from './constants.js'; +import { ChangeRecord } from './changes/change-record.js'; +import { PropertyAddedRecord } from './changes/property-added-record.js'; +import { PropertyEditedRecord } from './changes/property-edited-record.js'; +import { PropertyRemovedRecord } from './changes/property-removed-record.js'; +import { + PropertyChangeRecord, + PropertyChangeRecords, +} from './changes/types.js'; +import { + PathAndPointer, + encodePointer, + parentPath, +} from './path-pointers/index.js'; +import { ChangeSet } from './changes/change-set.js'; + +function fixPath(path: PathSegments): PathSegments { + return path.length && path[0] === '' ? path.slice(1) : path; +} + +type Indices = [number[], number[]]; +type ArrayMember = { + left: unknown; + right: unknown; + leftHash: number; + rightHash: number; + leftIndices?: Indices; + rightIndices?: Indices; +}; +type ArrayMembers = ArrayMember[]; + +function descendPath( + target: unknown, + path: PathSegments, + accessor: Accessor, + mutator: Mutator, + createDuringDescent = true, +): [unknown, PropertyKey] { + if (typeof target !== 'object') throw Error("Don't know how to do that!"); + let descent: object | unknown = target; + const last = path.length - 1; + let i = -1; + while (++i < last) { + const key = path[i]; + const subpath = path.slice(0, i + 1); + let prop = accessor(subpath, key, descent); + if (prop === undefined || (prop === null && createDuringDescent)) { + // If creating during descent, we infer the structure as either an + // object in the case of a string or symbol key, otherwise an array. + prop = mutator( + subpath, + key, + descent, + typeof path[i + 1] === 'number' ? [] : {}, + ); + } + descent = prop; + } + let prop = accessor(path, path[last], descent); + if (createDuringDescent && (prop === undefined || prop === null)) { + // If creating during descent, we infer the structure as either an + // object in the case of a string or symbol key, otherwise an array. + prop = mutator( + path, + path[last], + descent, + typeof path[i + 1] === 'number' ? [] : {}, + ); + } + return [descent, path[last]]; +} + +const DEFAULT_SERIALIZER: Serializer = (...changes: Changes[]): string => { + return JSON.stringify( + changes.length && !Array.isArray(changes[0]) + ? changes[0].compact(true) + : changes.flat().map((it) => it.compact(true)), + ); +}; +const DEFAULT_DESERIALIZER: Deserializer = (source: string): Changes => { + const it = JSON.parse(source); + return Array.isArray(it) + ? it.map(ChangeRecord.from.bind(null)) + : ChangeRecord.from(it); +}; + +export interface DeepDiffOptions { + includeNonEnumerable?: boolean; + includeSymbols?: boolean; + includeFunctions?: boolean; + ignoreArrayOrder?: boolean; + ignoreProperties?: PathSegments; + ignorePaths?: string[]; + reportTypePropertyChanges?: boolean; + reportPropertyOrderPropertyChanges?: boolean; + serializer?: Serializer; + deserializer?: Deserializer; + filter?: PropertyFilter; + normalize?: Normalize; + accessor?: Accessor; + mutator?: Mutator; +} + +export class DeepDiff { + public static DEFAULT_OPTIONS: DeepDiffOptions = { + includeNonEnumerable: DEFAULT_INCLUDE_NON_ENUMERABLE, + includeSymbols: DEFAULT_INCLUDE_SYMBOLS, + includeFunctions: DEFAULT_INCLUDE_FUNCTIONS, + ignoreArrayOrder: DEFAULT_IGNORE_ARRAY_ORDER, + reportTypePropertyChanges: DEFAULT_REPORT_TYPE_CHANGES, + reportPropertyOrderPropertyChanges: DEFAULT_REPORT_PROPERTY_ORDER_CHANGES, + serializer: DEFAULT_SERIALIZER, + deserializer: DEFAULT_DESERIALIZER, + accessor: DEFAULT_ACCESSOR, + mutator: DEFAULT_MUTATOR, + }; + + public includeNonEnumerable: boolean; + public includeSymbols: boolean; + public includeFunctions: boolean; + public ignoreArrayOrder: boolean; + public ignoreProperties?: PathSegments; + public ignorePaths?: string[]; + public reportTypePropertyChanges: boolean; + public reportPropertyOrderPropertyChanges: boolean; + public serializer: Serializer; + public deserializer: Deserializer; + public filter?: PropertyFilter; + public normalize?: Normalize; + public accessor: Accessor; + public mutator: Mutator; + + private ignoring: boolean; + + constructor(options?: DeepDiffOptions) { + const { + includeNonEnumerable, + includeSymbols, + includeFunctions, + ignoreArrayOrder, + ignoreProperties, + ignorePaths, + reportTypePropertyChanges, + reportPropertyOrderPropertyChanges, + serializer, + deserializer, + filter, + normalize, + accessor, + mutator, + } = { + ...DeepDiff.DEFAULT_OPTIONS, + ...options, + }; + this.includeNonEnumerable = includeNonEnumerable; + this.includeSymbols = includeSymbols; + this.includeFunctions = includeFunctions; + this.ignoreArrayOrder = ignoreArrayOrder; + this.ignoreProperties = ignoreProperties; + this.ignorePaths = ignorePaths; + this.ignoring = (ignoreProperties || ignorePaths) !== undefined; + this.reportTypePropertyChanges = reportTypePropertyChanges; + this.reportPropertyOrderPropertyChanges = + reportPropertyOrderPropertyChanges; + this.serializer = serializer || DEFAULT_SERIALIZER; + this.deserializer = deserializer || DEFAULT_DESERIALIZER; + this.filter = filter || null; + this.normalize = normalize || null; + this.accessor = accessor; + this.mutator = mutator; + } + + listComparableMembers( + subject: unknown, + path?: PathSegments, + cache?: Map, + isArray = false, + ): PathSegments { + path = path || []; + if ( + subject === undefined || + subject === null || + !PropertyAssignable.get(extendedTypeOf(subject)) + ) { + return []; + } + if (cache && cache.has(subject)) return cache.get(subject); + const { includeNonEnumerable, includeSymbols, includeFunctions } = this; + let props: PathSegments = Object.getOwnPropertyNames(subject); + if (includeSymbols) { + props = [...props, ...Object.getOwnPropertySymbols(subject)]; + } + const res: PathSegments = []; + for (const nameOrSymbol of props) { + if (typeof nameOrSymbol === 'symbol' && !includeSymbols) continue; + // for array types, filter length and array elements... + if ( + (isArray && + (nameOrSymbol === 'length' || + String(Number(nameOrSymbol)) === nameOrSymbol)) || + (this.ignoring && this._ignoreProperty(path, nameOrSymbol)) + ) { + continue; + } + const { value, get, enumerable } = Object.getOwnPropertyDescriptor( + subject, + nameOrSymbol, + ); + if (!enumerable && !includeNonEnumerable) continue; + // Getters shouldn't have side-effects, but many programs are suspect! + // TODO: consider accessor when getting from getter! + const resolvedValue = value || (get && subject[nameOrSymbol]); + if (typeof resolvedValue === 'function' && !includeFunctions) continue; + res.push(nameOrSymbol); + } + if (cache) cache.set(subject, res); + return res; + } + + _ignoreProperty(path: PathSegments, prop: PropertyKey): boolean { + const { ignoring, ignoreProperties, ignorePaths } = this; + if (ignoring && ignoreProperties && ignoreProperties.indexOf(prop) !== -1) + return true; + if (ignoring && ignorePaths) { + const pointer = encodePointer(path); + const len = ignorePaths.length; + let i = -1; + while (++i < len) { + if (pointer.indexOf(ignorePaths[i]) === 0) return true; + } + } + return false; + } + + *changes( + subject: unknown, + comparand: unknown, + path?: PathSegments, + leftStack?: Map, + rightStack?: Map, + ): Generator { + path = path || []; + const { filter, normalize, accessor } = this; + if (filter && filter(path, subject, comparand)) return; + if (normalize) { + const [normalizedSubject, normalizedComparand] = normalize( + path, + subject, + comparand, + ); + subject = normalizedSubject; + comparand = normalizedComparand; + } + if (subject === comparand) return; + leftStack = leftStack || new Map(); + rightStack = rightStack || new Map(); + const propCache = new Map(); + const subjectType = extendedTypeOf(subject); + const comparandType = extendedTypeOf(comparand); + const propertyTypeChanged = subjectType != comparandType; + if (propertyTypeChanged && comparandType === ExtendedTypeOf.undefined) { + // short-circuit on deletes + yield new PropertyRemovedRecord(path.slice(0), subject); + return; + } + const descending = + PropertyAssignable.get(comparandType) && subject !== comparand; + + const leftCycles = descending && leftStack.get(subject); + const rightCycles = descending && rightStack.get(comparand); + if (descending) { + leftStack.set(subject, path.length); + rightStack.set(comparand, path.length); + } + try { + switch (subjectType) { + case ExtendedTypeOf.object: + if (propertyTypeChanged) { + yield new PropertyEditedRecord(path.slice(0), subject, comparand); + return; + } + break; + case ExtendedTypeOf.array: + if (propertyTypeChanged) { + yield new PropertyEditedRecord(path.slice(0), subject, comparand); + return; + } + yield* this._arrayPropertyChanges( + path, + subject as Array, + comparand as Array, + leftStack, + rightStack, + ); + break; + case ExtendedTypeOf.date: + if ( + propertyTypeChanged || + (subject as Date).valueOf() !== (comparand as Date).valueOf() + ) { + yield new PropertyEditedRecord(path.slice(0), subject, comparand); + if (propertyTypeChanged) return; + } + break; + case ExtendedTypeOf.function: + if ( + !propertyTypeChanged && + subject.toString() !== comparand.toString() + ) { + yield new PropertyEditedRecord(path.slice(0), subject, comparand); + } + break; + case ExtendedTypeOf.regexp: + if (String(subject) !== String(comparand)) { + yield new PropertyEditedRecord(path.slice(0), subject, comparand); + return; + } + break; + case ExtendedTypeOf.number: { + const bothNaN = + isNaN(subject as number) && isNaN(comparand as number); + if (propertyTypeChanged || (subject !== comparand && !bothNaN)) { + yield new PropertyEditedRecord(path.slice(0), subject, comparand); + } + return; + } + case ExtendedTypeOf.bigint: + case ExtendedTypeOf.null: + case ExtendedTypeOf.string: + case ExtendedTypeOf.symbol: + case ExtendedTypeOf.undefined: + if (propertyTypeChanged || subject !== comparand) { + yield new PropertyEditedRecord(path.slice(0), subject, comparand); + } + return; + } + + if (!descending) { + yield new PropertyEditedRecord(path.slice(0), subject, comparand); + return; + } + if (leftCycles === rightCycles && leftCycles !== undefined) return; + const propsLeft = this.listComparableMembers( + subject, + path, + propCache, + subjectType === ExtendedTypeOf.array, + ); + const propsRight = this.listComparableMembers( + comparand, + path, + propCache, + comparandType === ExtendedTypeOf.array, + ); + const props = calculatePropertySet(propsLeft, propsRight).reverse(); + // Handle empty object case... + if (props.length === 0) return; + while (props.length) { + const [key, leftIndex, rightIndex] = props.pop(); + path.push(key); + try { + if (leftIndex === undefined) { + yield new PropertyAddedRecord( + path.slice(0), + accessor(path, key, comparand), + ); + continue; + } + if (rightIndex === undefined) { + yield new PropertyRemovedRecord( + path.slice(0), + accessor(path, key, subject), + ); + continue; + } + const left = accessor(path, key, subject); + const right = accessor(path, key, comparand); + yield* this.changes(left, right, path, leftStack, rightStack); + } finally { + path.pop(); + } + } + } finally { + if (descending) { + leftStack.delete(subject); + rightStack.delete(comparand); + } + } + } + + *calculateChangeSets( + target: unknown, + changes: PropertyChange[], + ): Generator { + const { accessor, mutator } = this; + const sorted = changes.sort(({ path: a }, { path: b }): number => + comparePaths(a, b), + ); + const len = sorted.length; + let i = -1; + let cacheTarget: unknown; + let cacheParent: PathAndPointer; + let cacheChanges: PropertyChange[]; + while (++i < len) { + const change = ChangeRecord.from(sorted[i]) as PropertyChangeRecord; + const parent = parentPath(change.path); + if (cacheParent?.pointer !== parent.pointer) { + if (cacheParent) { + yield ChangeSet.from({ + target: cacheTarget, + path: cacheParent.path, + changes: cacheChanges, + }); + } + if (parent.path.length) { + const [descent, key] = descendPath( + target, + parent.path, + accessor, + mutator, + true, + ); + cacheTarget = accessor(parent.path, key, descent); + } else { + cacheTarget = target; + } + cacheParent = parent; + cacheChanges = []; + } + cacheChanges.push(change); + } + if (cacheParent) { + yield ChangeSet.from({ + target: cacheTarget, + path: cacheParent.path, + changes: cacheChanges, + }); + } + } + + apply(target: unknown, ...changes: Changes[]): unknown { + const { accessor, mutator } = this; + const flat = changes.flat(); + if (flat.length === 1 && flat[0].path.length === 0) { + // Special case; root object changed + const change = ChangeRecord.from(flat[0]) as PropertyChangeRecord; + return change.kind !== PropertyChangeKinds.remove + ? (change as PropertyChangeWithComparand).comparand + : undefined; + } + for (const change of this.calculateChangeSets(target, flat)) { + change.apply(accessor, mutator); + } + return target; + } + + revert(target: unknown, ...changes: Changes[]): unknown { + const { accessor, mutator } = this; + const flat = changes.flat(); + if (flat.length === 1 && flat[0].path.length === 0) { + // Special case; root object changed + const change = ChangeRecord.from(flat[0]) as PropertyChangeRecord; + return (change as PropertyChangeWithSubject).subject; + } + for (const change of this.calculateChangeSets(target, flat)) { + change.revert(accessor, mutator); + } + return target; + } + + /** + * Used internally to calculates the changes within an array, using an + * implementation of the levenshtein distance algorithm that allows us to + * report each change. It is a memory efficient O(n+1) version, that + * avoids allocating a matrix. + * + * There are faster implementations, but they throw away information + * necessary to report the differences. The straight levenshtein distance + * is concerned with the number of differences, whereas we need the + * kinds of differences and where they occur. + */ + *_arrayPropertyChanges( + path: PathSegments, + subject: unknown[], + comparand: unknown[], + leftStack: Map, + rightStack: Map, + ): Generator { + let leftLen = subject.length; + let rightLen = comparand.length; + + if (subject === comparand || (rightLen === 0 && leftLen === 0)) return; + const filter = this.filter; + const cache = new Map(); + const { members, map } = this._indexMembers( + subject, + comparand, + path, + cache, + ); + + // remove equal ends of the array + let offset = 0; + let leftEnd = leftLen; + let rightEnd = rightLen; + + while ( + offset < leftEnd && + offset < rightEnd && + members[offset].leftHash == members[offset].rightHash + ) { + offset++; + } + while ( + offset < leftEnd && + offset < rightEnd && + members[leftEnd - 1].leftHash == members[rightEnd - 1].rightHash + ) { + leftEnd--; + rightEnd--; + } + + if (offset > 0 || leftEnd !== leftLen) { + leftLen = leftEnd - offset; + rightLen = rightEnd - offset; + } + + // left side is empty and right side isn't, then all + // items on right are added... + if (leftLen === 0 && rightLen) { + let i = -1; + while (++i < rightLen) { + const candidatePath = [...path, offset + i]; + if ( + filter === null || + !filter(candidatePath, undefined, comparand[offset + i]) + ) + yield new PropertyAddedRecord(candidatePath, comparand[offset + i]); + } + return; + } + // right side is empty and left side isn't, then all + // items on left are deleted... + if (rightLen === 0 && leftLen) { + let i = -1; + while (++i < leftLen) { + const candidatePath = [...path, offset + i]; + if ( + filter === null || + !filter(candidatePath, subject[offset + i], undefined) + ) + yield new PropertyRemovedRecord(candidatePath, subject[offset + i]); + } + return; + } + + const previousRow = [...Array(rightLen)].fill(0); + + for (let i = 1; i <= rightLen; ++i) { + previousRow[i] = i; + } + + const movedItems = Array(members.length); + const lookBehind: PropertyChangeRecords = []; + let count = 0; + for (let i = 1; i <= leftLen; ++i) { + const indexLeft = offset + i - 1; + let previousDiagonal = previousRow[0]; + let previousColumn = previousRow[0]++; + + for (let j = 1; j <= rightLen; ++j) { + const indexRight = offset + j - 1; + previousColumn = Math.min(previousColumn, previousDiagonal); + previousColumn = Math.min(previousColumn, previousRow[j]); + const v = ++previousColumn; + + if (i === leftLen && j > leftLen && v !== count) { + // add + count = v; + const candidatePath = [...path, indexRight]; + if ( + filter === null || + !filter(candidatePath, undefined, comparand[indexRight]) + ) + lookBehind.push( + movedItems[indexRight] + ? movedItems[indexRight] + : new PropertyAddedRecord(candidatePath, comparand[indexRight]), + ); + } else if (j === rightLen && i > rightLen && v !== count) { + // delete + count = v; + const candidatePath = [...path, indexLeft]; + if ( + filter === null || + !filter(candidatePath, subject[indexLeft], undefined) + ) + lookBehind.push( + movedItems[indexLeft] + ? movedItems[indexLeft] + : new PropertyRemovedRecord(candidatePath, subject[indexLeft]), + ); + } else if (i == j && v !== count) { + // edit + count = v; + const candidatePath = [...path, indexLeft]; + if ( + filter === null || + !filter(candidatePath, subject[indexLeft], comparand[indexLeft]) + ) + lookBehind.push( + movedItems[indexLeft] + ? movedItems[indexLeft] + : new PropertyEditedRecord( + candidatePath, + subject[indexLeft], + comparand[indexLeft], + ), + ); + } + + previousDiagonal = previousRow[j]; + previousRow[j] = previousColumn; + } + while (lookBehind.length) { + const change = lookBehind.shift(); + switch (change.kind) { + case PropertyChangeKinds.edit: { + const { + path: p, + subject, + comparand, + } = change as PropertyEditedRecord; + yield* this.changes(subject, comparand, p, leftStack, rightStack); + break; + } + case PropertyChangeKinds.move: { + // Special case for moves; don't descend. + const { + path: p, + subject, + comparand, + } = change as PropertyEditedRecord; + if ((p[p.length - 1] as number) >= leftEnd) { + yield new PropertyAddedRecord(p, comparand); + } else { + yield new PropertyEditedRecord(p, subject, comparand); + } + break; + } + default: + yield change; + } + } + } + } + + _checkStack(subject, stack, path, side): void { + if (stack.has(subject)) { + const prior = fixPath(path.slice(0, stack.get(subject) + 1)); + const checked = path; + throw new Error( + `Unsupported cycle, ${side} side: reference at '${prior}' cycles at '${checked}'`, + ); + } + } + + *_walkObjectForComparableProp( + left, + right, + props, + state, + ): Generator { + const { path } = state; + while (props.length && !state.siblingFound) { + const [prop, leftIndex, rightIndex] = props.pop(); + path.push(prop); + try { + if (leftIndex === undefined) { + yield new PropertyAddedRecord(path.slice(0), right[prop]); + continue; + } + if (rightIndex === undefined) { + yield new PropertyRemovedRecord(path.slice(0), left[prop]); + continue; + } + state.left = left[prop]; + state.right = right[prop]; + if (state.left !== state.right) { + state.siblingFound = true; + break; + } + } finally { + if (!state.siblingFound) path.pop(); + } + } + } + + looksEqual( + left: unknown, + right: unknown, + path?: PathSegments, + map?: Map, + ): boolean { + if (map) { + let hashLeft = map.get(left); + if (hashLeft === undefined) { + hashLeft = this.hashUnknown(left, path, map); + } + let hashRight = map.get(right); + if (hashRight === undefined) { + hashRight = this.hashUnknown(right, path, map); + } + return hashRight === hashLeft; + } + return false; + } + + hashString(subject: string, map?: Map): number { + let hash = (map && map.get(subject)) || 0; + if (!hash) { + hash = murmur3Hash32(subject); + if (map) map.set(subject, hash); + } + return hash; + } + + hashArray( + subject: unknown[], + path?: PathSegments, + map?: Map, + stack?: Map, + ): number { + path = path || []; + map = map || new Map(); + let hash = map.get(subject) || 0; + if (!hash) { + stack = stack || new Map(); + if (stack.get(subject) !== undefined) + throw new Error('Unsupported cycle encountered in the graph'); + stack.set(subject, stack.size); + try { + const { ignoreArrayOrder } = this; + const len = subject.length; + if (len) { + let i = -1; + while (++i < len) { + let itemHash = this.hashUnknown(subject[i], path, map, stack); + if (!ignoreArrayOrder) { + itemHash = this.hashString( + `${ExtendedTypeOf.array} [${i}] ${itemHash}`, + map, + ); + } + hash += itemHash; + } + } + hash += this.hashString(`${ExtendedTypeOf.array} ${hash}`, map); + map.set(subject, hash); + } finally { + stack.delete(subject); + } + } + return hash; + } + + hashObject( + subject: unknown, + path?: PathSegments, + map?: Map, + stack?: Map, + ): number { + const { includeSymbols } = this; + path = path || []; + map = map || new Map(); + let hash = map.get(subject) || 0; + if (!hash) { + stack = stack || new Map(); + if (stack.get(subject) !== undefined) + throw new Error('Unsupported cycle encountered in the graph'); + stack.set(subject, stack.size); + try { + const obj = subject as Record; + const props = this.listComparableMembers(obj, path); + const len = props.length; + let i = -1; + while (++i < len) { + const key = props[i]; + const name = + includeSymbols && typeof key === 'symbol' + ? `Symbol(${(key as symbol).description}` + : (key as string); + const itemHash = this.hashUnknown(obj[key], path, map, stack); + hash += this.hashString( + `${ExtendedTypeOf.object} .${name} ${itemHash}`, + ); + } + map.set(subject, hash); + } finally { + stack.delete(subject); + } + } + return hash; + } + + hashUnknown( + value: unknown, + path?: PathSegments, + map?: Map, + stack?: Map, + ): number { + const type = extendedTypeOf(value); + switch (type) { + case ExtendedTypeOf.object: + return this.hashObject( + value as Record, + path, + map, + stack, + ); + case ExtendedTypeOf.array: + return this.hashArray(value as unknown[], path, map, stack); + case ExtendedTypeOf.string: + case ExtendedTypeOf.number: + case ExtendedTypeOf.bigint: + case ExtendedTypeOf.undefined: + case ExtendedTypeOf.null: + case ExtendedTypeOf.date: + case ExtendedTypeOf.function: + case ExtendedTypeOf.regexp: + case ExtendedTypeOf.math: + return this.hashString(`${type} ${value}`); + case ExtendedTypeOf.symbol: + return this.hashString(`${type} ${String(value)}`); + } + throw new Error(`Unsupported typeof: ${type}`); + } + + private _indexMembers( + subject: unknown[], + comparand: unknown[], + path: PathSegments, + cache?: Map, + ): { members: ArrayMembers; map: Map } { + const map = new Map(); + const leftLen = subject.length; + const rightLen = comparand.length; + const len = Math.max(leftLen, rightLen); + const members: ArrayMembers = Array(len); + let i = -1; + while (++i < len) { + const left = subject[i]; + const right = comparand[i]; + const itemPath = [...path, i]; + let leftHash = NaN; + let rightHash = NaN; + let leftIndices: Indices; + let rightIndices: Indices; + if (i < leftLen) { + leftHash = this.hashUnknown(left, itemPath, cache); + let indexed = map.get(leftHash); + if (!indexed) { + indexed = [[], []]; + map.set(leftHash, indexed); + } + indexed[0].push(i); + leftIndices = indexed; + } + if (i < rightLen) { + rightHash = this.hashUnknown(right, itemPath, cache); + let indexed = map.get(rightHash); + if (!indexed) { + indexed = [[], []]; + map.set(rightHash, indexed); + } + indexed[1].push(i); + rightIndices = indexed; + } + members[i] = { + left, + right, + leftHash, + rightHash, + leftIndices, + rightIndices, + }; + } + return { members, map }; + } + + stringify(...changes: Changes[]): string { + return this.serializer( + changes.length && !Array.isArray(changes[0]) + ? changes[0] + : changes.flat(), + ); + } + + parse(changes: string): Changes { + return this.deserializer(changes); + } +} diff --git a/src/extended-type-of.ts b/src/extended-type-of.ts new file mode 100644 index 0000000..30d52ac --- /dev/null +++ b/src/extended-type-of.ts @@ -0,0 +1,51 @@ +export enum ExtendedTypeOf { + array, + bigint, + date, + function, + map, + math, + null, + number, + object, + regexp, + set, + string, + symbol, + undefined, +} + +export const PropertyAssignable = new Map([ + [ExtendedTypeOf.array, true], + [ExtendedTypeOf.date, true], // ??! + [ExtendedTypeOf.bigint, false], + [ExtendedTypeOf.function, true], + [ExtendedTypeOf.map, true], // ??! + [ExtendedTypeOf.math, true], // ??! + [ExtendedTypeOf.null, false], + [ExtendedTypeOf.number, false], + [ExtendedTypeOf.object, true], + [ExtendedTypeOf.regexp, true], // ??! + [ExtendedTypeOf.set, true], // ??! + [ExtendedTypeOf.string, false], + [ExtendedTypeOf.symbol, false], + [ExtendedTypeOf.undefined, false], +]); + +export function extendedTypeOf(subject: unknown): ExtendedTypeOf { + const type = typeof subject; + if (type !== 'object') return ExtendedTypeOf[type]; + if (subject === null) return ExtendedTypeOf.null; + if (Array.isArray(subject)) return ExtendedTypeOf.array; + const objectStringTag = Object.prototype.toString.call(subject); + // Short circuit on object, it is probably most common. + if (objectStringTag === '[object Object]') return ExtendedTypeOf.object; + if (objectStringTag === '[object Date]') return ExtendedTypeOf.date; + if (objectStringTag === '[object Map]') return ExtendedTypeOf.map; + if (objectStringTag === '[object Math]') return ExtendedTypeOf.math; + if (objectStringTag === '[object RegExp]') return ExtendedTypeOf.regexp; + if (objectStringTag === '[object Set]') return ExtendedTypeOf.set; + // TODO: Decide what to do about Buffer, which occurs often in node. + // ...all others are objects. + return ExtendedTypeOf.object; +} diff --git a/src/murmur3-32.ts b/src/murmur3-32.ts new file mode 100644 index 0000000..60583bb --- /dev/null +++ b/src/murmur3-32.ts @@ -0,0 +1,102 @@ +// Adapted from https://github.com/pid/murmurHash3js's x86 version of murmur3 +// murmurHash3js bears the following MIT license: +// +// The MIT License (MIT) +// Copyright (c) 2012-2015 Karan Lyons, Sascha Droste +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// ============================================================================ +// Our modifications are for speed; primarily inlining the functions [multiply, +// rotl, and final-mix]. Essentially, we made it a lot harder to understand, +// but removed several clock-cycles. + +export function murmur3Hash32(key = '', seed = 0): number { + // + // Given a string and an optional seed as an int, returns a 32 bit hash + // using the x86 flavor of MurmurHash3, as an unsigned int. + // + const remainder = key.length % 4; + const bytes = key.length - remainder; + + let h1 = seed; + let k1 = 0; + + const c1 = 0xcc9e2d51; + const c2 = 0x1b873593; + let i = 0; + while (i < bytes) { + k1 = + (key.charCodeAt(i) & 0xff) | + ((key.charCodeAt(i + 1) & 0xff) << 8) | + ((key.charCodeAt(i + 2) & 0xff) << 16) | + ((key.charCodeAt(i + 3) & 0xff) << 24); + + k1 = (k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16); + k1 = (k1 << 15) | (k1 >>> (32 - 15)); + k1 = (k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16); + + h1 ^= k1; + h1 = (h1 << 13) | (h1 >>> (32 - 13)); + h1 = (h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16) + 0xe6546b64; + i += 4; + } + + k1 = 0; + + switch (remainder) { + case 3: + k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16; + k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; + k1 ^= key.charCodeAt(i) & 0xff; + k1 = (k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16); + k1 = (k1 << 15) | (k1 >>> (32 - 15)); + k1 = (k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16); + h1 ^= k1; + break; + + case 2: + k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; + k1 ^= key.charCodeAt(i) & 0xff; + k1 = (k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16); + k1 = (k1 << 15) | (k1 >>> (32 - 15)); + k1 = (k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16); + h1 ^= k1; + break; + case 1: + k1 ^= key.charCodeAt(i) & 0xff; + k1 = (k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16); + k1 = (k1 << 15) | (k1 >>> (32 - 15)); + k1 = (k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16); + h1 ^= k1; + break; + } + + h1 ^= key.length; + // final mix + h1 ^= h1 >>> 16; + h1 = + (h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16); + h1 ^= h1 >>> 13; + h1 = + (h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16); + h1 ^= h1 >>> 16; + + return h1 >>> 0; +} diff --git a/src/parse-utils.ts b/src/parse-utils.ts new file mode 100644 index 0000000..d01c79a --- /dev/null +++ b/src/parse-utils.ts @@ -0,0 +1,173 @@ +import { ok } from 'assert'; + +export const DOT = '.'; +export const OPEN_BRACE = '['; +export const CLOSE_BRACE = ']'; +export const QUOTE = '"'; +export const DELIMITER = '\\'; +export const COMMA = ','; +export const HASH = '#'; + +const D0 = '0'; +const D9 = '9'; + +export function seekEndQuote( + str: string, + offset = 0, + quote = QUOTE, + delimiter = DELIMITER, +): number { + const len = str.length; + let cursor = offset; + while (cursor < len) { + const i = str.indexOf(quote, cursor); + if (i === -1) break; + // skip the quote if it is delimited + if (i > offset && str[i - 1] === delimiter) { + cursor = i + 1; + } else return i; + } + return -1; +} + +export function quote(str: string): string { + return `"${str.replace(/"/g, '\\"')}"`; +} + +export function unquote(str: string): string { + return str.slice(0, str.length).replace(/\\"/g, QUOTE); +} + +export function expectCh( + str: string, + cursor: number, + ch: string, + description?: string, +): void { + ok(cursor >= 0 && cursor < str.length, 'cursor out of range'); + if (str[cursor] !== ch) { + throw new Error( + `expected ${description || `"${ch}"`} but received (${ + str[cursor] + }) at ${cursor}.`, + ); + } +} +export function expectOneOf( + str: string, + cursor: number, + chars: T[], + description?: string, +): T { + ok(cursor >= 0 && cursor < str.length, 'cursor out of range'); + const ch = str[cursor]; + const numChars = chars.length; + switch (numChars) { + case 0: + break; + case 1: { + if (ch == chars[0]) return chars[0]; + break; + } + case 2: { + if (ch == chars[0]) return chars[0]; + if (ch == chars[1]) return chars[1]; + break; + } + case 3: { + if (ch == chars[0]) return chars[0]; + if (ch == chars[1]) return chars[1]; + if (ch == chars[2]) return chars[2]; + break; + } + default: { + if (ch == chars[0]) return chars[0]; + if (ch == chars[1]) return chars[1]; + if (ch == chars[2]) return chars[2]; + if (ch == chars[3]) return chars[3]; + let i = 3; + while (++i < numChars) { + if (ch === chars[i]) return chars[i]; + } + } + } + throw new Error( + `expected ${ + description || chars.map((c) => `"${c}"`).join(' | ') + }} but received "${ch}" at ${cursor}.`, + ); +} + +export function sliceTo( + str: string, + cursor = 0, + ch: string, +): { found: string; at: number } { + const at = str.indexOf(ch, cursor); + const found = at === -1 ? '' : str.slice(cursor, at); + return { found, at }; +} + +export function sliceToOneOf( + str: string, + cursor = 0, + ch: string[], +): { found: string; at: number } { + if (str.length === 0) return { found: '', at: -1 }; + const len = str.length; + const count = ch.length; + let found = ''; + let at = -1; + let i = cursor - 1; + // Just the cases we need. + switch (count) { + case 1: + return sliceTo(str, cursor, ch[0]); + case 2: { + while (++i < len) { + if (ch[0] === str[i] || ch[1] === str[i]) { + at = i; + found = str.slice(cursor, at); + break; + } + } + break; + } + case 3: { + while (++i < len) { + if (ch[0] === str[i] || ch[1] === str[i] || ch[2] === str[i]) { + at = i; + found = str.slice(cursor, at); + break; + } + } + } + } + return { found, at }; +} + +export function sliceToNonDigit( + str: string, + cursor = 0, +): { found: string; at: number } { + const len = str.length; + let at = cursor - 1; + while (++at < len) { + if (str[at] < D0 || str[at] > D9) + return { found: str.slice(cursor, at), at }; + } + return { found: '', at: -1 }; +} + +export function expectOnlyDecimalCharacters(str: string, cursor = 0): void { + const len = str.length; + let i = -1; + while (++i < len) { + if (str[i] < D0 || str[i] > D9) + throw new Error( + `Invalid dot-notation; index starting at ${cursor} contains an invalid decimal character at ${ + cursor + i + }.`, + ); + } +} diff --git a/src/path-pointers/dotted-notation.ts b/src/path-pointers/dotted-notation.ts new file mode 100644 index 0000000..df1f686 --- /dev/null +++ b/src/path-pointers/dotted-notation.ts @@ -0,0 +1,229 @@ +import { + CLOSE_BRACE, + DOT, + OPEN_BRACE, + QUOTE, + expectCh, + expectOneOf, + expectOnlyDecimalCharacters, + quote, + sliceTo, + sliceToOneOf, + unquote, +} from '../parse-utils.js'; +import { PathSegments } from '../types.js'; +import { PathSchemeCodec } from './types.js'; + +/** + * Determines if a string matches the following identifier grammar + * + * Identifier :: + * IdentifierName but not ReservedWord + * + * IdentifierName :: + * IdentifierStart + * IdentifierName IdentifierPart + * + * IdentifierStart :: + * UnicodeLetter + * $ + * _ + * \ UnicodeEscapeSequence + * + * IdentifierPart :: + * IdentifierStart + * UnicodeCombiningMark + * UnicodeDigit + * UnicodeConnectorPunctuation + * \ UnicodeEscapeSequence + * + * UnicodeLetter + * any character in the Unicode categories “Uppercase letter (Lu)”, “Lowercase letter (Ll)”, “Titlecase letter (Lt)”, + * “Modifier letter (Lm)”, “Other letter (Lo)”, or “Letter number (Nl)”. + * + * UnicodeCombiningMark + * any character in the Unicode categories “Non-spacing mark (Mn)” or “Combining spacing mark (Mc)” + * + * UnicodeDigit + * any character in the Unicode category “Decimal number (Nd)” + * + * UnicodeConnectorPunctuation + * any character in the Unicode category “Connector punctuation (Pc)” + * + * UnicodeEscapeSequence + * see 7.8.4. + * + * HexDigit :: one of + * 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F + * + * + */ +const ALWAYS_QUOTE = [ + // keywords + 'break', + 'case', + 'catch', + 'class', + 'const', + 'continue', + 'debugger', + 'default', + 'delete', + 'do', + 'else', + 'export', + 'extends', + 'false', + 'finally', + 'for', + 'function', + 'if', + 'import', + 'in', + 'instanceof', + 'new', + 'null', + 'return', + 'super', + 'switch', + 'this', + 'throw', + 'true', + 'try', + 'typeof', + 'var', + 'void', + 'while', + 'with', + // strict mode keywords + 'let', + 'static', + 'yield', + // module/async keyword + 'await', + // future reserved words + 'enum', + // reserved in strict mode + 'implements', + 'interface', + 'package', + 'private', + 'protected', + 'public', + // reserved in older standards + 'abstract', + 'boolean', + 'byte', + 'char', + 'double', + 'final', + 'float', + 'goto', + 'int', + 'long', + 'native', + 'short', + 'synchronized', + 'throws', + 'transient', + 'volatile', + // special meaning + 'arguments', + 'as', + 'async', + 'eval', + 'from', + 'get', + 'of', + 'set', +].sort(); + +function isEcmaScriptWord(word: string): boolean { + // binary search + let start = 0; + let end = ALWAYS_QUOTE.length - 1; + while (start <= end) { + const mid = Math.floor((start + end) / 2); + if (ALWAYS_QUOTE[mid] === word) return true; + else if (ALWAYS_QUOTE[mid] < word) start = mid + 1; + else end = mid - 1; + } + return false; +} + +const IDENTIFIER_RE = + /^[$_\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}][$_\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}\u200C\u200D\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/u; + +function mustQuote(candidate: string): boolean { + return !IDENTIFIER_RE.test(candidate) || isEcmaScriptWord(candidate); +} + +class DottedPathPointerCodec implements PathSchemeCodec { + public encode(path: PathSegments): string { + const len = path.length; + if (len === 0) return DOT; + let dotted = ''; + let i = -1; + while (++i < len) { + let it = path[i]; + if (typeof it === 'number') { + dotted += `.[${it}]`; + } else { + it = String(it); + dotted += mustQuote(it) ? `.[${quote(it)}]` : `.${it}`; + } + } + return dotted; + } + + decode(dotted: string): PathSegments { + const keys: PathSegments = []; + const len = dotted.length; + let cursor = 0; + if (dotted[cursor] === DOT) cursor++; + while (cursor < len) { + if (dotted[cursor] === OPEN_BRACE) { + cursor++; + if (dotted[cursor] === QUOTE) { + const { found, at } = sliceTo(dotted, cursor + 1, CLOSE_BRACE); + if (at === -1) { + throw new Error( + `Invalid dot-notation; unterminated double-quote starting at ${cursor}.`, + ); + } + const key = unquote(found); + keys.push(key); + cursor = at; + expectCh(dotted, cursor++, CLOSE_BRACE); + } else { + // If not a double-quoted string, it must be an array index. + const { found, at } = sliceTo(dotted, cursor, CLOSE_BRACE); + if (at === -1) { + throw new Error( + `Invalid dot-notation; unterminated open-brace starting at ${cursor}.`, + ); + } + expectOnlyDecimalCharacters(found, cursor); + keys.push(parseInt(found, 10)); + cursor = at + 1; + } + } else { + const { found, at } = sliceToOneOf(dotted, cursor, [DOT, OPEN_BRACE]); + if (at === cursor) + throw new Error( + `Invalid dot-notation; empty path segment at ${cursor} not allowed.`, + ); + keys.push(at !== -1 ? found : dotted.slice(cursor)); + cursor = at === -1 ? len : at; + } + // expect dot separating keys + if (cursor < len) { + const ch = expectOneOf(dotted, cursor, [DOT, OPEN_BRACE]); + if (ch === DOT) cursor++; + } + } + return keys; + } +} + +export const dottedPathSchemeCodec = new DottedPathPointerCodec(); diff --git a/src/path-pointers/fragment-pointer-notation.ts b/src/path-pointers/fragment-pointer-notation.ts new file mode 100644 index 0000000..ded7ed6 --- /dev/null +++ b/src/path-pointers/fragment-pointer-notation.ts @@ -0,0 +1,76 @@ +import { PathSegments } from '../types.js'; +import { PathSchemeCodec } from './types.js'; + +const D0 = '0'; +const D9 = '9'; + +function decodePointerSegments(path: PathSegments): PathSegments { + let i = -1; + const len = path.length; + const segments: PathSegments = new Array(len); + while (++i < len) { + const segment = decodeURIComponent(String(path[i])) + .replaceAll('~1', '/') + .replaceAll('~0', '~'); + if ( + segment.length && + segment[0] >= D0 && + segment[0] <= D9 && + String(Number(segment)) === segment + ) { + segments[i] = Number(segment); + } else { + segments[i] = segment; + } + } + return segments; +} + +function encodePointerSegments(segments: PathSegments): PathSegments { + let i = -1; + const len = segments.length; + const res = new Array(len); + while (++i < len) { + if (typeof segments[i] === 'number') { + res[i] = segments[i]; + } else { + res[i] = encodeURIComponent( + String(segments[i]).replaceAll('~', '~0').replaceAll('/', '~1'), + ); + } + } + return res; +} + +class UriFragmentPointerCodec implements PathSchemeCodec { + public encode(path: PathSegments): string { + if (!path || (path && !Array.isArray(path))) { + throw new TypeError('Invalid type: path must be an array of segments.'); + } + if (path.length === 0) { + return '#'; + } + return `#/${encodePointerSegments(path).join('/')}`; + } + decode(pointer: string): PathSegments { + if (typeof pointer !== 'string') { + throw new TypeError( + 'Invalid type: JSON Pointers are represented as strings.', + ); + } + if (pointer.length === 0 || pointer[0] !== '#') { + throw new ReferenceError( + 'Invalid JSON Pointer; URI fragment identifiers must begin with a hash.', + ); + } + if (pointer.length === 1) { + return []; + } + if (pointer[1] !== '/') { + throw new ReferenceError('Invalid JSON Pointer syntax.'); + } + return decodePointerSegments(pointer.substring(2).split('/')); + } +} + +export const uriFragmentPointerCodec = new UriFragmentPointerCodec(); diff --git a/src/path-pointers/index.ts b/src/path-pointers/index.ts new file mode 100644 index 0000000..b292c8d --- /dev/null +++ b/src/path-pointers/index.ts @@ -0,0 +1,66 @@ +import { DOT, HASH, OPEN_BRACE, expectOneOf } from '../parse-utils.js'; +import { PathSegments } from '../types.js'; +import { dottedPathSchemeCodec } from './dotted-notation.js'; +import { uriFragmentPointerCodec } from './fragment-pointer-notation.js'; +import { jsonSchemeCodec } from './json-notation.js'; +import { + PathAndPointer, + PathPointer, + PathScheme, + PathSchemeCodec, + PathSchemes, +} from './types.js'; + +let defaultScheme = PathSchemes.pointer; + +export function getDefaultPathScheme(): PathScheme { + return defaultScheme; +} + +export function setDefaultPathScheme(scheme: PathScheme): PathScheme { + if (!PathSchemes[scheme]) + throw new Error(`Unrecognized path scheme: ${scheme}`); + const recent = defaultScheme; + defaultScheme = scheme; + return recent; +} + +export function selectPathSchemeCodec(scheme?: PathScheme): PathSchemeCodec { + const which = PathSchemes[scheme || defaultScheme]; + if (which === PathSchemes.pointer) return uriFragmentPointerCodec; + if (which === PathSchemes.dotted) return dottedPathSchemeCodec; + if (which === PathSchemes.json) return jsonSchemeCodec; + throw new Error(`Unrecognized path scheme: ${scheme}`); +} + +export function encodePointer(path: PathSegments, scheme?: PathScheme): string { + const which = PathSchemes[scheme || defaultScheme]; + if (which === PathSchemes.pointer) + return uriFragmentPointerCodec.encode(path); + if (which === PathSchemes.dotted) return dottedPathSchemeCodec.encode(path); + if (which === PathSchemes.json) return jsonSchemeCodec.encode(path); + throw new Error(`Unrecognized path scheme: ${scheme}`); +} + +export function decodePointer(pointer: string): PathSegments { + const which = expectOneOf(pointer, 0, [HASH, DOT, OPEN_BRACE]); + if (which === HASH) return uriFragmentPointerCodec.decode(pointer); + if (which === DOT) return dottedPathSchemeCodec.decode(pointer); + return jsonSchemeCodec.decode(pointer); +} + +export function decodePathPointer(target: PathPointer): PathAndPointer { + // Normalize pointer to the default notation. + const isPointer = typeof target === 'string'; + const path = isPointer ? decodePointer(target) : (target as PropertyKey[]); + return { path, pointer: encodePointer(path, defaultScheme) }; +} + +export function parentPath(path: PathPointer): PathAndPointer { + return decodePathPointer(path.slice(0, path.length - 1)); +} + +export * from './types.js'; +export * from './dotted-notation.js'; +export * from './fragment-pointer-notation.js'; +export * from './json-notation.js'; diff --git a/src/path-pointers/json-notation.ts b/src/path-pointers/json-notation.ts new file mode 100644 index 0000000..735c601 --- /dev/null +++ b/src/path-pointers/json-notation.ts @@ -0,0 +1,68 @@ +import { + CLOSE_BRACE, + COMMA, + OPEN_BRACE, + QUOTE, + expectCh, + expectOneOf, + sliceTo, + sliceToNonDigit, +} from '../parse-utils.js'; +import { PathSegments } from '../types.js'; +import { PathSchemeCodec } from './types.js'; + +class JsonSchemeCodec implements PathSchemeCodec { + encode(path: PathSegments): string { + const segments: string[] = []; + const len = path.length; + let i = -1; + while (++i < len) { + const segment = path[i]; + segments.push( + typeof segment === 'number' + ? String(segment) + : `"${encodeURIComponent(String(segment))}"`, + ); + } + return OPEN_BRACE + segments.join(COMMA) + CLOSE_BRACE; + } + + decode(path: string): PathSegments { + const segments: PathSegments = []; + const len = path.length; + let cursor = 0; + expectCh(path, cursor++, OPEN_BRACE); + while (cursor < len && path[cursor] !== CLOSE_BRACE) { + if (path[cursor] === QUOTE) { + const { found, at } = sliceTo(path, cursor + 1, QUOTE); + if (at === -1) { + throw new Error( + `Invalid json scheme; unterminated double-quote starting at ${cursor}.`, + ); + } + const key = decodeURIComponent(found); + segments.push(key); + cursor = at + 1; + } else { + // If not a double-quoted string, it must be an array index. + const { found, at } = sliceToNonDigit(path, cursor); + if (at === -1) { + throw new Error( + `Invalid json scheme; number starting at ${cursor} must be followed by COMMA or CLOSE_BRACE.`, + ); + } + expectOneOf(path, at, [COMMA, CLOSE_BRACE]); + segments.push(parseInt(found, 10)); + cursor = at; + } + if (path[cursor] === CLOSE_BRACE) return segments; + if (cursor < len && path[cursor] === COMMA) { + cursor++; + } + } + expectCh(path, cursor, CLOSE_BRACE); + return segments; + } +} + +export const jsonSchemeCodec = new JsonSchemeCodec(); diff --git a/src/path-pointers/types.ts b/src/path-pointers/types.ts new file mode 100644 index 0000000..878d621 --- /dev/null +++ b/src/path-pointers/types.ts @@ -0,0 +1,22 @@ +import { PathSegments } from '../types.js'; + +export type PathScheme = 'json' | 'pointer' | 'dotted'; +export type PathPointer = PathSegments | string; +export type PathAndPointer = { + path: PathSegments; + pointer: string; +}; + +export type EncodePath = (path: PathSegments) => string; +export type DecodePath = (path: string) => PathSegments; + +export const PathSchemes: Record = Object.freeze({ + dotted: 'dotted', + json: 'json', + pointer: 'pointer', +}); + +export interface PathSchemeCodec { + encode: EncodePath; + decode: DecodePath; +} diff --git a/src/transforms/string-transform.ts b/src/transforms/string-transform.ts new file mode 100644 index 0000000..3c328cd --- /dev/null +++ b/src/transforms/string-transform.ts @@ -0,0 +1,238 @@ +import { + expectCh, + expectOneOf, + expectOnlyDecimalCharacters, + sliceTo, +} from '../parse-utils.js'; +import { Transform } from './transform.js'; +import { + PathScheme, + PathSchemeCodec, + decodePointer, + getDefaultPathScheme, + selectPathSchemeCodec, +} from '../path-pointers/index.js'; +import { + PropertyAdded, + PropertyChange, + PropertyChangeKinds, + PropertyRemoved, + PropertyEdited, + PropertyMoved, + Factory, +} from '../types.js'; + +const DEFAULT_AUDIT = false; +const DEFAULT_VALUE_TRANSFORM_TO = JSON.stringify.bind(null); +const DEFAULT_VALUE_TRANSFORM_FROM = JSON.parse.bind(null); +const DEFAULT_EDIT_VALUE_SEPARATOR = ' => '; + +export interface StringTransformOptions { + pathScheme?: PathScheme; + audit?: boolean; + valueTransformTo?: (v: unknown) => string; + valueTransformFrom?: (v: string) => unknown; + editValueSeparator?: string; +} + +export class StringTransform implements Transform { + public static DEFAULT_OPTIONS: StringTransformOptions = { + audit: DEFAULT_AUDIT, + valueTransformTo: DEFAULT_VALUE_TRANSFORM_TO, + valueTransformFrom: DEFAULT_VALUE_TRANSFORM_FROM, + editValueSeparator: DEFAULT_EDIT_VALUE_SEPARATOR, + }; + + public readonly pathScheme: PathScheme; + public readonly audit: boolean; + public readonly valueTransformTo: (v: unknown) => string; + public readonly valueTransformFrom: (v: string) => unknown; + public readonly editValueSeparator: string; + + private readonly _codec: PathSchemeCodec; + private readonly factory: Factory; + + constructor(factory: Factory, options?: StringTransformOptions) { + const { + pathScheme, + audit, + valueTransformTo, + valueTransformFrom, + editValueSeparator, + } = { + ...StringTransform.DEFAULT_OPTIONS, + ...(options || {}), + }; + this.factory = factory; + this.pathScheme = pathScheme || getDefaultPathScheme(); + this.audit = audit; + this.valueTransformTo = valueTransformTo; + this.valueTransformFrom = valueTransformFrom; + this.editValueSeparator = editValueSeparator; + this._codec = selectPathSchemeCodec(pathScheme); + } + + to(change: PropertyChange): string { + const { pointer, kind } = change; + const path = decodePointer(pointer); + const encodedPath = this._codec.encode(path); + if (kind === PropertyChangeKinds.add) + return this._transformAddedTo(encodedPath, change as PropertyAdded); + if (kind === PropertyChangeKinds.edit) + return this._transformEditedTo(encodedPath, change as PropertyEdited); + if (kind === PropertyChangeKinds.move) + return this._transformMovedTo(encodedPath, change as PropertyMoved); + if (kind === PropertyChangeKinds.remove) + return this._transformRemovedTo(encodedPath, change as PropertyRemoved); + throw new Error(`Unrecognized change kind: ${kind}.`); + } + + from(source: string): PropertyChange { + if (!source?.length) throw Error('source (string) is required'); + let cursor = 0; + const kind = expectOneOf(source, cursor++, [ + PropertyChangeKinds.add, + PropertyChangeKinds.edit, + PropertyChangeKinds.move, + PropertyChangeKinds.remove, + ]); + expectCh(source, cursor++, ' '); + const { found, at } = sliceTo(source, cursor, ' '); + const path = this._codec.decode(found); + cursor = at + 1; + switch (kind) { + case PropertyChangeKinds.add: { + const { found: comparand } = this._transformValueFrom(source, cursor); + return this.factory({ + kind, + path, + comparand, + } as PropertyChange); + } + case PropertyChangeKinds.edit: { + const { found: subject, length } = this._transformValueFrom( + source, + cursor, + ); + if (!length) throw new Error(`Expected encoded object at ${cursor}`); + cursor += length; + if (cursor < source.length) { + const { found: comparand, length } = this._transformValueFrom( + source, + cursor, + ); + if (!length) throw new Error(`Expected encoded object at ${cursor}`); + cursor += length; + return this.factory({ + kind, + path, + subject, + comparand, + } as PropertyChange); + } + return this.factory({ + kind, + path, + subject: undefined, + comparand: subject, + } as PropertyChange); + } + case PropertyChangeKinds.move: { + const { found, at } = sliceTo(source, cursor, ' '); + if (at === -1) { + throw new Error( + `Invalid numeric; expected decimal digits at ${cursor}.`, + ); + } + expectOnlyDecimalCharacters(found, cursor); + const origin = parseInt(found, 10); + const { found: subject, length } = this._transformValueFrom( + source, + cursor, + ); + if (!length) throw new Error(`Expected encoded object at ${cursor}`); + cursor += length; + if (cursor < source.length) { + const { found: comparand, length } = this._transformValueFrom( + source, + cursor, + ); + if (!length) throw new Error(`Expected encoded object at ${cursor}`); + cursor += length; + return this.factory({ + kind, + path, + subject, + comparand, + origin, + } as PropertyChange); + } + return this.factory({ + kind, + path, + subject: undefined, + comparand: subject, + origin, + } as PropertyChange); + } + case PropertyChangeKinds.remove: { + const { found: subject } = this._transformValueFrom(source, cursor); + return this.factory({ + kind, + path, + subject, + } as PropertyChange); + } + } + } + + _transformAddedTo(path: string, { comparand }): string { + return `${PropertyChangeKinds.add} ${path} ${this._transformValueTo( + comparand, + )}`; + } + _transformEditedTo(path: string, { subject, comparand }): string { + return this.audit + ? `${PropertyChangeKinds.edit} ${path} ${this._transformValueTo( + subject, + )}${this.editValueSeparator}${this._transformValueTo(comparand)}` + : `${PropertyChangeKinds.edit} ${path} ${this._transformValueTo( + comparand, + )}`; + } + _transformMovedTo(path: string, { subject, comparand, origin }): string { + return this.audit + ? `${PropertyChangeKinds.move} ${path} ${origin} ${this._transformValueTo( + subject, + )}${this.editValueSeparator}${this._transformValueTo(comparand)}` + : `${PropertyChangeKinds.move} ${path} ${origin} ${this._transformValueTo( + comparand, + )}`; + } + _transformRemovedTo(path: string, { subject }): string { + return this.audit + ? `${PropertyChangeKinds.remove} ${path} ${this._transformValueTo( + subject, + )}` + : `${PropertyChangeKinds.remove} ${path}`; + } + _transformValueTo(value: unknown): string { + const data = this.valueTransformTo(value); + return `${data.length} ${data}`; + } + _transformValueFrom( + str: string, + cursor: number, + ): { found: unknown; length: number } { + // JSON encoded data is length prefixed in the string. + const { found, at } = sliceTo(str, cursor, ' '); + if (at === -1) { + throw new Error(`Invalid numeric; expected decimal digits at ${cursor}.`); + } + expectOnlyDecimalCharacters(found, cursor); + const length = parseInt(found, 10); + const end = at + length + 1; + const data = this.valueTransformFrom(str.slice(at + 1, end)); + return { found: data, length }; + } +} diff --git a/src/transforms/transform.ts b/src/transforms/transform.ts new file mode 100644 index 0000000..778e134 --- /dev/null +++ b/src/transforms/transform.ts @@ -0,0 +1,6 @@ +import { PropertyChange } from '../types.js'; + +export interface Transform { + to(change: PropertyChange): T; + from(source: T): PropertyChange; +} diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..2b632dd --- /dev/null +++ b/src/types.ts @@ -0,0 +1,103 @@ +export type PropertyChangeKind = 'A' | 'E' | 'R' | 'M'; + +export const PropertyChangeKinds = Object.freeze({ + add: 'A', + edit: 'E', + remove: 'R', + move: 'M', +}); + +export type PathSegments = PropertyKey[]; + +export interface BasicPropertyChange { + readonly kind: PropertyChangeKind; + readonly path: PathSegments; + readonly pointer: string; + + /** + * Applies a captured change to the target object. + * @param target a target of the change + */ + apply( + target: unknown, + descend: boolean, + offset: number, + accessor: Accessor, + mutator: Mutator, + ): number; + + /** + * Reverts a captured change on the target object. + * @param target a target of the change + */ + revert( + target: unknown, + descend: boolean, + offset: number, + accessor: Accessor, + mutator: Mutator, + ): number; + + compact(audit: boolean): Record; +} + +export interface PropertyChangeWithComparand extends BasicPropertyChange { + readonly comparand: unknown; +} + +export interface PropertyChangeWithSubject extends BasicPropertyChange { + readonly subject: unknown; +} + +export interface PropertyAdded extends PropertyChangeWithComparand {} + +export type PropertyEdited = PropertyChangeWithComparand & + PropertyChangeWithSubject; + +export interface PropertyMoved extends PropertyEdited { + readonly origin: number; +} + +export interface PropertyRemoved extends PropertyChangeWithSubject { + readonly subject: unknown; +} + +export type PropertyChange = + | PropertyAdded + | PropertyEdited + | PropertyRemoved + | PropertyMoved; + +export type PropertyChanges = PropertyChange[]; + +export type Changes = PropertyChange | PropertyChanges; + +export type PropertyFilter = ( + path: PathSegments, + subject: unknown, + comparand: unknown, +) => boolean; + +export type Normalize = ( + path: PathSegments, + subject: unknown, + comparand: unknown, +) => [unknown, unknown]; + +export type Accessor = ( + path: PathSegments, + key: PropertyKey, + target: unknown, +) => unknown; + +export type Mutator = ( + path: PathSegments, + key: PropertyKey, + target: unknown, + value: unknown, +) => unknown; + +export type Factory = (change: PropertyChange) => PropertyChange; + +export type Serializer = (target: Changes) => string; +export type Deserializer = (string: string) => Changes; diff --git a/test/.eslintrc b/test/.eslintrc deleted file mode 100644 index 338df30..0000000 --- a/test/.eslintrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "plugins": [ - "mocha" - ], - "env": { - "node": true, - "mocha": true, - "browser": true - }, -} \ No newline at end of file diff --git a/test/common/utils.ts b/test/common/utils.ts new file mode 100644 index 0000000..6e1eee6 --- /dev/null +++ b/test/common/utils.ts @@ -0,0 +1,199 @@ +import { faker } from '@faker-js/faker'; +import { PropertyKey } from '../../src/deep-diff.js'; +import { hrtime } from 'process'; + +export const rand = (min: number, max: number): number => + Math.floor(Math.random() * (Math.floor(max) - Math.ceil(min) + 1)) + + Math.ceil(min); + +export interface Vehicle { + year: number; + manufacturer: string; + model: string; + type: string; + fuel: string; + color: string; + vin: string; + blurb: string; +} + +export const EnumerableVehicleProperties: PropertyKey[] = [ + 'year', + 'manufacturer', + 'model', + 'type', + 'fuel', + 'color', + 'vin', + 'blurb', +]; +export const AllVehicleProperties = EnumerableVehicleProperties.concat(['vrm']); + +export function makeVehicle(): Vehicle { + const vehicle = { + year: faker.date.past({ years: 112 }).getFullYear(), + manufacturer: faker.vehicle.manufacturer(), + model: faker.vehicle.model(), + type: faker.vehicle.type(), + fuel: faker.vehicle.fuel(), + color: faker.vehicle.color(), + vin: faker.vehicle.vin(), + blurb: faker.lorem.paragraph(), + }; + Object.defineProperty(vehicle, 'vrm', { + configurable: false, + enumerable: false, + writable: false, + value: faker.vehicle.vrm(), + }); + return vehicle; +} + +export function makeVehicles(count: number): Vehicle[] { + const vehicles: Vehicle[] = []; + for (let i = 0; i < count; ++i) { + vehicles.push(makeVehicle()); + } + return vehicles; +} + +export function changeVrm(it: Vehicle): Vehicle { + const vehicle: Vehicle = { + ...it, + }; + Object.defineProperty(vehicle, 'vrm', { + configurable: false, + enumerable: false, + writable: false, + value: faker.vehicle.vrm(), + }); + return vehicle; +} + +export function changeRandomVrm(it: Vehicle[]): Vehicle[] { + const item = rand(1, it.length) - 1; + it[item] = changeVrm(it[item]); + return it; +} + +export const $sym = Symbol('sym'); + +export function addSymbol(it: T): T { + it[$sym] = faker.string.uuid(); + return it; +} + +export function addSymbolToRandom(it: T[]): T[] { + const item = rand(1, it.length) - 1; + addSymbol(it[item]); + return it; +} + +export function copy( + it: T, + includeNonEnumerable = false, + includeSymbols = false, +): T { + const copy = includeNonEnumerable + ? copyWithNonEnumerable(it) + : { + ...it, + }; + if (includeSymbols) { + for (const sym of Object.getOwnPropertySymbols(it)) { + const descriptor = Object.getOwnPropertyDescriptor(it, sym); + Object.defineProperty(copy, sym, descriptor); + } + } + return copy; +} + +export function copyWithNonEnumerable(it: T): T { + const copy = {}; + for (const name of Object.getOwnPropertyNames(it)) { + const descriptor = Object.getOwnPropertyDescriptor(it, name); + Object.defineProperty(copy, name, descriptor); + } + return copy as T; +} + +export function moveRandomElement(arr: T[]): T[] { + if (arr.length < 2) return arr; + const n = rand(1, arr.length) - 1; + let m = 0; + do { + m = rand(1, arr.length) - 1; + } while (m === n); + [arr[n], arr[m]] = [arr[m], arr[n]]; + return arr; +} + +export type Gender = 'male' | 'female'; + +export interface Employee { + gender: Gender; + firstName: string; + lastName: string; + middleName?: string; + prefix?: string; + jobArea: string; + jobDescriptor: string; + jobTitle: string; + jobType: string; + boss?: Employee; + subordinates?: []; +} + +export const EnumerableEmployeeProperties: PropertyKey[] = [ + 'gender', + 'firstName', + 'lastName', + 'middleName', + 'prefix', + 'jobArea', + 'jobDescriptor', + 'jobTitle', + 'jobType', + 'boss', + 'subordinates', +]; +export const OptionalEmployeeProperties: PropertyKey[] = [ + 'middleName', + 'prefix', + 'boss', + 'subordinates', +]; + +export function makeWorker(): Employee { + const gender = faker.person.sex() as Gender; + const chance = rand(0, 100); + const hasMiddleName = chance % 3 === 0; + const hasPrefix = chance % 5 === 0; + return { + gender, + firstName: faker.person.firstName(gender), + lastName: faker.person.lastName(gender), + ...(hasMiddleName && { middleName: faker.person.middleName(gender) }), + ...(hasPrefix && { prefix: faker.person.prefix(gender) }), + jobArea: faker.person.jobArea(), + jobDescriptor: faker.person.jobDescriptor(), + jobTitle: faker.person.jobTitle(), + jobType: faker.person.jobType(), + }; +} + +const NS_PER_SEC = 1e9; +export function elapsed( + time: [number, number], + ops: number, + name = 'unnamed', +): void { + const diff = hrtime(time); + const elapsed_ns = diff[0] * NS_PER_SEC + diff[1]; + const elapsed_ms = elapsed_ns / 1000000; + console.log( + `${name}: ${Math.floor( + ops / elapsed_ms, + )}/ms; elapsed ${elapsed_ns}ns or ${elapsed_ms}ms`, + ); +} diff --git a/test/regression/issue-1.ts b/test/regression/issue-1.ts new file mode 100644 index 0000000..89b44bb --- /dev/null +++ b/test/regression/issue-1.ts @@ -0,0 +1,31 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyEditedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/1 + * https://github.com/flitbit/diff/issues/2 + */ +tap.test('issue-1, issue-2', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { + name: 'my object', + }; + + const comparand = null; + + const diff = new DeepDiff(); + + t.test('comparand is null', async (t) => { + const found = Array.from(diff.changes(subject, comparand)); + const expect = [new PropertyEditedRecord('#', subject, comparand)]; + t.matchOnly(found, expect, 'matches expected changes'); + }); + + t.test('subject is null', async (t) => { + const found = Array.from(diff.changes(comparand, subject)); + const expect = [new PropertyEditedRecord('#', comparand, subject)]; + t.matchOnly(found, expect, 'matches expected changes'); + }); +}); diff --git a/test/regression/issue-10.ts b/test/regression/issue-10.ts new file mode 100644 index 0000000..a0c40ba --- /dev/null +++ b/test/regression/issue-10.ts @@ -0,0 +1,67 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyEditedRecord } from '../../src/changes/property-edited-record.js'; + +/** + * https://github.com/flitbit/diff/issues/10 + * + * Apply change: Error when switching 2 items in array + */ +tap.test('issue-10', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { + id: 'Release', + phases: [ + { + id: 'Phase1', + tasks: [{ id: 'Task1' }, { id: 'Task2' }], + }, + { + id: 'Phase2', + tasks: [{ id: 'Task3' }], + }, + ], + }; + + const comparand = { + id: 'Release', + phases: [ + { + id: 'Phase2', + tasks: [{ id: 'Task3' }], + }, + { + id: 'Phase1', + tasks: [{ id: 'Task1' }, { id: 'Task2' }], + }, + ], + }; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + // const wanted = [ + // new PropertyEditedRecord( + // '#/phases/0', + // subject.phases[0], + // comparand.phases[0], + // ), + // new PropertyEditedRecord( + // '#/phases/1', + // subject.phases[1], + // comparand.phases[1], + // ), + // ]; + + // t.matchOnly(found, wanted, 'matches expected changes'); + + const original = JSON.parse(JSON.stringify(subject)); + + // The differences can be applied... + const changed = diff.apply(subject, found); + t.matchOnly(changed, comparand, 'applied changes produce matching'); + + // The differences can be reverted... + const reverted = diff.revert(subject, found); + t.matchOnly(reverted, original, 'reverted changes produce original'); +}); diff --git a/test/regression/issue-11.ts b/test/regression/issue-11.ts new file mode 100644 index 0000000..b67ca14 --- /dev/null +++ b/test/regression/issue-11.ts @@ -0,0 +1,53 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { randomBytes, randomInt } from 'crypto'; +import { PropertyEditedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/11 + * + * Filter/Ignore Keys? + */ +tap.test('issue-11', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { + obj: { + with: { + random: { + $key: 'to ignore', + num: randomInt(1000000), + }, + }, + }, + but: ['also', 'other', { data: randomBytes(10).toString('hex') }], + }; + + const comparand = { + obj: { + with: { + random: { + $key: randomBytes(16).toString('hex'), + num: randomInt(1000000), + }, + }, + }, + but: ['also', 'other', { data: randomBytes(28).toString('hex') }], + }; + + const diff = new DeepDiff({ ignoreProperties: ['$key'] }); + const found = Array.from(diff.changes(subject, comparand)); + const expect = [ + new PropertyEditedRecord( + '.obj.with.random.num', + subject.obj.with.random.num, + comparand.obj.with.random.num, + ), + new PropertyEditedRecord( + '.but.[2].data', + subject.but[2]['data'], + comparand.but[2]['data'], + ), + ]; + t.matchOnly(found, expect, 'matches expected changes'); +}); diff --git a/test/regression/issue-14.ts b/test/regression/issue-14.ts new file mode 100644 index 0000000..3ea5038 --- /dev/null +++ b/test/regression/issue-14.ts @@ -0,0 +1,52 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { DEFAULT_ACCESSOR, DEFAULT_MUTATOR } from '../../src/constants.js'; +import { PropertyEditedRecord } from '../../src/changes/property-edited-record.js'; + +/** + * https://github.com/flitbit/diff/issues/14 + * + * added function which reverts a single change item + */ +tap.test('issue-14', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { + a: 'a', + a1: [ + { + b1: 'b1', + b2: { c1: 'c1' }, + b3: 'b3', + }, + ], + }; + + const comparand = { + a: 'a', + a1: [ + { + b1: 'b1', + b3: null, + b2: null, + }, + ], + }; + + const diff = new DeepDiff(); + + const found = Array.from(diff.changes(subject, comparand)); + const changes = [ + new PropertyEditedRecord('#/a1/0/b3', subject.a1[0].b3, comparand.a1[0].b3), + new PropertyEditedRecord('#/a1/0/b2', subject.a1[0].b2, comparand.a1[0].b2), + ]; + t.matchOnly(found, changes, 'matches expected changes'); + + // Apply the changes to the subject... + diff.apply(subject, changes); + t.matchOnly(subject, comparand, 'subject and comparand match'); + + // Revert one change... + changes[0].revert(subject, true, 0, DEFAULT_ACCESSOR, DEFAULT_MUTATOR); + t.equal(subject.a1[0].b3, changes[0].subject, 'property was restored'); +}); diff --git a/test/regression/issue-15.ts b/test/regression/issue-15.ts new file mode 100644 index 0000000..abc451b --- /dev/null +++ b/test/regression/issue-15.ts @@ -0,0 +1,20 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; + +/** + * https://github.com/flitbit/diff/issues/15 + * + * shows no difference when you compare two NaN + */ +tap.test('issue-15', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = NaN; + const comparand = NaN; + + const diff = new DeepDiff(); + + const found = Array.from(diff.changes(subject, comparand)); + const expect = []; + t.matchOnly(found, expect, 'matches expected (empty) changes'); +}); diff --git a/test/regression/issue-17.ts b/test/regression/issue-17.ts new file mode 100644 index 0000000..314e0a4 --- /dev/null +++ b/test/regression/issue-17.ts @@ -0,0 +1,25 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyAddedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/17 + * + * A question about applying a diff. + */ +tap.test('issue-17', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = [1, 2, 3, 4]; + const comparand = [1, 2, 3, 4, 5, 6, 7]; + + const diff = new DeepDiff(); + + const found = Array.from(diff.changes(subject, comparand)); + const expect = [ + new PropertyAddedRecord('#/4', 5), + new PropertyAddedRecord('#/5', 6), + new PropertyAddedRecord('#/6', 7), + ]; + t.matchOnly(found, expect, 'matches expected changes'); +}); diff --git a/test/regression/issue-181.ts b/test/regression/issue-181.ts new file mode 100644 index 0000000..e0a5396 --- /dev/null +++ b/test/regression/issue-181.ts @@ -0,0 +1,48 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + PropertyAddedRecord, + PropertyEditedRecord, +} from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/181 + */ +tap.test('issue-181', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { + name: 'my object', + description: "it's an object!", + details: { + it: 'has', + an: 'array', + with: ['a', 'few', 'elements'], + }, + }; + + const comparand = { + name: 'updated object', + description: "it's an object!", + details: { + it: 'has', + an: 'array', + with: ['a', 'few', 'more', 'elements', { than: 'before' }], + }, + }; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + + const expect = [ + new PropertyEditedRecord('#/name', subject.name, comparand.name), + new PropertyEditedRecord( + '#/details/with/2', + subject.details.with[2], + comparand.details.with[2], + ), + new PropertyAddedRecord('#/details/with/3', comparand.details.with[3]), + new PropertyAddedRecord('#/details/with/4', comparand.details.with[4]), + ]; + t.matchOnly(found, expect, 'matches expected changes'); +}); diff --git a/test/regression/issue-19.ts b/test/regression/issue-19.ts new file mode 100644 index 0000000..efd9f52 --- /dev/null +++ b/test/regression/issue-19.ts @@ -0,0 +1,116 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + PropertyAddedRecord, + PropertyRemovedRecord, +} from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/19 + * + * Path param in prefilter function is not useful. + * + * In version 2.x, 'prefilter' has been renamed to 'filter' in + * constructor options. + */ +tap.test('issue-19', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const filterIndexFour = (path): boolean => + path.length && path[path.length - 1] === 4; + + const filterNamedProperty = (path): boolean => + path.length && path[path.length - 1] === 'two'; + + t.test('arrays of numbers, filtering an index', (t) => { + const subject = [1, 2, 3, 4]; + const comparand = [1, 2, 3, 4, 5, 6, 7]; + + const diff = new DeepDiff({ + filter: filterIndexFour, + }); + + const found = Array.from(diff.changes(subject, comparand)); + const expect = [ + new PropertyAddedRecord('#/5', 6), + new PropertyAddedRecord('#/6', 7), + ]; + t.matchOnly(found, expect, 'matches expected changes'); + t.end(); + }); + + t.test('arrays of objects, filtering an index', (t) => { + const subject = [{ one: 1 }, { two: 2 }, { three: 3 }, { four: 4 }]; + const comparand = [ + { one: 1 }, + { two: 2 }, + { three: 3 }, + { four: 4 }, + { five: 5 }, + { six: 6 }, + { seven: 7 }, + ]; + + const diff = new DeepDiff({ + filter: filterIndexFour, + }); + + const found = Array.from(diff.changes(subject, comparand)); + const expect = [ + new PropertyAddedRecord('#/5', comparand[5]), + new PropertyAddedRecord('#/6', comparand[6]), + ]; + t.matchOnly(found, expect, 'matches expected changes'); + t.end(); + }); + + t.test('nested arrays of objects, filtering an index', (t) => { + const subject = { + objects: [{ one: 1 }, { two: 2 }, { three: 3 }, { four: 4 }], + }; + const comparand = { + objects: [ + { one: 1 }, + { two: 2 }, + { three: 3 }, + { four: 4 }, + { five: 5 }, + { six: 6 }, + { seven: 7 }, + ], + }; + + const diff = new DeepDiff({ + filter: filterIndexFour, + }); + + const found = Array.from(diff.changes(subject, comparand)); + const expect = [ + new PropertyAddedRecord('#/objects/5', comparand.objects[5]), + new PropertyAddedRecord('#/objects/6', comparand.objects[6]), + ]; + t.matchOnly(found, expect, 'matches expected changes'); + t.end(); + }); + + t.test('nested arrays of objects, filtering a property by name', (t) => { + const subject = { + objects: [{ one: 1 }, { two: 2 }, { three: 3 }, { four: 4 }], + }; + const comparand = { + objects: [{ one: 1 }, { two: 'two' }, { three: 3 }], + }; + + const diff = new DeepDiff({ + filter: filterNamedProperty, + }); + + const found = Array.from(diff.changes(subject, comparand)); + const expect = [ + //new PropertyEditedRecord('#/objects/1/two', subject.objects[1].two, comparand.objects[1].two), + new PropertyRemovedRecord('#/objects/3', subject.objects[3]), + ]; + t.matchOnly(found, expect, 'matches expected changes'); + t.end(); + }); +}); diff --git a/test/regression/issue-23.ts b/test/regression/issue-23.ts new file mode 100644 index 0000000..b447e85 --- /dev/null +++ b/test/regression/issue-23.ts @@ -0,0 +1,49 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyRemovedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/23 + * + * Determine Shallow Change + */ +tap.test('issue-23', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = [ + { + name: 'Panda', + types: ['red', 'white'], + food: 'bamboo', + }, + { + name: 'Monkey', + types: ['brown', 'white'], + food: 'bananas', + }, + ]; + + const comparand = [ + { + name: 'Monkey', + types: ['brown', 'white'], + food: 'bananas', + }, + ]; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + const wanted = [new PropertyRemovedRecord('#/0', subject[0])]; + + t.matchOnly(found, wanted, 'matches expected changes'); + + const original = JSON.parse(JSON.stringify(subject)); + + // The differences can be applied... + const changed = diff.apply(subject, found); + t.matchOnly(changed, comparand, 'applied changes produce matching'); + + // The differences can be reverted... + const reverted = diff.revert(subject, found); + t.matchOnly(reverted, original, 'reverted changes produce original'); +}); diff --git a/test/regression/issue-3.ts b/test/regression/issue-3.ts new file mode 100644 index 0000000..e460701 --- /dev/null +++ b/test/regression/issue-3.ts @@ -0,0 +1,28 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; + +/** + * https://github.com/flitbit/diff/issues/3 + * + * Apply diff to ad different object + */ +tap.test('issue-3', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { noChange: 'same', levelOne: { levelTwo: 'value' } }; + const comparand = { + noChange: 'same', + levelOne: { levelTwo: 'another value' }, + }; + + const expect = { levelOne: { levelTwo: 'another value' } }; + + const diff = new DeepDiff(); + + const found = Array.from(diff.changes(subject, comparand)); + const other = {}; + + // Applies changes... + diff.apply(other, found); + t.matchOnly(other, expect, 'matches expected changes'); +}); diff --git a/test/regression/issue-32.ts b/test/regression/issue-32.ts new file mode 100644 index 0000000..7a27839 --- /dev/null +++ b/test/regression/issue-32.ts @@ -0,0 +1,31 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { ChangeRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/32 + * + * Diff returns undefined + * + */ +tap.test('issue-32', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { name: 'my object' }; + const comparand = subject; + + const diff = new DeepDiff(); + + // In version 2.x, the diff behavior is implemented as a generator function, + // so the result is never undefined... + const generator = diff.changes(subject, comparand); + + // ... and it can be iterated over + for (const change of generator) { + t.ok(change instanceof ChangeRecord); + } + + // ... and you can create an array from it... + const changes = Array.from(diff.changes(subject, comparand)); + t.matchOnly(changes, [], 'expected empty changes'); +}); diff --git a/test/regression/issue-33.ts b/test/regression/issue-33.ts new file mode 100644 index 0000000..378ecec --- /dev/null +++ b/test/regression/issue-33.ts @@ -0,0 +1,50 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { Normalize } from '../../src/types.js'; +import { v4, parse, stringify } from 'uuid'; +import { PropertyEditedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/33 + * + * Feature: Add support for normalizing values before diffing. + */ +tap.test('issue-33', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const _id = parse(v4()); + + const subject = { + _id, + submittedBy: 'wilbur_finkleworth', + }; + + const comparand = JSON.parse(JSON.stringify(subject)); + comparand._id = stringify(_id); + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + const wanted = [ + new PropertyEditedRecord('#/_id', subject._id, comparand._id), + ]; + t.matchOnly(found, wanted, 'reflects one difference'); + + type Uuid = string | Uint8Array; + const coerceUuidToString = (it: Uuid): string => + typeof it !== 'string' ? stringify(it) : it; + + // If the property is '_id', coerce it to a string + const normalize: Normalize = (path, subject, comparand) => { + return path.length && path[path.length - 1] === '_id' + ? [ + coerceUuidToString(subject as Uuid), + coerceUuidToString(comparand as Uuid), + ] + : [subject, comparand]; + }; + const normalizing = new DeepDiff({ normalize }); + + const none = Array.from(normalizing.changes(subject, comparand)); + + t.matchOnly(none, [], 'reflect no differences'); +}); diff --git a/test/regression/issue-35.ts b/test/regression/issue-35.ts new file mode 100644 index 0000000..0204854 --- /dev/null +++ b/test/regression/issue-35.ts @@ -0,0 +1,34 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyRemovedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/35 + * + * Taking diff of two array's not working + */ +tap.test('issue-35', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = ['a', 'a', 'a']; + const comparand = ['a']; + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + + const wanted = [ + new PropertyRemovedRecord('#/1', subject[1]), + new PropertyRemovedRecord('#/2', subject[2]), + ]; + t.matchOnly(found, wanted, 'found wanted differences'); + + const original = JSON.parse(JSON.stringify(subject)); + + // The differences can be applied... + // ... note the changes are applied to arrays in reverse order! + const changed = diff.apply(subject, found.reverse()); + t.matchOnly(changed, comparand, 'applied changes produce matching'); + + // The differences can be reverted... + const reverted = diff.revert(subject, found.reverse()); + t.matchOnly(reverted, original, 'reverted changes produce original'); +}); diff --git a/test/regression/issue-36.ts b/test/regression/issue-36.ts new file mode 100644 index 0000000..bef54d1 --- /dev/null +++ b/test/regression/issue-36.ts @@ -0,0 +1,55 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyEditedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/36 + * + * Stricter type checking among object types + */ +tap.test('issue-36', (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const diff = new DeepDiff(); + t.test('empty array subject, empty object comparand', (t) => { + const subject = []; + const comparand = {}; + + const found = Array.from(diff.changes(subject, comparand)); + const wanted = [new PropertyEditedRecord('#', subject, comparand)]; + t.matchOnly(found, wanted, 'found root change'); + t.end(); + }); + + t.test('array subject, object comparand', (t) => { + const subject = ['a', 'b', 'c']; + const comparand = { a: 1, b: 2, c: 3 }; + + const found = Array.from(diff.changes(subject, comparand)); + const wanted = [new PropertyEditedRecord('#', subject, comparand)]; + t.matchOnly(found, wanted, 'found root change'); + t.end(); + }); + + t.test('object subject, regex comparand', (t) => { + const subject = {}; + const comparand = /surely these are different!/gi; + + const found = Array.from(diff.changes(subject, comparand)); + const wanted = [new PropertyEditedRecord('#', subject, comparand)]; + t.matchOnly(found, wanted, 'found root change'); + t.end(); + }); + + t.test('object subject, array comparand', (t) => { + const subject = { a: 1 }; + const comparand = [1]; + + const found = Array.from(diff.changes(subject, comparand)); + const wanted = [new PropertyEditedRecord('#', subject, comparand)]; + t.matchOnly(found, wanted, 'found root change'); + t.end(); + }); + + t.end(); +}); diff --git a/test/regression/issue-37.ts b/test/regression/issue-37.ts new file mode 100644 index 0000000..ccfa350 --- /dev/null +++ b/test/regression/issue-37.ts @@ -0,0 +1,31 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyAddedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/37 + * + * Diffing array is very inefficient if deletion/addition occurs anywhere but + * at the end of the array + */ +tap.test('issue-37', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = ['h', 'a', 'p', 'p', 'y']; + const comparand = ['c', 'h', 'a', 'p', 'p', 'y']; + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + + const wanted = [new PropertyAddedRecord('#/0', comparand[0])]; + t.matchOnly(found, wanted, 'found wanted differences'); + + const original = JSON.parse(JSON.stringify(subject)); + + // The differences can be applied... + const changed = diff.apply(subject, found); + t.matchOnly(changed, comparand, 'applied changes produce match'); + + // The differences can be reverted... + const reverted = diff.revert(subject, found); + t.matchOnly(reverted, original, 'reverted changes produce original'); +}); diff --git a/test/regression/issue-48.ts b/test/regression/issue-48.ts new file mode 100644 index 0000000..62554d7 --- /dev/null +++ b/test/regression/issue-48.ts @@ -0,0 +1,63 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + PropertyAddedRecord, + PropertyEditedRecord, +} from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/48 + * + * Taking diff of two array's not working + */ +tap.test('issue-48', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { + name: 'my object', + description: "it's an object!", + details: { + it: 'has', + an: 'array', + with: ['a', 'few', 'elements'], + }, + }; + + const comparand = { + name: 'updated object', + description: "it's an object!", + details: { + it: 'has', + an: 'array', + with: ['a', 'few', 'more', 'elements', { than: 'before' }], + }, + }; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + + const wanted = [ + new PropertyEditedRecord('#/name', subject.name, comparand.name), + new PropertyEditedRecord( + '#/details/with/2', + subject.details.with[2], + comparand.details.with[2], + ), + new PropertyAddedRecord('#/details/with/3', comparand.details.with[3]), + new PropertyAddedRecord('#/details/with/4', comparand.details.with[4]), + ]; + t.matchOnly(found, wanted, 'found wanted differences'); + + const clone = (it): unknown => JSON.parse(JSON.stringify(it)); + + const original = clone(subject); + + // The differences can be applied... + // ... note the changes are applied to arrays in reverse order! + const applied = diff.apply(subject, found.reverse()); + t.matchOnly(applied, comparand, 'applied changes produce match'); + + // The differences can be reverted... + const reverted = diff.revert(subject, found.reverse()); + t.matchOnly(reverted, original, 'reverted changes produce original'); +}); diff --git a/test/regression/issue-49.ts b/test/regression/issue-49.ts new file mode 100644 index 0000000..4e46258 --- /dev/null +++ b/test/regression/issue-49.ts @@ -0,0 +1,23 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; + +/** + * https://github.com/flitbit/diff/issues/49 + * + * Object.create(null) causes error + */ +tap.test('issue-49', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = Object.create(null); + const comparand = {}; + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + + t.matchOnly(found, [], 'found no differences'); + + // Process again with the objects swapped... + + const again = Array.from(diff.changes(comparand, subject)); + t.matchOnly(again, [], 'found no differences'); +}); diff --git a/test/regression/issue-5.ts b/test/regression/issue-5.ts new file mode 100644 index 0000000..7f4136f --- /dev/null +++ b/test/regression/issue-5.ts @@ -0,0 +1,41 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyEditedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/5 + */ +tap.test('issue-5', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { + a: 'a', + a1: [ + { + b1: 'b1', + b2: { c1: 'c1' }, + b3: 'b3', + }, + ], + }; + + const comparand = { + a: 'a', + a1: [ + { + b1: 'b1', + b3: null, + b2: null, + }, + ], + }; + + const diff = new DeepDiff(); + + const found = Array.from(diff.changes(subject, comparand)); + const expect = [ + new PropertyEditedRecord('#/a1/0/b3', subject.a1[0].b3, comparand.a1[0].b3), + new PropertyEditedRecord('#/a1/0/b2', subject.a1[0].b2, comparand.a1[0].b2), + ]; + t.matchOnly(found, expect, 'matches expected changes'); +}); diff --git a/test/regression/issue-54.ts b/test/regression/issue-54.ts new file mode 100644 index 0000000..850a2fb --- /dev/null +++ b/test/regression/issue-54.ts @@ -0,0 +1,46 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { Accessor, Mutator } from '../../src/types.js'; +import { PropertyEditedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/54 + * + * Allow Custom Accessor and Mutator Functions + */ +tap.test('issue-54', async (t) => { + const subject = { one: 1, two: 2, three: 'three' }; + const comparand = { one: 1, two: 'two', three: 3 }; + + const map = new Map([ + ['one', 1], + ['two', 2], + ['three', 3], + ]); + + const accessor: Accessor = (_path, key, target) => { + const value = target[key]; + return typeof value === 'string' ? map.get(value) : value; + }; + const mutator: Mutator = (_path, key, target, value) => { + return typeof value === 'string' && map.get(value) + ? value + : (target[key] = value); + }; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly( + found, + [ + new PropertyEditedRecord('#/two', subject.two, comparand.two), + new PropertyEditedRecord('#/three', subject.three, comparand.three), + ], + 'found wanted differences', + ); + + const customized = new DeepDiff({ accessor, mutator }); + + const again = Array.from(customized.changes(comparand, subject)); + t.matchOnly(again, [], 'found no differences'); +}); diff --git a/test/regression/issue-59.ts b/test/regression/issue-59.ts new file mode 100644 index 0000000..1d275f6 --- /dev/null +++ b/test/regression/issue-59.ts @@ -0,0 +1,36 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + PropertyAddedRecord, + PropertyEditedRecord, + PropertyRemovedRecord, +} from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/59 + * + * stringify changed values of type "object" + */ +tap.test('issue-59', async (t) => { + const subject = { one: 1, two: 2, three: 'three' }; + const comparand = { two: 'two', three: 3, four: 'four' }; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly( + found, + [ + new PropertyRemovedRecord('#/one', subject.one), + new PropertyEditedRecord('#/two', subject.two, comparand.two), + new PropertyEditedRecord('#/three', subject.three, comparand.three), + new PropertyAddedRecord('#/four', comparand.four), + ], + 'found wanted differences', + ); + + const text = diff.stringify(found); + console.log(text); + const deserialized = diff.parse(text); + + t.matchOnly(deserialized, found, 'deserialized equivalent'); +}); diff --git a/test/regression/issue-62.ts b/test/regression/issue-62.ts new file mode 100644 index 0000000..8a3f5d1 --- /dev/null +++ b/test/regression/issue-62.ts @@ -0,0 +1,29 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; + +/** + * https://github.com/flitbit/diff/issues/62 + * + * deep-diff does not handle cycles + */ +tap.test('issue-62', async (t) => { + // https://github.com/flitbit/diff/issues/62#issuecomment-229549984 + // 3: appears to be fixed, probably in fixing #74. + + const a: Record = {}; + const b: Record = {}; + a.x = b; + b.x = b; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(a, b)); + const wanted = []; + + t.matchOnly(found, wanted, 'found no differences'); + + a.x = a; // Change to a + + const cycles = Array.from(diff.changes(a, b)); + + t.matchOnly(cycles, found, 'deserialized equivalent'); +}); diff --git a/test/regression/issue-69.ts b/test/regression/issue-69.ts new file mode 100644 index 0000000..6175ed3 --- /dev/null +++ b/test/regression/issue-69.ts @@ -0,0 +1,36 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyAddedRecord } from '../../src/changes/property-added-record.js'; + +/** + * https://github.com/flitbit/diff/issues/69 + * + * diff() does not detect properties added to functions + */ +tap.test('issue-69', async (t) => { + const subject = { + obj: {}, + func: function (): void {}, + }; + const comparand = { + obj: {}, + func: function (): void {}, + }; + comparand.obj['added'] = 'test'; + comparand.func['added'] = 'test'; + + // In version 2.x, functions are not processed... just like version 1.x + let diff = new DeepDiff(); + let found = Array.from(diff.changes(subject, comparand)); + let wanted = [new PropertyAddedRecord('#/obj/added', comparand.obj['added'])]; + t.matchOnly(found, wanted, 'found no differences'); + + // However, in v2.x+, you can tell deep-diff to include functions... + diff = new DeepDiff({ includeFunctions: true }); + found = Array.from(diff.changes(subject, comparand)); + wanted = [ + new PropertyAddedRecord('#/obj/added', comparand.obj['added']), + new PropertyAddedRecord('#/func/added', comparand.func['added']), + ]; + t.matchOnly(found, wanted, 'found no differences'); +}); diff --git a/test/regression/issue-7.ts b/test/regression/issue-7.ts new file mode 100644 index 0000000..d866c1f --- /dev/null +++ b/test/regression/issue-7.ts @@ -0,0 +1,21 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyEditedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/7 + */ +tap.test('issue-7', async (t) => { + // Rewritten to be valid Typescript and semantics of v2.x + + const subject = { key: new Date(555555555555) }; + const comparand = { key: new Date(777777777777) }; + + const diff = new DeepDiff(); + + const found = Array.from(diff.changes(subject, comparand)); + const expect = [ + new PropertyEditedRecord('#/key', subject.key, comparand.key), + ]; + t.matchOnly(found, expect, 'matches expected changes'); +}); diff --git a/test/regression/issue-70.ts b/test/regression/issue-70.ts new file mode 100644 index 0000000..38293aa --- /dev/null +++ b/test/regression/issue-70.ts @@ -0,0 +1,32 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyRemovedRecord } from '../../src/changes/property-removed-record.js'; + +/** + * https://github.com/flitbit/diff/issues/70 + * + * DeepDiff({ foo : undefined }, {}) reports no differences + */ +tap.test('issue-70', async (t) => { + t.test('original report', (t) => { + const subject = { foo: undefined }; + const comparand = {}; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + const wanted = [new PropertyRemovedRecord('#/foo', subject.foo)]; + t.matchOnly(found, wanted, 'found no differences'); + t.end(); + }); + t.test('later report', (t) => { + //https://github.com/flitbit/diff/issues/70#issuecomment-298158143 + const subject = { foo: undefined }; + const comparand = { foo: undefined }; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + const wanted = []; + t.matchOnly(found, wanted, 'found no differences'); + t.end(); + }); +}); diff --git a/test/regression/issue-71.ts b/test/regression/issue-71.ts new file mode 100644 index 0000000..86114b4 --- /dev/null +++ b/test/regression/issue-71.ts @@ -0,0 +1,32 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyEditedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/71 + * + * Non-function toString will cause crash + */ +tap.test('issue-71', async (t) => { + const subject = { left: 'yes', right: 'no' }; + const comparand = { + left: { + toString: true, + }, + right: 'no', + }; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly( + found, + [new PropertyEditedRecord('#/left', subject.left, comparand.left)], + 'found wanted differences', + ); + + const text = diff.stringify(found); + console.log(text); + const deserialized = diff.parse(text); + + t.matchOnly(deserialized, found, 'deserialized equivalent'); +}); diff --git a/test/regression/issue-72.ts b/test/regression/issue-72.ts new file mode 100644 index 0000000..447e2b3 --- /dev/null +++ b/test/regression/issue-72.ts @@ -0,0 +1,35 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { PropertyEditedRecord } from '../../src/changes/index.js'; + +/** + * https://github.com/flitbit/diff/issues/72 + * + * Array order? + */ +tap.test('issue-72', async (t) => { + const subject = { data: [1, 2, 3] }; + const comparand = { data: [4, 5, 1] }; + + const diff = new DeepDiff(); + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly( + found, + [ + new PropertyEditedRecord('#/data/0', subject.data[0], comparand.data[0]), + new PropertyEditedRecord('#/data/1', subject.data[1], comparand.data[1]), + new PropertyEditedRecord('#/data/2', subject.data[2], comparand.data[2]), + ], + 'found wanted differences', + ); + + const original = JSON.parse(JSON.stringify(subject)); + + // The differences can be applied... + const changed = diff.apply(subject, found); + t.matchOnly(changed, comparand, 'applied changes produce matching'); + + // The differences can be reverted... + const reverted = diff.revert(changed, found); + t.matchOnly(reverted, original, 'reverted changes produce original'); +}); diff --git a/test/src/calculate-property-set.ts b/test/src/calculate-property-set.ts new file mode 100644 index 0000000..47cccfc --- /dev/null +++ b/test/src/calculate-property-set.ts @@ -0,0 +1,193 @@ +import tap from 'tap'; +import { + PropertySet, + calculatePropertySet, +} from '../../src/calculate-property-set.js'; + +tap.test('fn calculatePropertySet()', async (t) => { + t.test('throws when subject unspecified', async (t) => { + t.throws(() => calculatePropertySet(undefined, undefined), { + message: "Cannot read properties of undefined (reading 'length')", + }); + }); + t.test('throws when comparand unspecified', async (t) => { + t.throws(() => calculatePropertySet([], undefined), { + message: "Cannot read properties of undefined (reading 'length')", + }); + }); + t.test('throws when comparand unspecified', async (t) => { + const found = calculatePropertySet([], []); + t.match(found, [], 'expected empty prop set'); + }); + + const twenty = [ + 'zero', + 'one', + 'two', + 'three', + 'four', + 'five', + 'six', + 'seven', + 'eight', + 'nine', + 'ten', + 'eleven', + 'twelve', + 'thirteen', + 'fourteen', + 'fifteen', + 'sixteen', + 'seventeen', + 'eighteen', + 'nineteen', + 'twenty', + 'twenty-one', + 'twenty-two', + 'twenty-three', + 'twenty-four', + 'twenty-five', + 'twenty-six', + 'twenty-seven', + 'twenty-eight', + ]; + + let zeroToTwentyEight = []; + const lastCase = twenty.length - 1; + for (let i = 0; i < twenty.length; ++i) { + const subset = twenty.slice(0, lastCase - i); + zeroToTwentyEight.push([ + twenty[subset.length] || 'zero', + subset, + subset, + subset.map((it, j) => [it, j, j]), + ]); + } + zeroToTwentyEight = zeroToTwentyEight.reverse(); + + const tests: [string, PropertyKey[], PropertyKey[], PropertySet][] = + zeroToTwentyEight.concat([ + [ + 'right has more (end)', + ['one', 'two', 'three'], + ['one', 'two', 'three', 'four'], + [ + ['one', 0, 0], + ['two', 1, 1], + ['three', 2, 2], + ['four', undefined, 3], + ], + ], + [ + 'right has more (middle)', + ['one', 'three'], + ['one', 'two', 'three'], + [ + ['one', 0, 0], + ['two', undefined, 1], + ['three', 1, 2], + ], + ], + [ + 'right has more (front)', + ['two', 'three', 'four'], + ['one', 'two', 'three', 'four'], + [ + ['one', undefined, 0], + ['two', 0, 1], + ['three', 1, 2], + ['four', 2, 3], + ], + ], + [ + 'left has more (end)', + ['one', 'two', 'three', 'four'], + ['one', 'two', 'three'], + [ + ['one', 0, 0], + ['two', 1, 1], + ['three', 2, 2], + ['four', 3, undefined], + ], + ], + [ + 'left has more (middle)', + ['one', 'two', 'three', 'four'], + ['one', 'two', 'four'], + [ + ['one', 0, 0], + ['two', 1, 1], + ['three', 2, undefined], + ['four', 3, 2], + ], + ], + [ + 'left has more (front)', + ['one', 'two', 'three', 'four'], + ['two', 'three', 'four'], + [ + ['one', 0, undefined], + ['two', 1, 0], + ['three', 2, 1], + ['four', 3, 2], + ], + ], + [ + 'no overlap', + ['one', 'two', 'three'], + ['four', 'five', 'six'], + [ + ['one', 0, undefined], + ['four', undefined, 0], + ['two', 1, undefined], + ['five', undefined, 1], + ['three', 2, undefined], + ['six', undefined, 2], + ], + ], + [ + 'nearly disjoint', + ['one', 'two', 'five', 'nine'], + ['three', 'four', 'five', 'six'], + [ + ['one', 0, undefined], + ['three', undefined, 0], + ['two', 1, undefined], + ['four', undefined, 1], + ['five', 2, 2], + ['nine', 3, undefined], + ['six', undefined, 3], + ], + ], + [ + 'disjoint middle', + ['one', 'two', 'five', 'six'], + ['three', 'four'], + [ + ['one', 0, undefined], + ['three', undefined, 0], + ['two', 1, undefined], + ['four', undefined, 1], + ['five', 2, undefined], + ['six', 3, undefined], + ], + ], + [ + 'removed middle', + ['one', 'two', 'three'], + ['one', 'three'], + [ + ['one', 0, 0], + ['two', 1, undefined], + ['three', 2, 1], + ], + ], + ]); + + for (const [what, left, right, wanted] of tests) { + t.test(what, async (t) => { + const found = calculatePropertySet(left, right); + t.matchOnly(found, wanted, 'expected'); + }); + } +}); diff --git a/test/src/deep-diff(defaults).ts b/test/src/deep-diff(defaults).ts new file mode 100644 index 0000000..a017b5e --- /dev/null +++ b/test/src/deep-diff(defaults).ts @@ -0,0 +1,65 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + addSymbol, + addSymbolToRandom, + copy, + makeVehicle, + makeVehicles, + rand, +} from '../common/utils.js'; +import { faker } from '@faker-js/faker'; + +tap.test('DeepDiff', async (t) => { + t.test('defaults', async (t) => { + const includeNonEnumerable = false; + const includeSymbols = false; + const it = new DeepDiff(); + t.test('.hashString()', async (t) => { + t.test('is pure', async (t) => { + for (let i = 0; i < 100; ++i) { + const value = faker.lorem.paragraph(); + const a = it.hashString(value); + const b = it.hashString(value); + t.equal(b, a, 'produces same hash'); + } + }); + }); + + t.test('.hashObject()', async (t) => { + for (let i = 0; i < 100; ++i) { + const vehicle = makeVehicle(); + const other = addSymbol( + copy(vehicle, includeNonEnumerable, includeSymbols), + ); + const wanted = it.hashObject(vehicle); + const found = it.hashObject(other); + t.equal(found, wanted, 'produces same hash'); + } + }); + + t.test('.hashArray()', async (t) => { + for (let i = 0; i < 100; ++i) { + const arr = addSymbolToRandom(makeVehicles(rand(1, 100))); + const other = arr.map((v) => + copy(v, includeNonEnumerable, includeSymbols), + ); + const wanted = it.hashArray(arr); + const found = it.hashArray(other); + t.equal(found, wanted, 'produces same hash'); + } + }); + + t.test('.hashUnknown()', async (t) => { + for (let i = 0; i < 100; ++i) { + const arr = addSymbolToRandom(makeVehicles(rand(1, 100))); + const other = arr.map((v) => + copy(v, includeNonEnumerable, includeSymbols), + ); + const wanted = it.hashUnknown(arr); + const found = it.hashUnknown(other); + t.equal(found, wanted, 'produces same hash'); + } + }); + }); +}); diff --git a/test/src/deep-diff(symbols).ts b/test/src/deep-diff(symbols).ts new file mode 100644 index 0000000..e63e9c7 --- /dev/null +++ b/test/src/deep-diff(symbols).ts @@ -0,0 +1,106 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + addSymbol, + addSymbolToRandom, + copy, + makeVehicle, + makeVehicles, + rand, +} from '../common/utils.js'; +import { faker } from '@faker-js/faker'; + +tap.test('DeepDiff', async (t) => { + t.test('symbols', async (t) => { + const includeNonEnumerable = false; + const includeSymbols = true; + const it = new DeepDiff({ includeNonEnumerable, includeSymbols }); + t.test('.hashString()', async (t) => { + t.test('is pure', async (t) => { + for (let i = 0; i < 100; ++i) { + const value = faker.lorem.paragraph(); + const a = it.hashString(value); + const b = it.hashString(value); + t.equal(b, a, 'produces same hash'); + } + }); + }); + + t.test('.hashObject()', async (t) => { + t.test('recognizes equals', async (t) => { + for (let i = 0; i < 100; ++i) { + const vehicle = makeVehicle(); + const other = copy(vehicle, includeNonEnumerable, includeSymbols); + const wanted = it.hashObject(vehicle); + const found = it.hashObject(other); + t.equal(found, wanted, 'produces same hash'); + } + }); + t.test('recognizes unequals', async (t) => { + for (let i = 0; i < 100; ++i) { + const vehicle = makeVehicle(); + const other = addSymbol( + copy(vehicle, includeNonEnumerable, includeSymbols), + ); + const wanted = it.hashObject(vehicle); + const found = it.hashObject(other); + t.not(found, wanted, 'produces different hash'); + } + }); + t.test('throws on cycles', async (t) => { + const sym = Symbol(13); + const vehicle = makeVehicle(); + vehicle[sym] = vehicle; + t.throws(() => it.hashObject(vehicle), { + message: 'Unsupported cycle encountered in the graph', + }); + }); + }); + + t.test('.hashArray()', async (t) => { + t.test('recognizes equals', async (t) => { + for (let i = 0; i < 100; ++i) { + const arr = addSymbolToRandom(makeVehicles(rand(1, 100))); + const other = arr.map((v) => + copy(v, includeNonEnumerable, includeSymbols), + ); + t.matchOnly(arr, other); + const wanted = it.hashArray(arr); + const found = it.hashArray(other); + t.equal(found, wanted, 'produces same hash'); + } + }); + t.test('throws on cycles', async (t) => { + const arr = makeVehicles(rand(1, 100)); + (arr as unknown[]).push(arr); + t.throws(() => it.hashArray(arr), { + message: 'Unsupported cycle encountered in the graph', + }); + }); + }); + t.test('.hashUnknown()', async (t) => { + t.test('recognizes equals', async (t) => { + for (let i = 0; i < 100; ++i) { + const arr = addSymbolToRandom(makeVehicles(rand(1, 100))); + const other = arr.map((v) => + copy(v, includeNonEnumerable, includeSymbols), + ); + const wanted = it.hashUnknown(arr); + const found = it.hashUnknown(other); + t.equal(found, wanted, 'produces same hash'); + } + }); + t.test('recognizes unequals', async (t) => { + for (let i = 0; i < 100; ++i) { + const arr = addSymbolToRandom(makeVehicles(rand(1, 100))); + const other = addSymbolToRandom( + arr.map((v) => copy(v, includeNonEnumerable, includeSymbols)), + ); + const wanted = it.hashUnknown(arr); + const found = it.hashUnknown(other); + t.not(found, wanted, 'produces different hash'); + } + }); + }); + }); +}); diff --git a/test/src/deep-diff-array.ts b/test/src/deep-diff-array.ts new file mode 100644 index 0000000..5931743 --- /dev/null +++ b/test/src/deep-diff-array.ts @@ -0,0 +1,179 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + PropertyEditedRecord, + PropertyAddedRecord, + PropertyRemovedRecord, +} from '../../src/changes/index.js'; +import { PropertyChanges } from '../../src/types.js'; + +tap.test('DeepDiff', async (t) => { + const diff = new DeepDiff(); + t.test('array subject', async (t) => { + /** + * When subject is a array, and comparand is a array, + * it should compare strictly equal, or strictly unequal, + * but, either side can be monkey patched, so dates are + * checked for ill-advised (monkey-patched) structure. + */ + t.test('array comparand', async (t) => { + const subject = []; + t.test('equal', async (t) => { + const comparand = []; + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly(found, [], 'empty results'); + }); + t.test('unequal', async (t) => { + const comparand = [1]; + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly(found, [new PropertyAddedRecord([0], 1)], 'edit result'); + }); + t.test('equal (patched)', async (t) => { + const subject = [1]; + const comparand = [1]; + // Ill-advised, but possible! + comparand['foo'] = 'bar'; + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly( + found, + [new PropertyAddedRecord(['foo'], 'bar')], + 'new record result', + ); + }); + const cases: [string, unknown[], unknown[], PropertyChanges][] = [ + ['item added (only)', [], [1], [new PropertyAddedRecord([0], 1)]], + ['item deleted (only)', [1], [], [new PropertyRemovedRecord([0], 1)]], + ['item edited (only)', [2], [1], [new PropertyEditedRecord([0], 2, 1)]], + [ + 'item deleted (middle)', + [0, 1, 2, 3, 4, 5, 6, 7], + [0, 1, 2, 3, 5, 6, 7], + [new PropertyRemovedRecord([4], 4)], + ], + [ + 'item added (front)', + [1, 2, 3, 4, 5, 6, 7], + [0, 1, 2, 3, 4, 5, 6, 7], + [new PropertyAddedRecord([0], 0)], + ], + [ + 'item added (middle)', + [0, 1, 2, 3, 5, 6, 7], + [0, 1, 2, 3, 4, 5, 6, 7], + [new PropertyAddedRecord([4], 4)], + ], + [ + 'items added (front, middle)', + [1, 2, 3, 5, 6, 7], + [0, 1, 2, 3, 4, 5, 6, 7], + [new PropertyAddedRecord([0], 0), new PropertyAddedRecord([4], 4)], + ], + [ + 'item edited (middle)', + [0, 1, 2, 3, 4, 5, 6, 7], + [0, 1, 2, 3, 8, 5, 6, 7], + [new PropertyEditedRecord([4], 4, 8)], + ], + [ + 'item deleted (end)', + [0, 1, 2, 3, 4, 5, 6, 7], + [0, 1, 2, 3, 4, 5, 6], + [new PropertyRemovedRecord([7], 7)], + ], + [ + 'item added (end)', + [0, 1, 2, 3, 4, 5, 6], + [0, 1, 2, 3, 4, 5, 6, 7], + [new PropertyAddedRecord([7], 7)], + ], + [ + 'item edited (end)', + [0, 1, 2, 3, 4, 5, 6, 7], + [0, 1, 2, 3, 4, 5, 6, 8], + [new PropertyEditedRecord([7], 7, 8)], + ], + [ + 'added below', + [{ one: 1, two: 2 }], + [{ one: 1, two: 2, three: 3 }], + [new PropertyAddedRecord([0, 'three'], 3)], + ], + [ + 'edited below', + [{ one: 1, two: 3 }], + [{ one: 1, two: 2 }], + [new PropertyEditedRecord([0, 'two'], 3, 2)], + ], + [ + 'deleted below', + [{ one: 1, two: 2, three: 3 }], + [{ one: 1, two: 2 }], + [new PropertyRemovedRecord([0, 'three'], 3)], + ], + [ + 'added center and end', + ['a', 'few', 'elements'], + ['a', 'few', 'more', 'other', 'elements', 'than', 'before'], + [ + new PropertyEditedRecord('#/2', 'elements', 'more'), + new PropertyAddedRecord('#/3', 'other'), + new PropertyAddedRecord('#/4', 'elements'), + new PropertyAddedRecord('#/5', 'than'), + new PropertyAddedRecord('#/6', 'before'), + ], + ], + ]; + for (const [name, subject, comparand, expect] of cases) { + t.test(`comparand is ${name}`, async (t) => { + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly(found, expect, 'expected changes'); + + const original = JSON.parse(JSON.stringify(subject)); + // The differences can be applied... + const changed = diff.apply(subject, found); + t.matchOnly(changed, comparand, 'applied changes produce match'); + // The differences can be reverted... + const reverted = diff.revert(subject, found); + t.matchOnly(reverted, original, 'reverted changes produce original'); + }); + } + }); + /** + * When subject is array, and comparand is non-array, then all + * structure comparisons are off. It should just be an edit. + * */ + t.test('non-date comparand', async (t) => { + const subject = new Date(); + const fn = (): void => {}; + const regexp = /foo/; + const sym = Symbol('foo'); + const cases: [string, unknown, PropertyChanges][] = [ + ['an array', [], [new PropertyEditedRecord([], subject, [])]], + ['a bigint', 1n, [new PropertyEditedRecord([], subject, 1n)]], + ['a function', fn, [new PropertyEditedRecord([], subject, fn)]], + ['a Math', Math, [new PropertyEditedRecord([], subject, Math)]], + ['null', null, [new PropertyEditedRecord([], subject, null)]], + ['number', 1, [new PropertyEditedRecord([], subject, 1)]], + ['object', {}, [new PropertyEditedRecord([], subject, {})]], + ['regexp', regexp, [new PropertyEditedRecord([], subject, regexp)]], + ['an empty string', '', [new PropertyEditedRecord([], subject, '')]], + ['string', 'foo', [new PropertyEditedRecord([], subject, 'foo')]], + ['symbol', sym, [new PropertyEditedRecord([], subject, sym)]], + ]; + for (const [name, comparand, expect] of cases) { + t.test(`comparand is ${name}`, async (t) => { + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly(found, expect, 'no changes'); + }); + } + t.test(`comparand is undefined`, async (t) => { + const found = Array.from(diff.changes(subject, undefined)); + t.matchOnly( + found, + [new PropertyRemovedRecord([], subject)], + 'a delete', + ); + }); + }); + }); +}); diff --git a/test/src/deep-diff-date.ts b/test/src/deep-diff-date.ts new file mode 100644 index 0000000..f0fbbdd --- /dev/null +++ b/test/src/deep-diff-date.ts @@ -0,0 +1,86 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + PropertyRemovedRecord, + PropertyEditedRecord, + PropertyAddedRecord, +} from '../../src/changes/index.js'; +import { PropertyChanges } from '../../src/types.js'; + +tap.test('DeepDiff', async (t) => { + const diff = new DeepDiff(); + t.test('date subject', async (t) => { + /** + * When subject is a date, and comparand is a date, + * it should compare strictly equal, or strictly unequal, + * but, either side can be monkey patched, so dates are + * checked for ill-advised (monkey-patched) structure. + */ + t.test('date comparand', async (t) => { + t.test('equal', async (t) => { + const subject = new Date(); + const comparand = new Date(subject.valueOf()); + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly(found, [], 'empty results'); + }); + t.test('unequal', async (t) => { + const subject = new Date(); + const comparand = new Date(subject.valueOf() + 1); + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly( + found, + [new PropertyEditedRecord([], subject, comparand)], + 'edit result', + ); + }); + t.test('equal (patched)', async (t) => { + const subject = new Date(); + const comparand = new Date(subject.valueOf()); + // Ill-advised, but possible! + comparand['foo'] = 'bar'; + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly( + found, + [new PropertyAddedRecord(['foo'], 'bar')], + 'new record result', + ); + }); + }); + /** + * When subject is date, and comparand is non-date, all + * structure comparisons are off. It should just be an edit. + */ + t.test('non-date comparand', async (t) => { + const subject = new Date(); + const fn = (): void => {}; + const regexp = /foo/; + const sym = Symbol('foo'); + const cases: [string, unknown, PropertyChanges][] = [ + ['a bigint', 1n, [new PropertyEditedRecord([], subject, 1n)]], + ['a function', fn, [new PropertyEditedRecord([], subject, fn)]], + ['a Math', Math, [new PropertyEditedRecord([], subject, Math)]], + ['null', null, [new PropertyEditedRecord([], subject, null)]], + ['number', 1, [new PropertyEditedRecord([], subject, 1)]], + ['object', {}, [new PropertyEditedRecord([], subject, {})]], + ['regexp', regexp, [new PropertyEditedRecord([], subject, regexp)]], + ['an empty string', '', [new PropertyEditedRecord([], subject, '')]], + ['string', 'foo', [new PropertyEditedRecord([], subject, 'foo')]], + ['symbol', sym, [new PropertyEditedRecord([], subject, sym)]], + ]; + for (const [name, comparand, expect] of cases) { + t.test(`comparand is ${name}`, async (t) => { + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly(found, expect, 'no changes'); + }); + } + t.test(`comparand is undefined`, async (t) => { + const found = Array.from(diff.changes(subject, undefined)); + t.matchOnly( + found, + [new PropertyRemovedRecord([], subject)], + 'a delete', + ); + }); + }); + }); +}); diff --git a/test/src/deep-diff-number.ts b/test/src/deep-diff-number.ts new file mode 100644 index 0000000..638316d --- /dev/null +++ b/test/src/deep-diff-number.ts @@ -0,0 +1,111 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + PropertyRemovedRecord, + PropertyEditedRecord, +} from '../../src/changes/index.js'; +import { PropertyChanges } from '../../src/types.js'; + +tap.test('DeepDiff', async (t) => { + const diff = new DeepDiff(); + t.test('NaN subject', async (t) => { + const subject = NaN; + const cases: [string, unknown, PropertyChanges][] = [ + ['NaN', NaN, []], + [ + 'upper bound', + Number.MAX_VALUE, + [new PropertyEditedRecord([], subject, Number.MAX_VALUE)], + ], + [ + 'positive infinity', + Number.POSITIVE_INFINITY, + [new PropertyEditedRecord([], subject, Number.POSITIVE_INFINITY)], + ], + [ + 'negative infinity', + Number.NEGATIVE_INFINITY, + [new PropertyEditedRecord([], subject, Number.NEGATIVE_INFINITY)], + ], + ]; + for (const [name, comparand, expect] of cases) { + t.test(`comparand is ${name}`, async (t) => { + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly(found, expect, 'no changes'); + }); + } + t.test(`comparand is undefined`, async (t) => { + const found = Array.from(diff.changes(subject, undefined)); + t.matchOnly(found, [new PropertyRemovedRecord([], subject)], 'a delete'); + }); + }); + + t.test('number comparand', async (t) => { + const subject = 1; + const cases: [string, unknown, PropertyChanges][] = [ + [ + 'plus one', + subject + 1, + [new PropertyEditedRecord([], subject, subject + 1)], + ], + ['minus one', 1n, [new PropertyEditedRecord([], subject, 1n)]], + [ + 'lower bound', + Number.MIN_VALUE, + [new PropertyEditedRecord([], subject, Number.MIN_VALUE)], + ], + [ + 'upper bound', + Number.MAX_VALUE, + [new PropertyEditedRecord([], subject, Number.MAX_VALUE)], + ], + ['NaN', NaN, [new PropertyEditedRecord([], subject, NaN)]], + [ + 'positive infinity', + Number.POSITIVE_INFINITY, + [new PropertyEditedRecord([], subject, Number.POSITIVE_INFINITY)], + ], + [ + 'negative infinity', + Number.NEGATIVE_INFINITY, + [new PropertyEditedRecord([], subject, Number.NEGATIVE_INFINITY)], + ], + ]; + for (const [name, comparand, expect] of cases) { + t.test(`comparand is ${name}`, async (t) => { + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly(found, expect, 'no changes'); + }); + } + }); + + t.test('non-date comparand', async (t) => { + const subject = 1; + const date = new Date(); + const fn = (): void => {}; + const regexp = /foo/; + const sym = Symbol('foo'); + const cases: [string, unknown, PropertyChanges][] = [ + ['an date', date, [new PropertyEditedRecord([], subject, date)]], + ['a bigint', 1n, [new PropertyEditedRecord([], subject, 1n)]], + ['a function', fn, [new PropertyEditedRecord([], subject, fn)]], + ['a Math', Math, [new PropertyEditedRecord([], subject, Math)]], + ['null', null, [new PropertyEditedRecord([], subject, null)]], + ['object', {}, [new PropertyEditedRecord([], subject, {})]], + ['regexp', regexp, [new PropertyEditedRecord([], subject, regexp)]], + ['an empty string', '', [new PropertyEditedRecord([], subject, '')]], + ['string', 'foo', [new PropertyEditedRecord([], subject, 'foo')]], + ['symbol', sym, [new PropertyEditedRecord([], subject, sym)]], + ]; + for (const [name, comparand, expect] of cases) { + t.test(`comparand is ${name}`, async (t) => { + const found = Array.from(diff.changes(subject, comparand)); + t.matchOnly(found, expect, 'no changes'); + }); + } + t.test(`comparand is undefined`, async (t) => { + const found = Array.from(diff.changes(subject, undefined)); + t.matchOnly(found, [new PropertyRemovedRecord([], subject)], 'a delete'); + }); + }); +}); diff --git a/test/src/deep-diff.changes.ts b/test/src/deep-diff.changes.ts new file mode 100644 index 0000000..bac8ebd --- /dev/null +++ b/test/src/deep-diff.changes.ts @@ -0,0 +1,124 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + PropertyEditedRecord, + PropertyAddedRecord, + PropertyRemovedRecord, +} from '../../src/changes/index.js'; + +tap.test('DeepDiff', async (t) => { + t.test('.changes()', async (t) => { + const diff = new DeepDiff(); + const sym = Symbol('sym'); + const obj = []; + const now = new Date(); + const fn = (): void => {}; + const tests = [ + ['object', obj, obj], + ['empty string', '', ''], + ['string', 'hi', 'hi'], + ['symbol', sym, sym], + ['number', 1, 1], + ['bigint', 1n, 1n], + ['undefined', undefined, undefined], + ['math', Math, Math], + ['date', new RegExp(''), new RegExp('')], + ['regexp', now, now], + ['function', fn, fn], + ]; + + for (const [type, left, right] of tests) { + t.test(`recognizes two equal ${String(type)}s as equal`, async (t) => { + const changes = Array.from(diff.changes(left, right)); + t.equal(changes.length, 0, 'no changes'); + }); + } + t.test(`recognizes deletion (objects 1 level)`, async (t) => { + const left = { + one: 1, + two: 2, + three: 3, + }; + const right = { + one: 1, + three: 3, + }; + const changes = Array.from(diff.changes(left, right)); + t.equal(changes.length, 1, 'one change'); + t.matchOnly( + changes, + [new PropertyRemovedRecord(['two'], left.two)], + 'deleted', + ); + }); + t.test(`recognizes deeper changes`, async (t) => { + const tests: [string, object, object, object[]][] = [ + [ + 'add below level 1', + { + one: 1, + two: 2, + three: 3, + four: { + five: 4, + }, + }, + { + one: 1, + two: 2, + three: 3, + four: { five: 4, six: 7 }, + }, + [new PropertyAddedRecord(['four', 'six'], 7)], + ], + [ + 'delete and edit, 2-levels', + { + one: 1, + two: 2, + three: 3, + four: { + five: 4, + }, + }, + { + one: 1, + three: 3, + four: { five: 6 }, + }, + [ + new PropertyRemovedRecord(['two'], 2), + new PropertyEditedRecord(['four', 'five'], 4, 6), + ], + ], + [ + 'small union', + { + one: 1, + two: 2, + three: 3n, + }, + { + three: 3, + four: 4, + five: { six: 6, seven: 'seven' }, + }, + [ + new PropertyRemovedRecord(['one'], 1), + new PropertyEditedRecord(['three'], 3n, 3), + new PropertyRemovedRecord(['two'], 2), + new PropertyAddedRecord(['four'], 4), + new PropertyAddedRecord(['five'], { six: 6, seven: 'seven' }), + ], + ], + ]; + for (const [what, left, right, wanted] of tests) { + t.test(what, async (t) => { + const found = Array.from(diff.changes(left, right)); + t.equal(found.length, wanted.length, 'equal changes'); + t.matchOnly(found, wanted, 'observes expected changes'); + }); + } + }); + }); +}); diff --git a/test/src/deep-diff.constructor.ts b/test/src/deep-diff.constructor.ts new file mode 100644 index 0000000..7b59861 --- /dev/null +++ b/test/src/deep-diff.constructor.ts @@ -0,0 +1,48 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; + +tap.test('DeepDiff', async (t) => { + t.test('.constructor', async (t) => { + t.test('succeeds with no arguments', async (t) => { + const it = new DeepDiff(); + t.equal( + it.includeNonEnumerable, + DeepDiff.DEFAULT_OPTIONS.includeNonEnumerable, + '.includesNonPublic is default', + ); + t.equal( + it.includeSymbols, + DeepDiff.DEFAULT_OPTIONS.includeSymbols, + '.includesSymbols is default', + ); + }); + t.test('conveys includeNonEnumerable when specified (true)', async (t) => { + const includeNonEnumerable = true; + const it = new DeepDiff({ includeNonEnumerable }); + t.equal( + it.includeNonEnumerable, + includeNonEnumerable, + '.includeNonEnumerable was ', + ); + }); + t.test('conveys includeNonEnumerable when specified (false)', async (t) => { + const includeNonEnumerable = false; + const it = new DeepDiff({ includeNonEnumerable }); + t.equal( + it.includeNonEnumerable, + includeNonEnumerable, + '.includeNonEnumerable was set', + ); + }); + t.test('conveys includeSymbols when specified (true)', async (t) => { + const includeSymbols = true; + const it = new DeepDiff({ includeSymbols }); + t.equal(it.includeSymbols, includeSymbols, '.includeSymbols was set'); + }); + t.test('conveys includeSymbols when specified (false)', async (t) => { + const includeSymbols = false; + const it = new DeepDiff({ includeSymbols }); + t.equal(it.includeSymbols, includeSymbols, '.includeSymbols was set'); + }); + }); +}); diff --git a/test/src/deep-diff.list-comparable-members.ts b/test/src/deep-diff.list-comparable-members.ts new file mode 100644 index 0000000..33b36b6 --- /dev/null +++ b/test/src/deep-diff.list-comparable-members.ts @@ -0,0 +1,86 @@ +import tap from 'tap'; +import { DeepDiff } from '../../src/deep-diff.js'; +import { + $sym, + AllVehicleProperties, + EnumerableVehicleProperties, + addSymbol, + makeVehicle, +} from '../common/utils.js'; + +tap.test('DeepDiff', async (t) => { + t.test('.listComparableMembers()', async (t) => { + const emptyList = []; + // [ + // description: string, + // value: any, + // expected: PropertyKey[] + // ][] + const tests = [ + ['undefined', undefined, emptyList], + ['null', null, emptyList], + ['a string', 'hi', emptyList], + ['an empty string', '', emptyList], + ['a number', 1, emptyList], + ['a bigint', 1n, emptyList], + ['a RegExp', new RegExp('.'), emptyList], + ['a Math', Math, emptyList], + ['an Array', [], emptyList], + ['a function', (): void => {}, emptyList], + ['empty object', {}, emptyList], + ['object 1', { id: 1 }, ['id']], + [ + 'object (vehicle)', + addSymbol(makeVehicle()), + EnumerableVehicleProperties, + AllVehicleProperties, + EnumerableVehicleProperties.concat([$sym]), + AllVehicleProperties.concat([$sym]), + ], + ]; + for (const [ + description, + value, + expected, + nonPublic, + symbols, + nonPublicAndSymbols, + ] of tests) { + t.test(`when subject ${description}`, async (t) => { + const it = new DeepDiff(); + const found = it.listComparableMembers(value); + t.matchOnly(found, expected, 'returns expected list'); + }); + if (nonPublic) { + t.test( + `includeNonEnumerable: when subject ${description}`, + async (t) => { + const it = new DeepDiff({ includeNonEnumerable: true }); + const found = it.listComparableMembers(value); + t.matchOnly(found, nonPublic, 'returns expected list'); + }, + ); + } + if (symbols) { + t.test(`symbols: when subject ${description}`, async (t) => { + const it = new DeepDiff({ includeSymbols: true }); + const found = it.listComparableMembers(value); + t.matchOnly(found, symbols, 'returns expected list'); + }); + } + if (nonPublicAndSymbols) { + t.test( + `nonPublicAndSymbols: when subject ${description}`, + async (t) => { + const it = new DeepDiff({ + includeNonEnumerable: true, + includeSymbols: true, + }); + const found = it.listComparableMembers(value); + t.matchOnly(found, nonPublicAndSymbols, 'returns expected list'); + }, + ); + } + } + }); +}); diff --git a/test/src/extended-type-of.ts b/test/src/extended-type-of.ts new file mode 100644 index 0000000..0d5a81e --- /dev/null +++ b/test/src/extended-type-of.ts @@ -0,0 +1,26 @@ +import tap from 'tap'; +import { ExtendedTypeOf, extendedTypeOf } from '../../src/extended-type-of.js'; + +tap.test('fn extendedTypeOf()', async (t) => { + const tests = [ + ['number', 1, ExtendedTypeOf.number], + ['bigint', 1n, ExtendedTypeOf.bigint], + ['string', 'hi', ExtendedTypeOf.string], + ['empty string', '', ExtendedTypeOf.string], + ['undefined', undefined, ExtendedTypeOf.undefined], + ['object', {}, ExtendedTypeOf.object], + ['Math', Math, ExtendedTypeOf.math], + ['Date', new Date(), ExtendedTypeOf.date], + ['RegExp', new RegExp(''), ExtendedTypeOf.regexp], + ['Array', [], ExtendedTypeOf.array], + ['function', (): void => {}, ExtendedTypeOf.function], + ['Null', null, ExtendedTypeOf.null], + ]; + + for (const [what, it, expect] of tests) { + t.test(`when subject is a ${what}`, async (t) => { + const found = extendedTypeOf(it); + t.equal(found, expect, `result is ${expect}`); + }); + } +}); diff --git a/test/src/path-pointers/index.ts b/test/src/path-pointers/index.ts new file mode 100644 index 0000000..65b07db --- /dev/null +++ b/test/src/path-pointers/index.ts @@ -0,0 +1,113 @@ +import tap from 'tap'; +import { PathSegments } from '../../../src/types.js'; +import { + PathSchemes, + decodePointer, + encodePointer, +} from '../../../src/path-pointers/index.js'; + +tap.test('encodePointer()', async (t) => { + const cases: [string, PathSegments, string, string, string][] = [ + ['empty', [], '.', '#', '[]'], + ['single prop', ['prop'], '.prop', '#/prop', '["prop"]'], + ['keyword', ['private'], '.["private"]', '#/private', '["private"]'], + [ + 'prop with dashes', + ['prop-with-dashes'], + '.["prop-with-dashes"]', + '#/prop-with-dashes', + '["prop-with-dashes"]', + ], + [ + 'prop with space', + ['prop with space'], + '.["prop with space"]', + '#/prop%20with%20space', + '["prop%20with%20space"]', + ], + + [ + 'prop with quote', + ['prop"quote'], + '.["prop\\"quote"]', + '#/prop%22quote', + '["prop%22quote"]', + ], + + [ + 'prop beginning with digit', + ['4giggles'], + '.["4giggles"]', + '#/4giggles', + '["4giggles"]', + ], + + ['prop with digit', ['g1ggl3s'], '.g1ggl3s', '#/g1ggl3s', '["g1ggl3s"]'], + + [ + 'chain of props', + ['one', 'two', 'three'], + '.one.two.three', + '#/one/two/three', + '["one","two","three"]', + ], + + [ + 'chain of props with number', + ['one', 2, 'three'], + '.one.[2].three', + '#/one/2/three', + '["one",2,"three"]', + ], + + [ + 'chain number at beginning', + [0, 'one', 'two'], + '.[0].one.two', + '#/0/one/two', + '[0,"one","two"]', + ], + + [ + 'chain number at end', + ['zero', 'one', 2], + '.zero.one.[2]', + '#/zero/one/2', + '["zero","one",2]', + ], + ]; + + t.test('dotted scheme notation', async (t) => { + for (const [what, it, expect, ,] of cases) { + t.test(`${what} round-trips`, (t) => { + const encoded = encodePointer(it, PathSchemes.dotted); + t.equal(encoded, expect, `encodes as ${expect}`); + const decoded = decodePointer(encoded); + t.matchOnly(decoded, it, `decodes as expected`); + t.end(); + }); + } + }); + t.test('pointer scheme notation', async (t) => { + for (const [what, it, , expect] of cases) { + t.test(`${what} round-trips`, (t) => { + const encoded = encodePointer(it, PathSchemes.pointer); + t.equal(encoded, expect, `encodes as ${expect}`); + const decoded = decodePointer(encoded); + t.matchOnly(decoded, it, `decodes as expected`); + t.end(); + }); + } + }); + t.test('json scheme notation', async (t) => { + for (const [what, it, , , expect] of cases) { + t.test(`${what} round-trips`, (t) => { + const encoded = encodePointer(it, PathSchemes.json); + t.equal(encoded, expect, `encodes as ${expect}`); + const decoded = decodePointer(encoded); + t.matchOnly(decoded, it, `decodes as expected`); + t.end(); + }); + } + }); +}); diff --git a/test/tests.html b/test/tests.html deleted file mode 100644 index d6094c0..0000000 --- a/test/tests.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - Mocha Tests - - - - - -
- - - - - - - - - - - - diff --git a/test/tests.js b/test/tests.js deleted file mode 100644 index 9207d1f..0000000 --- a/test/tests.js +++ /dev/null @@ -1,855 +0,0 @@ -(function (root, factory) { - if (typeof define === 'function' && define.amd) { // eslint-disable-line no-undef - define(['deep-diff', 'expect.js'], factory);// eslint-disable-line no-undef - } else if (typeof module === 'object' && module.exports) { - module.exports = factory(require('../'), require('expect.js')); - } else { - root.returnExports = factory(root.DeepDiff, root.expect); - } - // eslint-disable-next-line no-undef -}(typeof self !== 'undefined' ? self : this, function (deep, expect) { - - describe('deep-diff', function () { - var empty = {}; - - describe('A target that has no properties', function () { - - it('shows no differences when compared to another empty object', function () { - expect(deep.diff(empty, {})).to.be.an('undefined'); - }); - - describe('when compared to a different type of keyless object', function () { - var comparandTuples = [ - ['an array', { - key: [] - }], - ['an object', { - key: {} - }], - ['a date', { - key: new Date() - }], - ['a null', { - key: null - }], - ['a regexp literal', { - key: /a/ - }], - ['Math', { - key: Math - }] - ]; - - comparandTuples.forEach(function (lhsTuple) { - comparandTuples.forEach(function (rhsTuple) { - if (lhsTuple[0] === rhsTuple[0]) { - return; - } - it('shows differences when comparing ' + lhsTuple[0] + ' to ' + rhsTuple[0], function () { - var diff = deep.diff(lhsTuple[1], rhsTuple[1]); - expect(diff).to.be.ok(); - expect(diff.length).to.be(1); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('E'); - }); - }); - }); - }); - - describe('when compared with an object having other properties', function () { - var comparand = { - other: 'property', - another: 13.13 - }; - var diff = deep.diff(empty, comparand); - - it('the differences are reported', function () { - expect(diff).to.be.ok(); - expect(diff.length).to.be(2); - - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('N'); - expect(diff[0]).to.have.property('path'); - expect(diff[0].path).to.be.an(Array); - expect(diff[0].path[0]).to.eql('other'); - expect(diff[0]).to.have.property('rhs'); - expect(diff[0].rhs).to.be('property'); - - expect(diff[1]).to.have.property('kind'); - expect(diff[1].kind).to.be('N'); - expect(diff[1]).to.have.property('path'); - expect(diff[1].path).to.be.an(Array); - expect(diff[1].path[0]).to.eql('another'); - expect(diff[1]).to.have.property('rhs'); - expect(diff[1].rhs).to.be(13.13); - }); - - }); - - }); - - describe('A target that has one property', function () { - var lhs = { - one: 'property' - }; - - it('shows no differences when compared to itself', function () { - expect(deep.diff(lhs, lhs)).to.be.an('undefined'); - }); - - it('shows the property as removed when compared to an empty object', function () { - var diff = deep.diff(lhs, empty); - expect(diff).to.be.ok(); - expect(diff.length).to.be(1); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('D'); - }); - - it('shows the property as edited when compared to an object with null', function () { - var diff = deep.diff(lhs, { - one: null - }); - expect(diff).to.be.ok(); - expect(diff.length).to.be(1); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('E'); - }); - - it('shows the property as edited when compared to an array', function () { - var diff = deep.diff(lhs, ['one']); - expect(diff).to.be.ok(); - expect(diff.length).to.be(1); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('E'); - }); - - }); - - describe('A target that has null value', function () { - var lhs = { - key: null - }; - - it('shows no differences when compared to itself', function () { - expect(deep.diff(lhs, lhs)).to.be.an('undefined'); - }); - - it('shows the property as removed when compared to an empty object', function () { - var diff = deep.diff(lhs, empty); - expect(diff).to.be.ok(); - expect(diff.length).to.be(1); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('D'); - }); - - it('shows the property is changed when compared to an object that has value', function () { - var diff = deep.diff(lhs, { - key: 'value' - }); - expect(diff).to.be.ok(); - expect(diff.length).to.be(1); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('E'); - }); - - it('shows that an object property is changed when it is set to null', function () { - lhs.key = { - nested: 'value' - }; - var diff = deep.diff(lhs, { - key: null - }); - expect(diff).to.be.ok(); - expect(diff.length).to.be(1); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('E'); - }); - - }); - - - describe('A target that has a date value', function () { - var lhs = { - key: new Date(555555555555) - }; - - it('shows the property is changed with a new date value', function () { - var diff = deep.diff(lhs, { - key: new Date(777777777777) - }); - expect(diff).to.be.ok(); - expect(diff.length).to.be(1); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('E'); - }); - - }); - - - describe('A target that has a NaN', function () { - var lhs = { - key: NaN - }; - - it('shows the property is changed when compared to another number', function () { - var diff = deep.diff(lhs, { - key: 0 - }); - expect(diff).to.be.ok(); - expect(diff.length).to.be(1); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('E'); - }); - - it('shows no differences when compared to another NaN', function () { - var diff = deep.diff(lhs, { - key: NaN - }); - expect(diff).to.be.an('undefined'); - }); - - }); - - - describe('can revert namespace using noConflict', function () { - if (deep.noConflict) { - deep = deep.noConflict(); - - it('conflict is restored (when applicable)', function () { - // In node there is no global conflict. - if (typeof globalConflict !== 'undefined') { - expect(DeepDiff).to.be(deep); // eslint-disable-line no-undef - } - }); - - it('DeepDiff functionality available through result of noConflict()', function () { - expect(deep.applyDiff).to.be.a('function'); - }); - } - }); - - - describe('When filtering keys', function () { - var lhs = { - enhancement: 'Filter/Ignore Keys?', - numero: 11, - submittedBy: 'ericclemmons', - supportedBy: ['ericclemmons'], - status: 'open' - }; - var rhs = { - enhancement: 'Filter/Ignore Keys?', - numero: 11, - submittedBy: 'ericclemmons', - supportedBy: [ - 'ericclemmons', - 'TylerGarlick', - 'flitbit', - 'ergdev' - ], - status: 'closed', - fixedBy: 'flitbit' - }; - - describe('if the filtered property is an array', function () { - - it('changes to the array do not appear as a difference', function () { - var prefilter = function (path, key) { - return key === 'supportedBy'; - }; - var diff = deep(lhs, rhs, prefilter); - expect(diff).to.be.ok(); - expect(diff.length).to.be(2); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('E'); - expect(diff[1]).to.have.property('kind'); - expect(diff[1].kind).to.be('N'); - }); - - }); - - describe('if the filtered config is passed as an object', function () { - - it('changes to the array to not appear as a difference', function () { - var prefilter = function (path, key) { - return key === 'supportedBy'; - }; - var diff = deep(lhs, rhs, {prefilter: prefilter}); - expect(diff).to.be.ok(); - expect(diff.length).to.be(2); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('E'); - expect(diff[1]).to.have.property('kind'); - expect(diff[1].kind).to.be('N'); - }); - - }); - - describe('if the filtered property is not an array', function () { - - it('changes do not appear as a difference', function () { - var prefilter = function (path, key) { - return key === 'fixedBy'; - }; - var diff = deep(lhs, rhs, prefilter); - expect(diff).to.be.ok(); - expect(diff.length).to.be(4); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('A'); - expect(diff[1]).to.have.property('kind'); - expect(diff[1].kind).to.be('A'); - expect(diff[2]).to.have.property('kind'); - expect(diff[2].kind).to.be('A'); - expect(diff[3]).to.have.property('kind'); - expect(diff[3].kind).to.be('E'); - }); - - }); - }); - - describe('Can normalize properties to before diffing', function () { - var testLHS = { - array: [1, 2, 3, 4, 5], - }; - - var testRHS = { - array: '1/2/3/4/5', - }; - - it('changes do not appear as a difference', function () { - var filter = { - normalize: function (path, key, lhs, rhs) { - expect(key).to.be('array'); - - if (Array.isArray(lhs)) { - lhs = lhs.join('/'); - } - if (Array.isArray(rhs)) { - rhs = rhs.join('/'); - } - return [lhs, rhs]; - } - }; - - var diff; - - diff = deep(testLHS, testRHS, filter); - expect(diff).to.be.an('undefined'); - - diff = deep(testRHS, testLHS, filter); - expect(diff).to.be.an('undefined'); - }); - - it('falsy return does not normalize', function () { - var filter = { - // eslint-disable-next-line no-unused-vars - normalize: function (path, key, lhs, rhs) { - return false; - } - }; - - var diff; - - diff = deep(testLHS, testRHS, filter); - expect(diff).to.be.ok(); - - diff = deep(testRHS, testLHS, filter); - expect(diff).to.be.ok(); - }); - }); - - describe('A target that has nested values', function () { - var nestedOne = { - noChange: 'same', - levelOne: { - levelTwo: 'value' - }, - arrayOne: [{ - objValue: 'value' - }] - }; - var nestedTwo = { - noChange: 'same', - levelOne: { - levelTwo: 'another value' - }, - arrayOne: [{ - objValue: 'new value' - }, { - objValue: 'more value' - }] - }; - - it('shows no differences when compared to itself', function () { - expect(deep.diff(nestedOne, nestedOne)).to.be.an('undefined'); - }); - - it('shows the property as removed when compared to an empty object', function () { - var diff = deep(nestedOne, empty); - expect(diff).to.be.ok(); - expect(diff.length).to.be(3); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('D'); - expect(diff[1]).to.have.property('kind'); - expect(diff[1].kind).to.be('D'); - }); - - it('shows the property is changed when compared to an object that has value', function () { - var diff = deep.diff(nestedOne, nestedTwo); - expect(diff).to.be.ok(); - expect(diff.length).to.be(3); - }); - - it('shows the property as added when compared to an empty object on left', function () { - var diff = deep.diff(empty, nestedOne); - expect(diff).to.be.ok(); - expect(diff.length).to.be(3); - expect(diff[0]).to.have.property('kind'); - expect(diff[0].kind).to.be('N'); - }); - - describe('when diff is applied to a different empty object', function () { - var diff = deep.diff(nestedOne, nestedTwo); - - it('has result with nested values', function () { - var result = {}; - - deep.applyChange(result, nestedTwo, diff[0]); - expect(result.levelOne).to.be.ok(); - expect(result.levelOne).to.be.an('object'); - expect(result.levelOne.levelTwo).to.be.ok(); - expect(result.levelOne.levelTwo).to.eql('another value'); - }); - - it('has result with array object values', function () { - var result = {}; - - deep.applyChange(result, nestedTwo, diff[2]); - expect(result.arrayOne).to.be.ok(); - expect(result.arrayOne).to.be.an('array'); - expect(result.arrayOne[0]).to.be.ok(); - expect(result.arrayOne[0].objValue).to.be.ok(); - expect(result.arrayOne[0].objValue).to.equal('new value'); - }); - - it('has result with added array objects', function () { - var result = {}; - - deep.applyChange(result, nestedTwo, diff[1]); - expect(result.arrayOne).to.be.ok(); - expect(result.arrayOne).to.be.an('array'); - expect(result.arrayOne[1]).to.be.ok(); - expect(result.arrayOne[1].objValue).to.be.ok(); - expect(result.arrayOne[1].objValue).to.equal('more value'); - }); - }); - }); - - describe('regression test for bug #10, ', function () { - var lhs = { - id: 'Release', - phases: [{ - id: 'Phase1', - tasks: [{ - id: 'Task1' - }, { - id: 'Task2' - }] - }, { - id: 'Phase2', - tasks: [{ - id: 'Task3' - }] - }] - }; - var rhs = { - id: 'Release', - phases: [{ - // E: Phase1 -> Phase2 - id: 'Phase2', - tasks: [{ - id: 'Task3' - }] - }, { - id: 'Phase1', - tasks: [{ - id: 'Task1' - }, { - id: 'Task2' - }] - }] - }; - - describe('differences in nested arrays are detected', function () { - var diff = deep.diff(lhs, rhs); - - // there should be differences - expect(diff).to.be.ok(); - expect(diff.length).to.be(6); - - it('differences can be applied', function () { - var applied = deep.applyDiff(lhs, rhs); - - it('and the result equals the rhs', function () { - expect(applied).to.eql(rhs); - }); - - }); - }); - - }); - - describe('regression test for bug #35', function () { - var lhs = ['a', 'a', 'a']; - var rhs = ['a']; - - it('can apply diffs between two top level arrays', function () { - var differences = deep.diff(lhs, rhs); - - differences.forEach(function (it) { - deep.applyChange(lhs, true, it); - }); - - expect(lhs).to.eql(['a']); - }); - }); - - describe('Objects from different frames', function () { - if (typeof globalConflict === 'undefined') { return; } - - // eslint-disable-next-line no-undef - var frame = document.createElement('iframe'); - // eslint-disable-next-line no-undef - document.body.appendChild(frame); - - var lhs = new frame.contentWindow.Date(2010, 1, 1); - var rhs = new frame.contentWindow.Date(2010, 1, 1); - - it('can compare date instances from a different frame', function () { - var differences = deep.diff(lhs, rhs); - - expect(differences).to.be(undefined); - }); - }); - - describe('Comparing regexes should work', function () { - var lhs = /foo/; - var rhs = /foo/i; - - it('can compare regex instances', function () { - var diff = deep.diff(lhs, rhs); - - expect(diff.length).to.be(1); - - expect(diff[0].kind).to.be('E'); - expect(diff[0].path).to.not.be.ok(); - expect(diff[0].lhs).to.be('/foo/'); - expect(diff[0].rhs).to.be('/foo/i'); - }); - }); - - describe('subject.toString is not a function', function () { - var lhs = { - left: 'yes', - right: 'no', - }; - var rhs = { - left: { - toString: true, - }, - right: 'no', - }; - - it('should not throw a TypeError', function () { - var diff = deep.diff(lhs, rhs); - - expect(diff.length).to.be(1); - }); - }); - - describe('regression test for issue #83', function () { - var lhs = { - date: null - }; - var rhs = { - date: null - }; - - it('should not detect a difference', function () { - expect(deep.diff(lhs, rhs)).to.be(undefined); - }); - }); - - describe('regression test for issue #70', function () { - - it('should detect a difference with undefined property on lhs', function () { - var diff = deep.diff({ foo: undefined }, {}); - - expect(diff).to.be.an(Array); - expect(diff.length).to.be(1); - - expect(diff[0].kind).to.be('D'); - expect(diff[0].path).to.be.an('array'); - expect(diff[0].path).to.have.length(1); - expect(diff[0].path[0]).to.be('foo'); - expect(diff[0].lhs).to.be(undefined); - - }); - - it('should detect a difference with undefined property on rhs', function () { - var diff = deep.diff({}, { foo: undefined }); - - expect(diff).to.be.an(Array); - expect(diff.length).to.be(1); - - expect(diff[0].kind).to.be('N'); - expect(diff[0].path).to.be.an('array'); - expect(diff[0].path).to.have.length(1); - expect(diff[0].path[0]).to.be('foo'); - expect(diff[0].rhs).to.be(undefined); - - }); - }); - - describe('regression test for issue #98', function () { - var lhs = { foo: undefined }; - var rhs = { foo: undefined }; - - it('should not detect a difference with two undefined property values', function () { - var diff = deep.diff(lhs, rhs); - - expect(diff).to.be(undefined); - - }); - }); - - describe('regression tests for issue #102', function () { - it('should not throw a TypeError', function () { - - var diff = deep.diff(null, undefined); - - expect(diff).to.be.an(Array); - expect(diff.length).to.be(1); - - expect(diff[0].kind).to.be('D'); - expect(diff[0].lhs).to.be(null); - - }); - - it('should not throw a TypeError', function () { - - var diff = deep.diff(Object.create(null), { foo: undefined }); - - expect(diff).to.be.an(Array); - expect(diff.length).to.be(1); - - expect(diff[0].kind).to.be('N'); - expect(diff[0].rhs).to.be(undefined); - }); - }); - - describe('Order independent hash testing', function () { - function sameHash(a, b) { - expect(deep.orderIndepHash(a)).to.equal(deep.orderIndepHash(b)); - } - - function differentHash(a, b) { - expect(deep.orderIndepHash(a)).to.not.equal(deep.orderIndepHash(b)); - } - - describe('Order indepdendent hash function should give different values for different objects', function () { - it('should give different values for different "simple" types', function () { - differentHash(1, -20); - differentHash('foo', 45); - differentHash('pie', 'something else'); - differentHash(1.3332, 1); - differentHash(1, null); - differentHash('this is kind of a long string, don\'t you think?', 'the quick brown fox jumped over the lazy doge'); - differentHash(true, 2); - differentHash(false, 'flooog'); - }); - - it('should give different values for string and object with string', function () { - differentHash('some string', { key: 'some string' }); - }); - - it('should give different values for number and array', function () { - differentHash(1, [1]); - }); - - it('should give different values for string and array of string', function () { - differentHash('string', ['string']); - }); - - it('should give different values for boolean and object with boolean', function () { - differentHash(true, { key: true }); - }); - - it('should give different values for different arrays', function () { - differentHash([1, 2, 3], [1, 2]); - differentHash([1, 4, 5, 6], ['foo', 1, true, undefined]); - differentHash([1, 4, 6], [1, 4, 7]); - differentHash([1, 3, 5], ['1', '3', '5']); - }); - - it('should give different values for different objects', function () { - differentHash({ key: 'value' }, { other: 'value' }); - differentHash({ a: { b: 'c' } }, { a: 'b' }); - }); - - it('should differentiate between arrays and objects', function () { - differentHash([1, true, '1'], { a: 1, b: true, c: '1' }); - }); - }); - - describe('Order independent hash function should work in pathological cases', function () { - it('should work in funky javascript cases', function () { - differentHash(undefined, null); - differentHash(0, undefined); - differentHash(0, null); - differentHash(0, false); - differentHash(0, []); - differentHash('', []); - differentHash(3.22, '3.22'); - differentHash(true, 'true'); - differentHash(false, 0); - }); - - it('should work on empty array and object', function () { - differentHash([], {}); - }); - - it('should work on empty object and undefined', function () { - differentHash({}, undefined); - }); - - it('should work on empty array and array with 0', function () { - differentHash([], [0]); - }); - }); - - describe('Order independent hash function should be order independent', function () { - it('should not care about array order', function () { - sameHash([1, 2, 3], [3, 2, 1]); - sameHash(['hi', true, 9.4], [true, 'hi', 9.4]); - }); - - it('should not care about key order in an object', function () { - sameHash({ foo: 'bar', foz: 'baz' }, { foz: 'baz', foo: 'bar' }); - }); - - it('should work with complicated objects', function () { - var obj1 = { - foo: 'bar', - faz: [ - 1, - 'pie', - { - food: 'yum' - } - ] - }; - - var obj2 = { - faz: [ - 'pie', - { - food: 'yum' - }, - 1 - ], - foo: 'bar' - }; - - sameHash(obj1, obj2); - }); - }); - }); - - - describe('Order indepedent array comparison should work', function () { - it('can compare simple arrays in an order independent fashion', function () { - var lhs = [1, 2, 3]; - var rhs = [1, 3, 2]; - - var diff = deep.orderIndependentDiff(lhs, rhs); - expect(diff).to.be(undefined); - }); - - it('still works with repeated elements', function () { - var lhs = [1, 1, 2]; - var rhs = [1, 2, 1]; - - var diff = deep.orderIndependentDiff(lhs, rhs); - expect(diff).to.be(undefined); - }); - - it('works on complex objects', function () { - var obj1 = { - foo: 'bar', - faz: [ - 1, - 'pie', - { - food: 'yum' - } - ] - }; - - var obj2 = { - faz: [ - 'pie', - { - food: 'yum' - }, - 1 - ], - foo: 'bar' - }; - - var diff = deep.orderIndependentDiff(obj1, obj2); - expect(diff).to.be(undefined); - }); - - it('should report some difference in non-equal arrays', function () { - var lhs = [1, 2, 3]; - var rhs = [2, 2, 3]; - - var diff = deep.orderIndependentDiff(lhs, rhs); - expect(diff.length).to.be.ok(); - }); - - - }); - - }); - - describe('Diff-ing symbol-based keys should work', function () { - const lhs = { - [Symbol.iterator]: 'Iterator', // eslint-disable-line no-undef - foo: 'bar' - }; - const rhs = { - foo: 'baz' - }; - - const res = deep.diff(lhs, rhs); - expect(res).to.be.ok(); - expect(res).to.be.an('array'); - expect(res).to.have.length(2); - - let changed = 0, deleted = 0; - for (const difference of res) { - if (difference.kind === 'D') { - deleted += 1; - } else if (difference.kind === 'E') { - changed += 1; - } - } - - expect(changed).to.be(1); - expect(deleted).to.be(1); - - }); - -})); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..6b03dd0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "es2022", + "module": "node16", + "lib": ["ES2022"], + "moduleResolution": "node16", + "esModuleInterop": true, + "rootDir": ".", + "outDir": "dist", + "allowSyntheticDefaultImports": true, + "allowJs": false, + "importHelpers": true, + "alwaysStrict": true, + "sourceMap": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitAny": false, + "noImplicitThis": false, + "strictNullChecks": false + }, + "include": ["src/**/*", "test/**/*", "examples/**/*"] +} diff --git a/tsconfig.release.json b/tsconfig.release.json new file mode 100644 index 0000000..f08638c --- /dev/null +++ b/tsconfig.release.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "sourceMap": false, + "removeComments": true + }, + "include": ["src/**/*"] +}