diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 96f1cb62..00000000 --- a/.eslintignore +++ /dev/null @@ -1,20 +0,0 @@ -*.sh -node_modules -*.md -*.woff -*.ttf -.vscode -.idea -dist -/public -/docs -.husky -.local -/bin -.eslintrc.js -prettier.config.js -/src/mock/* -coverage -docs-html -.github -pnpm-lock.yaml \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index b9df709d..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,50 +0,0 @@ -module.exports = { - /* 优先级低于parse的语法解析配置 */ - parserOptions: { - parser: '@typescript-eslint/parser', - }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', // typescript-eslint推荐规则 - 'prettier', - 'plugin:prettier/recommended', - ], - env: { - browser: true, - node: true, - es6: true, - }, - rules: { - // 禁止使用 var - 'no-var': 'error', - // 不使用结尾分号 - semi: 'off', - eqeqeq: 'error', - 'no-case-declarations': 'off', - // 优先使用 interface 而不是 type - '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/ban-types': 'off', - '@typescript-eslint/no-unused-vars': 'error', - '@typescript-eslint/no-this-alias': 'off', - }, - overrides: [ - { - files: ['**/__tests__/**'], - rules: { - eqeqeq: 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/ban-ts-comment': 'off', - }, - }, - { - files: ['**/scripts/**.[jt]s', 'rollup.config.js'], - rules: { - eqeqeq: 'off', - '@typescript-eslint/no-var-requires': 'off', - }, - }, - ], -}; diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml new file mode 100644 index 00000000..f59b4f6a --- /dev/null +++ b/.github/workflows/gh-pages.yml @@ -0,0 +1,24 @@ +name: github pages +on: + push: + branches: + - main +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install pnpm + uses: pnpm/action-setup@v2 + - name: Set node version to 18 + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: 'pnpm' + - run: pnpm install --frozen-lockfile + - run: npm run typedoc:build + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs-dist diff --git a/.gitignore b/.gitignore index fa66ea14..b3368d36 100644 --- a/.gitignore +++ b/.gitignore @@ -104,5 +104,5 @@ dist .tern-port .idea -docs-html +docs-dist temp diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e5c4f4b..de85c742 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,309 @@ +## [0.9.6](https://github.com/js-tool-pack/basic/compare/v0.9.5...v0.9.6) (2025-03-20) + +### Features + +- 为 DynamicEnum 添加 map 方法 ([d9c7151](https://github.com/js-tool-pack/basic/commit/d9c715113ab758eb7ae301e4fde7c34e62ca3226)) + +## [0.9.5](https://github.com/js-tool-pack/basic/compare/v0.9.3...v0.9.5) (2025-03-19) + +### Features + +- 为 DynamicEnum 添加 setOrSwap 方法 ([456e6d4](https://github.com/js-tool-pack/basic/commit/456e6d48dcaa1ed95799b5939831aaf8c1b1025a)) +- 为 DynamicEnum 添加泛型推断 ([6ed6aca](https://github.com/js-tool-pack/basic/commit/6ed6aca58d99036ab1fdfc7e0f2755e82b116b89)) + +## [0.9.3](https://github.com/js-tool-pack/basic/compare/v0.9.1...v0.9.3) (2025-03-18) + +### Features + +- **common:** 新增 DynamicEnum ([5f1800b](https://github.com/js-tool-pack/basic/commit/5f1800bcae2c658ab883e440af0b515661ed0d91)) + +## [0.9.2](https://github.com/js-tool-pack/basic/compare/v0.9.1...v0.9.2) (2025-03-18) + +### Features + +- **common:** 新增 DynamicEnum ([5f1800b](https://github.com/js-tool-pack/basic/commit/5f1800bcae2c658ab883e440af0b515661ed0d91)) + +## [0.9.1](https://github.com/js-tool-pack/basic/compare/v0.9.0...v0.9.1) (2024-06-03) + +### Features + +- **common:** 新增 createEventBus ([7e62276](https://github.com/js-tool-pack/basic/commit/7e62276b32b64492e27ee6e15c69b4bcf9555986)) + +# [0.9.0](https://github.com/js-tool-pack/basic/compare/v0.8.3...v0.9.0) (2024-05-30) + +### Bug Fixes + +- 修复 exports 顺序在某些打包工具中default 不在最后会报错的问题 ([a3f9f97](https://github.com/js-tool-pack/basic/commit/a3f9f972b327d18de85591f0010d5dd5e17a216d)) + +## [0.8.3](https://github.com/js-tool-pack/basic/compare/v0.8.2...v0.8.3) (2024-05-15) + +### Features + +- **base64:** 新增 parseBase64、arrayBufferToBase64、base64ToArrayBuffer ([8eafa04](https://github.com/js-tool-pack/basic/commit/8eafa04aa3c8bd7ce3877e9e0399b41101f08595)) + +## [0.8.2](https://github.com/js-tool-pack/basic/compare/v0.8.1...v0.8.2) (2024-05-15) + +### Bug Fixes + +- **common:** 修复 throttle 对有参数的函数会类型报错的问题 ([7687330](https://github.com/js-tool-pack/basic/commit/768733046acc8a32a105ebc9ed58b88b3913b3e7)) + +## [0.8.1](https://github.com/js-tool-pack/basic/compare/v0.8.0...v0.8.1) (2024-05-13) + +### Features + +- **array-buffer:** 为 stringToArrayBuffer 和 arrayBufferToString 添加可选择 Uint16Array 还是 Uint8Array 的功能 ([e764e4e](https://github.com/js-tool-pack/basic/commit/e764e4e5c2266f2081dc471a7bc20fee21cade65)) + +# [0.8.0](https://github.com/js-tool-pack/basic/compare/v0.7.7...v0.8.0) (2024-05-13) + +### Bug Fixes + +- **array-buffer:** 修复 stringToArrayBuffer 和 arrayBufferToString 中文乱码的问题 ([0f95bbc](https://github.com/js-tool-pack/basic/commit/0f95bbcafc762afeb666c9c882d2537acf8456e6)) + +## [0.7.7](https://github.com/js-tool-pack/basic/compare/v0.7.6...v0.7.7) (2024-05-13) + +### Features + +- **array-buffer:** 新增 arrayBufferToString 和 stringToArrayBuffer ([6bfc336](https://github.com/js-tool-pack/basic/commit/6bfc3362c96a3923b0136e4466cd1b9a066feaba)) +- **array-buffer:** 新增 encodeObjectToArrayBuffer 和 decodeArrayBufferToObject ([0a0874e](https://github.com/js-tool-pack/basic/commit/0a0874e1f875d876180231053910eb1c70a8a3c0)) +- **promise/nextTick:** 当传入参数时返回值改为中断闭包函数 ([d546707](https://github.com/js-tool-pack/basic/commit/d546707baf8a1773b8af7d7c432906fd8d44b015)) + +## [0.7.6](https://github.com/js-tool-pack/basic/compare/v0.7.5...v0.7.6) (2024-04-09) + +### Performance Improvements + +- **array/groupBy:** 提供更精准的返回值类型 ([2ba7382](https://github.com/js-tool-pack/basic/commit/2ba738226838fee0d9e611c42e14ce23217a1c4a)) + +## [0.7.5](https://github.com/js-tool-pack/basic/compare/v0.7.4...v0.7.5) (2024-04-09) + +### Performance Improvements + +- **array:** 优化 groupBy ([6a6ce83](https://github.com/js-tool-pack/basic/commit/6a6ce8376c2fa7f9dd5c1420b0f74bfc5d65220a)) + +## [0.7.4](https://github.com/js-tool-pack/basic/compare/v0.7.3...v0.7.4) (2024-04-09) + +### Features + +- **common/createEnum:** 添加类型体操 ([67863b5](https://github.com/js-tool-pack/basic/commit/67863b5ab70898b7dd1c2b6e6de385db2326a74d)) +- **object/getReversedObj:** 添加类型体操 ([6c55b41](https://github.com/js-tool-pack/basic/commit/6c55b419002de6cd13017c2bcf4e89d4307b126c)) + +## [0.7.3](https://github.com/js-tool-pack/basic/compare/v0.7.2...v0.7.3) (2024-04-04) + +### Features + +- **number:** 新增 shortenNumber 缩短数字 ([04f3bcd](https://github.com/js-tool-pack/basic/commit/04f3bcd46ab4f1293b5c85335e46daddd9874697)) + +## [0.7.2](https://github.com/js-tool-pack/basic/compare/v0.7.1...v0.7.2) (2024-04-04) + +### Features + +- **time/dateAdd:** 第二个参数可为对象,增加复数类型数值 ([d6c9fad](https://github.com/js-tool-pack/basic/commit/d6c9fad6e92f7e3651b24d57f5f446e62d1acbd8)) + +## [0.7.1](https://github.com/js-tool-pack/basic/compare/v0.7.0...v0.7.1) (2024-03-26) + +# [0.7.0](https://github.com/js-tool-pack/basic/compare/v0.6.0...v0.7.0) (2024-01-16) + +### Features + +- **time:** isSameDate 判断两个日期是否是同一天 ([c63d36e](https://github.com/js-tool-pack/basic/commit/c63d36e0343ac5b5c3d4683b35aaf4bef8e21481)) + +# [0.6.0](https://github.com/js-tool-pack/basic/compare/v0.5.2...v0.6.0) (2024-01-12) + +### Features + +- **time:** isNextMonth 判断日期是否是下个月 ([16f933e](https://github.com/js-tool-pack/basic/commit/16f933eeac224da4c5ea38f329ca8d85dd66eec9)) + +## [0.5.2](https://github.com/js-tool-pack/basic/compare/v0.5.1...v0.5.2) (2024-01-11) + +### Bug Fixes + +- **time:** 修复 parseFormattedDate 漏掉 date 会变成前一个月的问题 ([335eb6d](https://github.com/js-tool-pack/basic/commit/335eb6da1a54a9648e0f24d925502730d821e16a)) + +## [0.5.1](https://github.com/js-tool-pack/basic/compare/v0.5.0...v0.5.1) (2024-01-11) + +### Features + +- **time:** 为 getStartOfMonth 添加 offset 参数 ([6bdbca7](https://github.com/js-tool-pack/basic/commit/6bdbca71816b6d549cebadee2b9ec957e78d2fce)) + +# [0.5.0](https://github.com/js-tool-pack/basic/compare/v0.4.0...v0.5.0) (2024-01-11) + +### Features + +- **time:** getStartOfMonth ([e17bb6c](https://github.com/js-tool-pack/basic/commit/e17bb6cefd3d3f4769e9c191459d8c6ce173792e)) + +# [0.4.0](https://github.com/js-tool-pack/basic/compare/v0.3.1...v0.4.0) (2024-01-03) + +### Bug Fixes + +- **time:** 修复 WeekDays 类型问题 ([5ba15a4](https://github.com/js-tool-pack/basic/commit/5ba15a479f3ebd395e5b0161ac43c9df0c9a6d19)) + +### Features + +- **time:** parseFormattedDate ([1f504d5](https://github.com/js-tool-pack/basic/commit/1f504d5df943a8bf96f81a5b1361e3469b2ca61d)) + +## [0.3.1](https://github.com/js-tool-pack/basic/compare/v0.3.0...v0.3.1) (2023-12-19) + +### Bug Fixes + +- **time:** 修复 getStartOfWeek 部分日期不准确的问题 ([0b643fd](https://github.com/js-tool-pack/basic/commit/0b643fd8b274f5bdcb59e347c1308112e5e37b2b)) + +# [0.3.0](https://github.com/js-tool-pack/basic/compare/v0.2.0...v0.3.0) (2023-12-19) + +### Features + +- **time:** getEndOfWeek 可选择星期的任意一天作为开始,不再局限于周一和周日 ([ea1862c](https://github.com/js-tool-pack/basic/commit/ea1862cb9f9ee9455f666ac78a876e4de7874574)) +- **time:** getStartOfWeek 可选择星期的任意一天作为开始,不再局限于周一和周日 ([ee7d868](https://github.com/js-tool-pack/basic/commit/ee7d86866d17b29489e873ea9831997b84e73a06)) +- **time:** 移除 getStartOfNextWeek ([265b7bb](https://github.com/js-tool-pack/basic/commit/265b7bb066ca710996770eb6d379da581a3fc703)) + +### BREAKING CHANGES + +- **time:** 移除 weekBegin 选项 +- **time:** 移除 getStartOfNextWeek,可通过 getStartOfWeek 添加偏移量代替该函数 +- **time:** 移除 weekBegin 选项 + +# [0.2.0](https://github.com/js-tool-pack/basic/compare/v0.1.3...v0.2.0) (2023-12-17) + +### Features + +- **time:** getEndOfMonth 函数添加 monthOffset 参数,可获取前 n 个或后 n 个月的结束日期 ([1b3b97c](https://github.com/js-tool-pack/basic/commit/1b3b97c68a6cd82a69ce99989b58d0a2947ba777)) +- **time:** 移除 getEndOfPrevMonth ([dc033f1](https://github.com/js-tool-pack/basic/commit/dc033f14fdfbc2361fbd8aff444c6d5a79159812)) + +### Performance Improvements + +- **array:** 优化 chunk 函数 ([c64c544](https://github.com/js-tool-pack/basic/commit/c64c5443c639a45e8a54055d9b567172597cb663)) + +### BREAKING CHANGES + +- **time:** 移除 getEndOfPrevMonth,可通过 getEndOfMonth 添加偏移量代替该函数 + +## [0.1.3](https://github.com/js-tool-pack/basic/compare/v0.1.2...v0.1.3) (2023-12-16) + +### Features + +- **time:** dateAdd ([084819c](https://github.com/js-tool-pack/basic/commit/084819cd62f2af224bf0004fe72ee11c608871ea)) +- **time:** getEndOfPrevMonth ([8c4b6a1](https://github.com/js-tool-pack/basic/commit/8c4b6a1827aba275a2207b6a9f997155ec63e2f7)) +- **time:** getEndOfWeek ([47e9eb9](https://github.com/js-tool-pack/basic/commit/47e9eb92c754974d47f21348ffa4fcd16c056289)) + +## [0.1.2](https://github.com/js-tool-pack/basic/compare/v0.1.1...v0.1.2) (2023-08-25) + +### Bug Fixes + +- **common:** 修复 createTimeCountUp 后马上调用 play 时间不对的问题 ([bcbba11](https://github.com/js-tool-pack/basic/commit/bcbba1148b1284cef2c9c4c1b8d2e594ef2b6f97)) + +### Features + +- **common:** emptyFn 空函数 ([82924f7](https://github.com/js-tool-pack/basic/commit/82924f72d9c7f0ab333ff6e87829f8adac0b4b2b)) + +## [0.1.1](https://github.com/js-tool-pack/basic/compare/v0.1.1-beta.1...v0.1.1) (2023-07-08) + +## [0.1.1-beta.1](https://github.com/js-tool-pack/basic/compare/v0.1.0...v0.1.1-beta.1) (2023-07-08) + +### Code Refactoring + +- **string/cases:** 使用 splitByCases 代替 CaseSplitRegExp ([0082080](https://github.com/js-tool-pack/basic/commit/0082080971bd29516b7297e9d6266098f8bf0468)), closes [#12](https://github.com/js-tool-pack/basic/issues/12) + +### Features + +- **string:** 新增 splitByCases,把各种变量风格的字符串分割成字符串数组;用于代替 CaseSplitRegExp ([0b6ff2b](https://github.com/js-tool-pack/basic/commit/0b6ff2bb3dce92dfc3f38b607d32c4cdf6a38f56)) + +### BREAKING CHANGES + +- **string/cases:** 移除 CaseSplitRegExp + +# [0.1.0](https://github.com/js-tool-pack/basic/compare/v0.0.27...v0.1.0) (2023-06-30) + +### Bug Fixes + +- **array:** inRange 类型不正确 ([ac907a4](https://github.com/js-tool-pack/basic/commit/ac907a4bfb879d5235677dbd5259022b93c5ee66)) + +### Features + +- **data-type:** 新增 isASCIIPunctuationSymbol,判断字符串内是否全部都是 ascii 标点符号 ([00ab5ad](https://github.com/js-tool-pack/basic/commit/00ab5ad80320e6d39e45d57c54898eccc90b33b8)) +- **string:** 新增 camelCase,其他变量命名风格转小驼峰 ([95cb370](https://github.com/js-tool-pack/basic/commit/95cb37097320685cf324f8d86eab66a952a6cb01)) +- **string:** 新增 CaseSplitRegExp 正则,用于切割各种命名法的字符串 ([6eb5c43](https://github.com/js-tool-pack/basic/commit/6eb5c43169be013c98f8a5f6aa8faeef5fe8ee67)) +- **string:** 新增 kebabCase,其他变量命名风格转小写加中划线 ([0c0a1f1](https://github.com/js-tool-pack/basic/commit/0c0a1f1efdb27cdab413a8f42c3c75152869164f)) +- **string:** 新增 pascalCase,其他变量命名风格转大驼峰 ([f9f77ce](https://github.com/js-tool-pack/basic/commit/f9f77ce0fd4c82329b2a6771bfbea450310ae038)) +- **string:** 新增 snakeCase,其他变量命名风格转蛇形 ([9d59b3d](https://github.com/js-tool-pack/basic/commit/9d59b3d2c67239e6413bc7fd03875bd52c8ac5d2)) +- **string:** 移除 fromCamel ([d272e84](https://github.com/js-tool-pack/basic/commit/d272e84e0f7d6a0385040dd6a513be3667184ddf)) +- **string:** 移除 toCamel ([beddc8a](https://github.com/js-tool-pack/basic/commit/beddc8ac5e36d5fdba6ffd9358f99b0f6b438a3e)) + +### BREAKING CHANGES + +- **string:** 移除 fromCamel,可以使用 kebabCase、pascalCase、snakeCase 代替 +- **string:** 移除 toCamel,可以使用 camelCase 或 pascalCase 作为代替 + +## [0.0.27](https://github.com/js-tool-pack/basic/compare/v0.0.26...v0.0.27) (2023-06-20) + +### Features + +- **promise:** nextTick ([a5202b0](https://github.com/js-tool-pack/basic/commit/a5202b0d0e0e15cee725832df2be12368650daef)) + +## [0.0.26](https://github.com/js-tool-pack/basic/compare/v0.0.25...v0.0.26) (2023-06-20) + +### Features + +- **data-type:** isArrayLike 支持范型 ([a3cf26f](https://github.com/js-tool-pack/basic/commit/a3cf26f39d027e72a05739485cdfe124da83c82e)) +- **data-type:** isIterable 支持范型 ([3ddfc2c](https://github.com/js-tool-pack/basic/commit/3ddfc2c179669638ebf80c81e7d5dc8c0535cdc2)) +- **data-type:** isObjectLike 支持范型 ([e5a6e33](https://github.com/js-tool-pack/basic/commit/e5a6e33fb29bb83ad2008e72f042b88f934752f8)) +- **data-type:** isObject 支持范型 ([c3bb8a5](https://github.com/js-tool-pack/basic/commit/c3bb8a5e43c43c84e6c278a08a6d70b7b8424961)) + +## [0.0.25](https://github.com/js-tool-pack/basic/compare/v0.0.24...v0.0.25) (2023-06-18) + +### Features + +- **array:** joinArray 添加 callbackFn 回调,可对数组遍历进行操作 ([f9f1b17](https://github.com/js-tool-pack/basic/commit/f9f1b172caa693d864d09c9bd5b3a80039099cc8)) + +## [0.0.24](https://github.com/js-tool-pack/basic/compare/v0.0.23...v0.0.24) (2023-06-18) + +### Features + +- **array:** joinArray separator 参数支持回调函数类型 ([d404e72](https://github.com/js-tool-pack/basic/commit/d404e72b994c431c8f472adb4a8d96635a94aa8c)) +- **data-type:** isArray 支持范型 ([6af6267](https://github.com/js-tool-pack/basic/commit/6af6267913734ab27a555e3e221d4d6390c781f1)) +- **data-type:** isFunction 支持范型 ([d1b9d4f](https://github.com/js-tool-pack/basic/commit/d1b9d4f47295b16d0c780b2ef584135066415095)) +- **data-type:** isNullish ([0443871](https://github.com/js-tool-pack/basic/commit/0443871be1402874dbdf2ecbe71d8508050bd09d)) +- **data-type:** isUnavailable ([5980edd](https://github.com/js-tool-pack/basic/commit/5980edd44b01da97e4d1347f6679e8c30daf11d9)) + +## [0.0.23](https://github.com/js-tool-pack/basic/compare/v0.0.22...v0.0.23) (2023-06-18) + +### Features + +- **array:** joinArray ([d39d888](https://github.com/js-tool-pack/basic/commit/d39d8885a36474beb12d7ca387839b8f1e4686a7)) + +## [0.0.22](https://github.com/js-tool-pack/basic/compare/v0.0.21...v0.0.22) (2023-06-17) + +### Features + +- **string:** getClassNames 当有重复的 className 时,后面的条件需要覆盖前面的条件 ([cca042d](https://github.com/js-tool-pack/basic/commit/cca042d0c6680d17e904e063ac37888dc90aed1a)) + +## [0.0.21](https://github.com/js-tool-pack/basic/compare/v0.0.20...v0.0.21) (2023-06-17) + +### Features + +- **string:** getClassNames 类型支持 null 和 undefined ([010f395](https://github.com/js-tool-pack/basic/commit/010f3959550fae102700029b26a5509fcae990cb)) + +## [0.0.20](https://github.com/js-tool-pack/basic/compare/v0.0.19...v0.0.20) (2023-05-30) + +### Bug Fixes + +- **time:** getEndOfMonth 在日期为 2023 年 5 月 31 号时会获取错误的日期 ([f503b93](https://github.com/js-tool-pack/basic/commit/f503b9340b20bb2eabbed27dcf37e55e67e7ec0f)) + +### Features + +- **common:** loadingElse ([34b2ed4](https://github.com/js-tool-pack/basic/commit/34b2ed427c322c7d750f03391b1bce4fb23bead8)) + +## [0.0.19](https://github.com/js-tool-pack/basic/compare/v0.0.18...v0.0.19) (2023-04-27) + +### Bug Fixes + +- **time:** 修复 msToDateStr 对小数秒数出错的 bug ([38f2710](https://github.com/js-tool-pack/basic/commit/38f27109094cef3b6b16983b31cbec0d41c8cde7)) + +### Features + +- **time:** msToDateStr 重命名为 formatMilliseconds ([0f3e030](https://github.com/js-tool-pack/basic/commit/0f3e03067dea295464056ddb4c9d8e0704cd4763)) + +### BREAKING CHANGES + +- **time:** 重命名 msToDateStr 为 formatMilliseconds + ## [0.0.18](https://github.com/js-tool-pack/basic/compare/v0.0.17...v0.0.18) (2023-04-26) ### Bug Fixes diff --git a/__tests__/array-buffer.test.ts b/__tests__/array-buffer.test.ts new file mode 100644 index 00000000..d561b122 --- /dev/null +++ b/__tests__/array-buffer.test.ts @@ -0,0 +1,21 @@ +import * as AB from '../src/array-buffer'; +describe('ArrayBuffer', function () { + test('arrayBufferToString', () => { + const ab = new Uint8Array(2); + ab[0] = 1; + ab[1] = 2; + expect(AB.arrayBufferToString(ab)).toBe(''); + expect(AB.arrayBufferToString(new Uint8Array(0))).toBe(''); + }); + test('stringToArrayBuffer & arrayBufferToString', () => { + const v = AB.stringToArrayBuffer('123'); + expect(AB.arrayBufferToString(v)).toBe('123'); + expect(AB.arrayBufferToString(v).length).toBe('123'.length); + expect(AB.arrayBufferToString(AB.stringToArrayBuffer('中文'))).toBe('中文'); + expect(AB.arrayBufferToString(AB.stringToArrayBuffer('中文', 8), 8)).not.toBe('中文'); + }); + test('encodeObjectToArrayBuffer & decodeArrayBufferToObject', () => { + const v = AB.encodeObjectToArrayBuffer({ a: 1, b: 2 }); + expect(AB.decodeArrayBufferToObject(v)).toEqual({ a: 1, b: 2 }); + }); +}); diff --git a/__tests__/array/array-async.test.ts b/__tests__/array/array-async.test.ts index f42557af..c44904fb 100644 --- a/__tests__/array/array-async.test.ts +++ b/__tests__/array/array-async.test.ts @@ -1,4 +1,4 @@ -import { sleep, forEachAsync, mapAsync, reduceAsync } from '../../src'; +import { forEachAsync, reduceAsync, mapAsync, sleep } from '../../src'; describe('promise', function () { test('forEachAsync', async () => { @@ -7,7 +7,7 @@ describe('promise', function () { await fn(arr1, async (_v, k) => (arr1[k] = k)); expect(arr1).toEqual([0, 1, 2]); // ArrayLike - await fn({ 0: 1, 1: 2, length: 2 }, async (_v, k) => (arr1[k] = k + k)); + await fn({ length: 2, 0: 1, 1: 2 }, async (_v, k) => (arr1[k] = k + k)); expect(arr1).toEqual([0, 2, 2]); // const arr = thisArg || this; await fn.call(arr1, arr1, async (_v, k) => (arr1[k] = k + 2)); diff --git a/__tests__/array/array.test.ts b/__tests__/array/array.test.ts index d4e8b06c..66b3ca98 100644 --- a/__tests__/array/array.test.ts +++ b/__tests__/array/array.test.ts @@ -1,28 +1,29 @@ import { + getYangHuiTriangleOne, + arrayRemoveItemsBy, + getYangHuiTriangle, + binaryFindIndex, + arrayRemoveItem, + findIndexRight, + insertToArray, + forEachAround, + forEachRight, createArray, - forEach, forEachObj, - isEqual, - forEachRight, - findIndex, - findIndexRight, binaryFind, - binaryFindIndex, - insertToArray, - arrayRemoveItem, - arrayRemoveItemsBy, - unique, - chunk, - inRange, - inRanges, - groupBy, someInList, + findIndex, castArray, + joinArray, + inRanges, + forEach, + isEqual, + inRange, + groupBy, + unique, + chunk, sum, avg, - getYangHuiTriangle, - getYangHuiTriangleOne, - forEachAround, } from '../../src'; describe('array', function () { @@ -37,21 +38,21 @@ describe('array', function () { expect(createArray({ start: 3, len: 1, end: 5 })).toEqual([3]); expect( createArray({ - start: 3, - len: 5, - end: 5, fill(item, index) { return item + '' + index; }, + start: 3, + len: 5, + end: 5, }), ).toEqual(['30', '41']); - expect(createArray({ start: 3, len: 5, end: 6, fill: 0 })).toEqual([0, 0, 0]); + expect(createArray({ start: 3, fill: 0, len: 5, end: 6 })).toEqual([0, 0, 0]); // 测试fill参数 const fn = jest.fn((a) => a); // end为len - createArray({ len: 5, fill: fn }); + createArray({ fill: fn, len: 5 }); expect(fn.mock.calls).toEqual([ [0, 0, 5], [1, 1, 5], @@ -63,7 +64,7 @@ describe('array', function () { fn.mock.calls.length = 0; // end为start+len - createArray({ start: 3, len: 5, fill: fn }); + createArray({ start: 3, fill: fn, len: 5 }); expect(fn.mock.calls).toEqual([ [3, 0, 8], [4, 1, 8], @@ -75,7 +76,7 @@ describe('array', function () { fn.mock.calls.length = 0; // end为end - createArray({ start: 2, end: 3, fill: fn }); + createArray({ start: 2, fill: fn, end: 3 }); expect(fn.mock.calls).toEqual([[2, 0, 3]]); }); test('forEach', () => { @@ -85,7 +86,7 @@ describe('array', function () { expect(isDone).toBe(true); // ArrayLike - isDone = forEach({ 0: 1, 1: 2, length: 2 }, (_v, k) => (arr1[k] = k + k)); + isDone = forEach({ length: 2, 0: 1, 1: 2 }, (_v, k) => (arr1[k] = k + k)); expect(isEqual(arr1, [0, 2, 2])).toBe(true); expect(isDone).toBe(true); @@ -138,10 +139,13 @@ describe('array', function () { return; }); expect(result).toEqual( - createArray({ start: 10, end: 20 }).reduce((obj, v) => { - obj[v] = v; - return obj; - }, {} as Record), + createArray({ start: 10, end: 20 }).reduce( + (obj, v) => { + obj[v] = v; + return obj; + }, + {} as Record, + ), ); const result2: any[] = []; @@ -205,12 +209,12 @@ describe('array', function () { const list: { id: number }[] = Array.from({ length: 100 }).map((_, i) => ({ id: i * 2 })); function find(target: number): { - times: number; index: ReturnType; + times: number; } { // 查找次数 let times = 0; - const index = binaryFindIndex(list, function ({ item, index, start, end }) { + const index = binaryFindIndex(list, function ({ index, start, item, end }) { times++; // console.log(index); // 判断index是否正确 @@ -277,9 +281,9 @@ describe('array', function () { test('binaryFind', () => { const list: { id: number }[] = [...Array(100).keys()].map((i) => ({ id: i * 2 })); - function find(target: number): { times: number; value: ReturnType } { + function find(target: number): { value: ReturnType; times: number } { let times = 0; - const value = binaryFind(list, ({ item, index }) => { + const value = binaryFind(list, ({ index, item }) => { times++; // console.log(index); // 判断index是否正确 @@ -311,23 +315,23 @@ describe('array', function () { // 正常查找 let findTimes = 0; const arr = [ - { id: 1, text: '1' }, - { id: 2, text: '2' }, - { id: 3, text: '3' }, - { id: 4, text: '4' }, - { id: 5, text: '5' }, - { id: 6, text: '6' }, + { text: '1', id: 1 }, + { text: '2', id: 2 }, + { text: '3', id: 3 }, + { text: '4', id: 4 }, + { text: '5', id: 5 }, + { text: '6', id: 6 }, ]; - expect(binaryFind(arr, (o) => (findTimes++, 3 - o.item.id))).toEqual({ id: 3, text: '3' }); + expect(binaryFind(arr, (o) => (findTimes++, 3 - o.item.id))).toEqual({ text: '3', id: 3 }); expect(findTimes).toBe(3); findTimes = 0; - expect(binaryFind(arr, (o) => (findTimes++, 2 - o.item.id))).toEqual({ id: 2, text: '2' }); + expect(binaryFind(arr, (o) => (findTimes++, 2 - o.item.id))).toEqual({ text: '2', id: 2 }); expect(findTimes).toBe(2); findTimes = 0; - expect(binaryFind(arr, (o) => (findTimes++, 6 - o.item.id))).toEqual({ id: 6, text: '6' }); + expect(binaryFind(arr, (o) => (findTimes++, 6 - o.item.id))).toEqual({ text: '6', id: 6 }); expect(findTimes).toBe(2); findTimes = 0; @@ -378,7 +382,7 @@ describe('array', function () { const a2: number[] = []; expect( - insertToArray(3, ({ item, insert }) => (a2.push(item), item < insert), arr7, { + insertToArray(3, ({ insert, item }) => (a2.push(item), item < insert), arr7, { reverse: true, after: true, }), @@ -446,7 +450,7 @@ describe('array', function () { // 恢复 arr = [1, 2, 3, 2]; // 反向查找 - expect(insertToArray(5, (o) => o.item === 2, arr, { after: false, reverse: true })).toBe(3); + expect(insertToArray(5, (o) => o.item === 2, arr, { reverse: true, after: false })).toBe(3); expect(arr).toEqual([1, 2, 3, 5, 2]); // 插入多个个 动态位置 @@ -500,7 +504,7 @@ describe('array', function () { expect(chunk([0, 1, 2, 3, 4, 5, 6], 1)).toEqual([[0], [1], [2], [3], [4], [5], [6]]); expect(chunk([0, 1, 2, 3, 4, 5, 6], 0)).toEqual([0, 1, 2, 3, 4, 5, 6]); // 不支持-1 - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error expect(chunk([0, 1, 2, 3, 4, 5, 6], -1)).toEqual([0, 1, 2, 3, 4, 5, 6]); expect(chunk([0, 1, 2, 3, 4, 5, 6], 3)).toEqual([[0, 1, 2], [3, 4, 5], [6]]); @@ -536,6 +540,7 @@ describe('array', function () { expect(inRange(0, [0])).toBe(true); expect(inRange(0, [1])).toBe(false); expect(inRange(0, [1, 2])).toBe(false); + expect(inRange(NaN, [0])).toBe(false); }); test('inRanges', () => { expect(inRanges(0, [undefined as any, 100])).toBe(true); @@ -555,28 +560,32 @@ describe('array', function () { 1: [{ type: 1 }], 2: [{ type: 2 }], }); + expect(groupBy({ 0: { type: 1 }, 1: { type: 2 }, length: 2 }, 'type')).toEqual({ + 1: [{ type: 1 }], + 2: [{ type: 2 }], + }); expect( groupBy( [ - { type: 1, value: 111 }, - { type: 2, value: 222 }, - { type: 1, value: 222 }, - { type: 2, value: 33344 }, - { type: 1, value: 333 }, - { type: 1, value: 444 }, + { value: 111, type: 1 }, + { value: 222, type: 2 }, + { value: 222, type: 1 }, + { value: 33344, type: 2 }, + { value: 333, type: 1 }, + { value: 444, type: 1 }, ], 'type', ), ).toEqual({ 1: [ - { type: 1, value: 111 }, - { type: 1, value: 222 }, - { type: 1, value: 333 }, - { type: 1, value: 444 }, + { value: 111, type: 1 }, + { value: 222, type: 1 }, + { value: 333, type: 1 }, + { value: 444, type: 1 }, ], 2: [ - { type: 2, value: 222 }, - { type: 2, value: 33344 }, + { value: 222, type: 2 }, + { value: 33344, type: 2 }, ], }); expect(groupBy([], '')).toEqual({}); @@ -595,6 +604,18 @@ describe('array', function () { other: [{ value: 2 }], 1: [{ type: 1 }], }); + const a = groupBy([{ a: 50 }, { a: 90 }, { a: 70 }], 'a'); + expect([a['*'], a['50'], a['70'], a['90']]).toEqual([ + undefined, + [{ a: 50 }], + [{ a: 70 }], + [{ a: 90 }], + ]); + // 测试体操获取属性是否报错 + // @ts-expect-error + expect(a['**']).toBe(undefined); + // @ts-expect-error + expect(a['1']).toBe(undefined); // cb expect( @@ -604,7 +625,7 @@ describe('array', function () { { name: 'b', score: 90 }, { name: 'c', score: 70 }, { name: 'd', score: 10 }, - { name: 'e', score: 100 }, + { score: 100, name: 'e' }, ], (item) => { const score = item.score; @@ -616,13 +637,59 @@ describe('array', function () { ).toEqual({ A: [ { name: 'b', score: 90 }, - { name: 'e', score: 100 }, + { score: 100, name: 'e' }, ], - B: [{ name: 'c', score: 70 }], C: [ { name: 'a', score: 50 }, { name: 'd', score: 10 }, ], + B: [{ name: 'c', score: 70 }], + }); + + const b = groupBy([50, 90, 70, 10, 100], (score) => { + if (score >= 90) return 'A'; + if (score >= 60) return 'B'; + return 'C'; + }); + expect([b['*'], b.A, b.B, b.C]).toEqual([undefined, [90, 100], [70], [50, 10]]); + + const c = groupBy( + [50, 90, 70, 10, 100], + (score): void | 'A' | 'B' => { + if (score >= 90) return 'A'; + if (score >= 60) return 'B'; + }, + 'C', + ); + expect([c.A, c.B, c.C]).toEqual([[90, 100], [70], [50, 10]]); + // C 替代了 * + // @ts-expect-error + expect(c['*']).toBe(undefined); + + expect( + groupBy([50, 90, 70, 10, 100], (score) => { + if (score >= 90) return 'A'; + if (score >= 60) return 'B'; + return 'C'; + }), + ).toEqual({ + A: [90, 100], + C: [50, 10], + B: [70], + }); + expect( + groupBy( + [50, 90, 70, 10, 100], + (score): string | void => { + if (score >= 90) return 'A'; + if (score >= 60) return 'B'; + }, + 'C', + ), + ).toEqual({ + A: [90, 100], + C: [50, 10], + B: [70], }); const list = [ @@ -772,7 +839,7 @@ describe('array', function () { res.push(v); if (i[0] === 0 && i[1] === 0) return false; }, - { startIndexes: [1, 4], startDirect: 'bottom' }, + { startDirect: 'bottom', startIndexes: [1, 4] }, ); expect(res).toEqual([10, 15, 20, 25, 24, 23, 22, 21, 16, 11, 6, 1]); @@ -803,4 +870,38 @@ describe('array', function () { forEachAround([], (v: any) => res.push(v), { startIndexes: [10, 10], startDirect: 'bottom' }); expect(JSON.stringify(res)).toBe('[]'); }); + + test('joinArray', () => { + expect(joinArray([1, 2, 3], 0)).toEqual([1, 0, 2, 0, 3]); + expect(joinArray([1], 0)).toEqual([1]); + expect(joinArray([1, 2], 0)).toEqual([1, 0, 2]); + expect(joinArray([1, 2, 3], 'a')).toEqual([1, 'a', 2, 'a', 3]); + expect(joinArray([1, 2, 3], 0, (it) => it + 10)).toEqual([11, 0, 12, 0, 13]); + expect(joinArray([1, 2, 3], 0, (it, i) => it + i)).toEqual([1, 0, 4, 0, 7]); + + // fn + expect(joinArray([1, 2, 3], (i) => i + 10)).toEqual([1, 11, 2, 13, 3]); + expect( + // @ts-expect-error + joinArray([1, 2, 3], (i) => i + '10'), + ).toEqual([1, '110', 2, '310', 3]); + expect(joinArray([1, 2, 3], (i) => i + '10')).toEqual([1, '110', 2, '310', 3]); + expect( + joinArray( + [1, 2, 3], + (i) => i + 10, + (it) => it + 100, + ), + ).toEqual([101, 11, 102, 13, 103]); + expect( + joinArray( + [1, 2, 3], + (it) => it + 10, + (it, i) => it + i, + ), + ).toEqual([1, 11, 4, 13, 7]); + + // edge + expect(joinArray([], 0)).toEqual([]); + }); }); diff --git a/__tests__/base64.test.ts b/__tests__/base64.test.ts new file mode 100644 index 00000000..3122b7ec --- /dev/null +++ b/__tests__/base64.test.ts @@ -0,0 +1,33 @@ +import { + arrayBufferToBase64, + base64ToArrayBuffer, + stringToArrayBuffer, + arrayBufferToString, + parseBase64, +} from '../src'; + +describe('Base64', () => { + test('parseBase64', () => { + // { hello: 'world' } + const p = parseBase64('data:application/json;base64,ewogICJoZWxsbyI6ICJ3b3JsZCIKfQ=='); + expect(p.mime).toBe('application/json'); + expect(String.fromCodePoint(...p.uint8Array)).toBe('{\n "hello": "world"\n}'); + + const p2 = parseBase64('ewogICJoZWxsbyI6ICJ3b3JsZCIKfQ=='); + expect(p2.mime).toBe(''); + expect(String.fromCodePoint(...p2.uint8Array)).toBe('{\n "hello": "world"\n}'); + expect(arrayBufferToString(p2.uint8Array, 8)).toBe('{\n "hello": "world"\n}'); + }); + + test('arrayBufferToBase64', () => { + const str = JSON.stringify({ hello: 'world' }, null, 2); + const buffer = stringToArrayBuffer(str, 8); + expect(arrayBufferToBase64(buffer)).toBe('ewogICJoZWxsbyI6ICJ3b3JsZCIKfQ=='); + }); + + test('base64ToArrayBuffer', () => { + const base64 = 'data:application/json;base64,ewogICJoZWxsbyI6ICJ3b3JsZCIKfQ=='; + const buffer = base64ToArrayBuffer(base64); + expect(arrayBufferToBase64(buffer)).toBe(base64.split(',')[1]); + }); +}); diff --git a/__tests__/bezier.html b/__tests__/bezier.html index 01643c45..ac8b64b5 100644 --- a/__tests__/bezier.html +++ b/__tests__/bezier.html @@ -1,4 +1,4 @@ - + diff --git a/__tests__/bezier.test.ts b/__tests__/bezier.test.ts index 9b2d1380..36101837 100644 --- a/__tests__/bezier.test.ts +++ b/__tests__/bezier.test.ts @@ -1,5 +1,5 @@ +import { useCubicBezier3, pointBezier3, pointBezier2, pointBezierN } from '../src/bezier'; import { createArray } from '../src'; -import { pointBezier3, useCubicBezier3, pointBezier2, pointBezierN } from '../src/bezier'; describe('bezier', function () { test('useCubicBezier3', () => { @@ -7,8 +7,8 @@ describe('bezier', function () { const c1 = useCubicBezier3(0, 600, 'ease-in-out'); let list = createArray({ - len: len + 1, fill: (i) => c1(i / len), + len: len + 1, }); expect(list).toEqual([ @@ -19,8 +19,8 @@ describe('bezier', function () { const c2 = useCubicBezier3(0, 600); list = createArray({ - len: len + 1, fill: (i) => c2(i / len), + len: len + 1, }); expect(list).toEqual([ @@ -33,8 +33,8 @@ describe('bezier', function () { // 反向生成,没有太好的方法检验是否准确 const c3 = useCubicBezier3(600, 0, 'ease-in-out'); const list2 = createArray({ - len: len + 1, fill: (i) => c3(i / len), + len: len + 1, }); expect(list2).toEqual([ @@ -58,9 +58,9 @@ describe('bezier', function () { ]; test('pointBezier2', () => { const bezierList = createArray({ + fill: (i) => pointBezier2(i / 10, [1, 1], [10, 10], [10, 10]), start: 0, end: 11, - fill: (i) => pointBezier2(i / 10, [1, 1], [10, 10], [10, 10]), }); expect(bezierList).toEqual(b2Res); @@ -80,9 +80,9 @@ describe('bezier', function () { ]; test('pointBezier3', () => { const bezierList = createArray({ + fill: (i) => pointBezier3(i / 10, [1, 1], [2, 2], [8, 8], [10, 10]), start: 0, end: 11, - fill: (i) => pointBezier3(i / 10, [1, 1], [2, 2], [8, 8], [10, 10]), }); expect(bezierList).toEqual(b3Res); @@ -90,27 +90,27 @@ describe('bezier', function () { test('pointBezierN', () => { // 2阶 const bezierList2 = createArray({ + fill: (i) => pointBezierN(i / 10, [1, 1], [10, 10], [10, 10]), start: 0, end: 11, - fill: (i) => pointBezierN(i / 10, [1, 1], [10, 10], [10, 10]), }); expect(bezierList2).toEqual(b2Res); // 3阶 const bezierList3 = createArray({ + fill: (i) => pointBezierN(i / 10, [1, 1], [2, 2], [8, 8], [10, 10]), start: 0, end: 11, - fill: (i) => pointBezierN(i / 10, [1, 1], [2, 2], [8, 8], [10, 10]), }); expect(bezierList3).toEqual(b3Res); // 4阶 const bezierList5 = createArray({ + fill: (i) => pointBezierN(i / 10, [1, 1], [2, 2], [5, 5], [8, 8], [10, 10]), start: 0, end: 11, - fill: (i) => pointBezierN(i / 10, [1, 1], [2, 2], [5, 5], [8, 8], [10, 10]), }); expect(bezierList5).toEqual([ diff --git a/__tests__/clone.test.ts b/__tests__/clone.test.ts index f8f14298..2e11891c 100644 --- a/__tests__/clone.test.ts +++ b/__tests__/clone.test.ts @@ -1,4 +1,4 @@ -import { cloneFunction, deepClone, deepCloneBfs } from '../src/clone'; +import { cloneFunction, deepCloneBfs, deepClone } from '../src/clone'; import { hasOwn } from '../src/object'; describe('clone', function () { @@ -28,16 +28,16 @@ describe('clone', function () { // 复制对象方法 const obj: any = { - a: 1, - b: 1, - c: 1, + fn3: function () { + return ++this.c; + }, fn1() { return ++this.a; }, fn2: () => ++obj.b, - fn3: function () { - return ++this.c; - }, + a: 1, + b: 1, + c: 1, }; obj.clone1 = cloneFunction(obj.fn1); expect(obj.fn1()).toBe(2); @@ -78,7 +78,7 @@ describe('clone', function () { // copy !== arr expect(arr === newArr).toBe(false); - const obj = { a: [2, 3], c: 1, d: { f: 123 } }; + const obj = { d: { f: 123 }, a: [2, 3], c: 1 }; const newObj = deepClone(obj); // copy == obj expect(newObj).toEqual(obj); @@ -118,8 +118,8 @@ describe('clone', function () { Foo.prototype.sayGoodBy = function () { console.log('Say Good By'); }; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + + // @ts-expect-error const myPro = new Foo(); expect(hasOwn(myPro, 'name')).toBeTruthy(); //true expect(hasOwn(myPro, 'toString')).toBe(false); //false @@ -161,7 +161,7 @@ describe('clone', function () { expect(o2.re.test('123')).toBe(true); expect(o2.re === re).toBe(false); - const o3: any = { a: 1, b: 2, c: 3, e: { a: 1 } }; + const o3: any = { e: { a: 1 }, a: 1, b: 2, c: 3 }; o3.d = o3; const c = deepClone(o3); expect(c).toEqual(o3); @@ -177,7 +177,7 @@ describe('clone', function () { expect(nObj.c).toEqual(3); expect(nObj === obj10086).toBe(false); - const obj10000 = { a: 1, b: { c: '123' } }; + const obj10000 = { b: { c: '123' }, a: 1 }; const nObj2 = deepCloneBfs(obj10000); expect(nObj2).toEqual(obj10000); @@ -188,7 +188,7 @@ describe('clone', function () { // copy !== arr expect(arr === newArr).toBe(false); - const obj = { a: [2, 3], c: 1, d: { f: 123 } }; + const obj = { d: { f: 123 }, a: [2, 3], c: 1 }; const newObj = deepCloneBfs(obj); // copy == obj expect(newObj).toEqual(obj); @@ -208,15 +208,14 @@ describe('clone', function () { Ext.prototype.b = '2'; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error expect(deepCloneBfs(new Ext())).toEqual({ a: 1 }); - const obj2 = { a: 1, b: [1, 2] }; - expect(deepCloneBfs(obj2)).toEqual({ a: 1, b: [1, 2] }); + const obj2 = { b: [1, 2], a: 1 }; + expect(deepCloneBfs(obj2)).toEqual({ b: [1, 2], a: 1 }); expect(obj2 !== deepCloneBfs(obj2)).toBeTruthy(); - const obj3 = { a: null, b: undefined, c: NaN }; - expect(deepCloneBfs(obj3)).toEqual({ a: null, b: undefined, c: NaN }); + const obj3 = { b: undefined, a: null, c: NaN }; + expect(deepCloneBfs(obj3)).toEqual({ b: undefined, a: null, c: NaN }); }); }); diff --git a/__tests__/color/RGB.test.ts b/__tests__/color/RGB.test.ts index 5e93f4ea..21522888 100644 --- a/__tests__/color/RGB.test.ts +++ b/__tests__/color/RGB.test.ts @@ -1,11 +1,11 @@ -import { RGB } from '../../src/color/RGB'; -import { isRGBColor, isHEXColor } from '../../src/color/color'; +import { isRGBColor, isHEXColor } from '../../src/color/base'; import { createArray, unique } from '../../src/array'; +import { RGB } from '../../src/color/RGB'; describe('RGB', function () { const rgb = new RGB(); const rgb2 = new RGB(255, 0, 1); - const rgbList = createArray({ len: 200, fill: RGB.random }); + const rgbList = createArray({ fill: RGB.random, len: 200 }); test('RGB.toString', () => { expect(rgb.toString()).toBe('rgb(0,0,0)'); expect(rgb2.toString()).toBe('rgb(255,0,1)'); diff --git a/__tests__/color/RGBA.test.ts b/__tests__/color/RGBA.test.ts index 4be1ec0e..d2d0da39 100644 --- a/__tests__/color/RGBA.test.ts +++ b/__tests__/color/RGBA.test.ts @@ -1,11 +1,11 @@ -import { RGBA } from '../../src/color/RGBA'; -import { isRGBColor, isHEXColor } from '../../src/color/color'; +import { isRGBColor, isHEXColor } from '../../src/color/base'; import { createArray, unique } from '../../src/array'; +import { RGBA } from '../../src/color/RGBA'; describe('RGBA', function () { const rgb = new RGBA(); const rgb2 = new RGBA(255, 0, 1); - const rgbList = createArray({ len: 200, fill: RGBA.random }); + const rgbList = createArray({ fill: RGBA.random, len: 200 }); test('RGBA.toString', () => { expect(rgb.toString()).toBe('rgba(0,0,0,1)'); expect(rgb2.toString()).toBe('rgba(255,0,1,1)'); diff --git a/__tests__/color/color.test.ts b/__tests__/color/color.test.ts index 84a58b06..9cdfb0c4 100644 --- a/__tests__/color/color.test.ts +++ b/__tests__/color/color.test.ts @@ -1,5 +1,5 @@ -import * as color from '../../src/color/color'; import { randomColor } from '../../src/random'; +import * as color from '../../src/color/base'; describe('color', function () { test('isRGBColor', () => { diff --git a/__tests__/common.test.ts b/__tests__/common.test.ts index 8157ecbc..0642d4cb 100644 --- a/__tests__/common.test.ts +++ b/__tests__/common.test.ts @@ -1,6 +1,5 @@ +import { inRange, sleep, avg } from '../src'; import * as cm from '../src/common'; -import { avg } from '../src'; -import { inRange } from '@mxssfd/core'; describe('common', function () { jest.useFakeTimers(); @@ -180,7 +179,7 @@ describe('common', function () { test('polling', async () => { let t = 0; - let { cancel, promise } = cm.polling((times) => { + let { promise, cancel } = cm.polling((times) => { t = times; if (times === 10) cancel(); }, 10); @@ -191,7 +190,7 @@ describe('common', function () { t = 0; jest.useRealTimers(); - ({ cancel, promise } = cm.polling( + ({ promise, cancel } = cm.polling( (times) => { return new Promise((res) => { t++; @@ -231,7 +230,7 @@ describe('common', function () { // object expect(createEnum({ a: 'aa', b: 'bb' })).toEqual({ a: 'aa', b: 'bb', aa: 'a', bb: 'b' }); - expect(createEnum({ a: 1, b: 2 })).toEqual({ a: 1, b: 2, 1: 'a', 2: 'b' }); + expect(createEnum({ a: 1, b: 2 })).toEqual({ 1: 'a', 2: 'b', a: 1, b: 2 }); // array expect(createEnum([0, 1])).toEqual({ '0': '0', '1': '1' }); @@ -241,6 +240,13 @@ describe('common', function () { test('throttle', async () => { // expect.assertions(33); const throttle = cm.throttle; + + const fn = jest.fn(); + const cb = throttle((value: number) => fn(value), 1, { leading: true }); + cb(1); + expect(fn).toHaveBeenCalled(); + expect(fn.mock.calls).toEqual([[1]]); + let times = 0; let invalidTimes = 0; let interval = 0; @@ -363,7 +369,7 @@ describe('common', function () { const fn = jest.fn(); const invFn = jest.fn(); // invalidCB - const wrapFn = cm.throttle(fn, 100, { leading: false, invalidCB: invFn }); + const wrapFn = cm.throttle(fn, 100, { invalidCB: invFn, leading: false }); // 初始时时0次 expect(fn.mock.calls.length).toBe(0); // 执行一次 @@ -441,7 +447,7 @@ describe('common', function () { }; // 禁止Function - // eslint-disable-next-line no-global-assign + Function = jest.fn(() => { throw new Error(''); }); @@ -449,7 +455,6 @@ describe('common', function () { // globalThis expect(cm.getRoot()).toBe(globalThis); - // eslint-disable-next-line no-global-assign Function = origin.fn; }); @@ -470,61 +475,214 @@ describe('common', function () { expect(pcp('node test.js test.js -a=123')).toEqual({ default: 'test.js', a: '123' }); expect(pcp('node test.js test.js -a=123 333 555 -b 666 888 -c=1 -b=999')).toEqual({ - default: 'test.js', a: ['123', '333', '555'], b: ['666', '888', '999'], + default: 'test.js', c: '1', }); expect(pcp('node test.js test.js -a=123=333=444=555')).toEqual({ - default: 'test.js', a: '123=333=444=555', + default: 'test.js', }); expect(pcp('node test.js test.js -a= ')).toEqual({ default: 'test.js', a: true }); expect(pcp('node test.js test.js -a= -b=123')).toEqual({ default: 'test.js', - a: true, b: '123', + a: true, }); expect(pcp('node test.js test.js -a==123=333=444=555')).toEqual({ - default: 'test.js', a: '=123=333=444=555', + default: 'test.js', }); expect(pcp('node test.js test.js --a==123=333=444=555', '--', 'args')).toEqual({ - args: 'test.js', a: '=123=333=444=555', + args: 'test.js', }); }); - test('formatBytes', () => { - const formatBytes = cm.formatBytes; - - expect(formatBytes(0)).toBe('0B'); - expect(formatBytes(1)).toBe('1B'); - expect(formatBytes(-1)).toBe('-1B'); - - expect(formatBytes(1024)).toBe('1KB'); - expect(formatBytes(1024 * 1024)).toBe('1MB'); - expect(formatBytes(1024 * 1024 * 1024)).toBe('1GB'); - expect(formatBytes(1024 * 1024 * 1024 * 1024)).toBe('1TB'); - expect(formatBytes(1024 * 1024 * 1024 * 1024 * 1024)).toBe('1PB'); - expect(formatBytes(1024 ** 6)).toBe('1EB'); - expect(formatBytes(1024 ** 7)).toBe('1ZB'); - expect(formatBytes(1024 ** 8)).toBe('1YB'); - - expect(formatBytes(1024 * 512 + 1000)).toBe('512.98KB'); - - // 指定单位 - expect(formatBytes(1024 * 512, { unit: 'MB' })).toBe('0.5MB'); - expect(formatBytes(1024 * 512, { unit: 'GB' })).toBe('0GB'); - // 指定小数位 - expect(formatBytes(1024 * 512, { unit: 'GB', fractionDigits: 5 })).toBe('0.00049GB'); - expect(formatBytes(1, { unit: 'GB', fractionDigits: 9 })).toBe('0.000000001GB'); - // 使用科学计数法 - expect(formatBytes(1, { unit: 'GB', fractionDigits: 9, exponential: true })).toBe('1e-9GB'); + test('loadingElse', async () => { + jest.useRealTimers(); + const loadingElse = cm.loadingElse; + + const fn = jest.fn(); + const cb = loadingElse(fn); + + cb(); + cb(); + cb(); + cb(); + cb(); + + expect(fn.mock.calls.length).toBe(5); + + fn.mock.calls.length = 0; + + const cb2 = loadingElse(() => sleep(10).then(fn)); + cb2(); + cb2(); + cb2(); + cb2(); + cb2(); + + await sleep(20); + expect(fn.mock.calls.length).toBe(1); + }); + describe('createEventBus', () => { + test('base', () => { + const eventBus = cm.createEventBus(); + const listener = jest.fn(); + eventBus.on(listener); + + expect(listener).not.toBeCalled(); + + eventBus.emit(1); + expect(listener).toBeCalled(); + expect(listener.mock.calls[0].length).toBe(2); + expect(listener.mock.calls[0][0]).toBe(1); + expect(typeof listener.mock.calls[0][1]).toBe('function'); + }); + test('off', () => { + const eventBus = cm.createEventBus(); + const listener = jest.fn(); + const listener2 = jest.fn((_, off) => off()) as typeof listener; + const off = eventBus.on(listener); + eventBus.on(listener2); + + expect(listener).not.toBeCalled(); + expect(listener2).not.toBeCalled(); + + eventBus.emit(1); + expect(listener.mock.calls[0][0]).toBe(1); + expect(listener2.mock.calls[0][0]).toBe(1); + + listener.mockClear(); + listener2.mockClear(); + eventBus.emit(2); + expect(listener.mock.calls[0][0]).toBe(2); + expect(listener2).not.toBeCalled(); + + listener.mockClear(); + listener2.mockClear(); + off(); + eventBus.emit(3); + expect(listener).not.toBeCalled(); + expect(listener2).not.toBeCalled(); + }); + test('foreach off', () => { + const eventBus = cm.createEventBus(); + const listeners = Array(10) + .fill(1) + .map(() => jest.fn((_, off) => off()) as jest.Mock); + listeners.forEach((l) => eventBus.on(l)); + + eventBus.emit(1); + expect(listeners.map((l) => l.mock.calls.length)).toEqual(Array(10).fill(1)); + expect(listeners.map((l) => l.mock.calls[0][0])).toEqual(Array(10).fill(1)); + + listeners.forEach((l) => l.mockClear()); + eventBus.emit(2); + expect(listeners.map((l) => l.mock.calls.length)).toEqual(Array(10).fill(0)); + }); + test('off next', () => { + const eventBus = cm.createEventBus(); + const listener = jest.fn(() => off()); + eventBus.on(listener); + const listener2 = jest.fn(); + const off = eventBus.on(listener2); + + eventBus.emit(1); + expect(listener).toBeCalled(); + expect(listener2).not.toBeCalled(); + }); + test('clear', () => { + const eventBus = cm.createEventBus(); + const listener = jest.fn(); + eventBus.on(listener); + + expect(listener).not.toBeCalled(); + eventBus.emit(1); + expect(listener).toBeCalled(); + + listener.mockClear(); + expect(listener).not.toBeCalled(); + eventBus.clear(); + eventBus.emit(2); + expect(listener).not.toBeCalled(); + }); + }); + describe('DynamicEnum', () => { + test('basic', () => { + const map = new Map([ + [1, 11], + [2, 22], + ]); + const de = new cm.DynamicEnum(map); + de.set(1, 111); + expect(map.get(1)).toBe(111); + expect(de.get(1)).toBe(111); + expect(de.size).toBe(2); + expect(map.size).toBe(2); + + de.setKeyByValue(111, 11); + expect(map.get(1)).toBeUndefined(); + expect(de.get(1)).toBeUndefined(); + expect(map.get(11)).toBe(111); + expect(de.getKeyByValue(111)).toBe(11); + + de.set(3, 33); + expect(map.get(3)).toBe(33); + expect(de.get(3)).toBe(33); + expect(map.size).toBe(3); + de.delete(3); + expect(map.get(3)).toBeUndefined(); + expect(de.get(3)).toBeUndefined(); + expect(map.size).toBe(2); + + de.deleteByValue(111); + expect(map.get(11)).toBeUndefined(); + expect(de.get(11)).toBeUndefined(); + expect(de.getKeyByValue(111)).toBeUndefined(); + expect(map.size).toBe(1); + + de.clear(); + expect(map.size).toBe(0); + }); + test('setOrSwap', () => { + const map = new Map([ + [1, 11], + [2, 22], + ]); + const de = new cm.DynamicEnum(map); + expect(map.get(1)).toBe(11); + expect(map.get(2)).toBe(22); + + de.setOrSwap(1, 22); + expect(map.get(1)).toBe(22); + expect(map.get(2)).toBe(11); + + de.setOrSwap(3, 33); + expect(map.get(1)).toBe(22); + expect(map.get(2)).toBe(11); + expect(map.get(3)).toBe(33); + }); + test('map', () => { + const map = new Map([ + [1, 11], + [2, 22], + ]); + const de = new cm.DynamicEnum(map); + expect(de.map((v, k) => k + v)).toEqual([12, 24]); + }); + test('createByObj', () => { + const de = cm.DynamicEnum.createByObj({ a: 1, b: 2, c: 3 }); + expect(de.size).toBe(3); + expect(de.get('a')).toBe(1); + expect(de.getKeyByValue(3)).toBe('c'); + }); }); }); diff --git a/__tests__/coordinate.test.ts b/__tests__/coordinate.test.ts index 39d24bd0..5e3c60cb 100644 --- a/__tests__/coordinate.test.ts +++ b/__tests__/coordinate.test.ts @@ -1,5 +1,5 @@ +import type { Point } from '@tool-pack/types'; import * as cd from '../src/coordinate'; -import { Point } from '@mxssfd/core'; describe('coordinate', function () { test('isPointInPath', () => { @@ -119,7 +119,7 @@ describe('coordinate', function () { test('getRotatePoint', () => { expect(cd.getRotatePoint([0, 0], Math.sqrt(2), 135)).toEqual([1, 1]); - const center: cd.Point = [1, 1]; + const center: Point = [1, 1]; const radius = 10; expect(cd.getRotatePoint(center, radius, 0)).toEqual([center[0], center[1] - radius]); expect(cd.getRotatePoint(center, radius, 90)).toEqual([center[0] + radius, center[1]]); diff --git a/__tests__/data-type.test.ts b/__tests__/data-type.test.ts index 11b36b57..bcef7c84 100644 --- a/__tests__/data-type.test.ts +++ b/__tests__/data-type.test.ts @@ -1,29 +1,33 @@ import { - isNative, - typeOf, - inTypes, - isArray, + isASCIIPunctuationSymbol, + includesChinese, + isEmptyObject, + isPromiseLike, + objectIsEqual, + isUnavailable, + isObjectLike, isArrayLike, + isUndefined, isArrayObj, - isBoolean, - isEmptyObject, - isEqual, isFunction, - includesChinese, - isInteger, isIterable, + isSameType, + isBoolean, + isInteger, + isPercent, + isNullish, + isNative, isNumber, isObject, - isPercent, - isPromiseLike, - isSameType, isString, - isUndefined, - objectIsEqual, - isNaN, + inTypes, + isArray, + isEqual, isEmpty, - isObjectLike, + typeOf, + isNaN, } from '../src'; +import { createArray } from '@mxssfd/core'; const cm = { polling: {} }; describe('data-type', function () { @@ -71,6 +75,17 @@ describe('data-type', function () { expect(typeof f === 'object').toBe(false); expect(isObject(f)).toBe(false); expect(isObject(function () {})).toBe(false); + + const o: any = { a: 1 }; + if (isObject(o)) { + // @ts-expect-error + o.a = 1; + } + if (isObject<{ a: string }>(o)) { + // @ts-expect-error + o.a = 1; + o.a = ''; + } }); test('isObjectLike', () => { expect(isObjectLike([1, 2, 3])).toBe(true); @@ -82,6 +97,17 @@ describe('data-type', function () { expect(isObjectLike(null)).toBe(false); expect(isObjectLike({})).toBe(true); expect(isObjectLike(() => {})).toBe(true); + + const o: any = { a: 1 }; + if (isObjectLike(o)) { + // @ts-expect-error + o.a = 1; + } + if (isObjectLike<{ a: string }>(o)) { + // @ts-expect-error + o.a = 1; + o.a = ''; + } }); test('isArray', () => { expect(Array.isArray(0.12345667)).toBe(false); @@ -93,8 +119,8 @@ describe('data-type', function () { expect(Array.isArray({})).toBe(false); expect(isArray({})).toBe(false); - expect(Array.isArray({ 0: 1, 1: 2, length: 2 })).toBe(false); - expect(isArray({ 0: 1, 1: 2, length: 2 })).toBe(false); + expect(Array.isArray({ length: 2, 0: 1, 1: 2 })).toBe(false); + expect(isArray({ length: 2, 0: 1, 1: 2 })).toBe(false); expect(Array.isArray(() => {})).toBe(false); expect(isArray(() => {})).toBe(false); @@ -119,6 +145,16 @@ describe('data-type', function () { expect(Array.isArray(document.getElementsByClassName('test'))).toBe(false); expect(isArray(document.getElementsByClassName('test'))).toBe(false); + + const arr: any = [1, 2]; + if (isArray(arr)) { + // @ts-expect-error + arr.push(3); + } + + if (isArray(arr)) { + arr.push(3); + } }); test('isArrayLike', () => { expect(isArrayLike([1, 2, 3])).toBe(true); @@ -134,6 +170,20 @@ describe('data-type', function () { expect(isArrayLike(null)).toBe(false); expect(isArrayLike({})).toBe(false); expect(isArrayLike(() => {})).toBe(false); + + const obj = { str: '', num: 1 }; + const a: unknown = 1; + if (isArrayLike(a)) { + // @ts-expect-error + obj.num = a[0]!; + obj.str = a[0]!; + } + + if (isArrayLike(a)) { + obj.num = a[0]!; + // @ts-expect-error + obj.str = a[0]!; + } }); test('isString', () => { expect(isString(123123)).toBe(false); @@ -143,7 +193,7 @@ describe('data-type', function () { test('isNumber', () => { expect(isNumber('')).toBe(false); expect(isNumber({})).toBe(false); - expect(isNumber({ 0: 1, 1: 2, length: 2 })).toBe(false); + expect(isNumber({ length: 2, 0: 1, 1: 2 })).toBe(false); expect(isNumber(() => {})).toBe(false); expect(isNumber(true)).toBe(false); expect(isNumber(undefined)).toBe(false); @@ -157,6 +207,30 @@ describe('data-type', function () { expect(isFunction('')).toBe(false); expect(isFunction(() => {})).toBe(true); expect(isFunction(function () {})).toBe(true); + + const f: any = (a: number) => a; + + if (isFunction<(a: string) => string>(f)) { + // @ts-expect-error + f(); + // @ts-expect-error + f(1); + f('123'); + } + if (isFunction<(a: number) => string>(f)) { + // @ts-expect-error + f(); + f(1); + // @ts-expect-error + f('123'); + } + + if ( + // @ts-expect-error + !isFunction(f) + ) { + console.log(f); + } }); test('isBoolean', () => { @@ -178,12 +252,11 @@ describe('data-type', function () { let a; expect(isUndefined(a)).toBe(true); expect(() => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error expect(isUndefined(b)).toBe(true); }).toThrow(); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + + // @ts-expect-error expect(typeof b).toBe('undefined'); }); test('isNaN', () => { @@ -284,7 +357,7 @@ describe('data-type', function () { expect(isEqual(false, undefined)).toBe(false); expect(isEqual(false, null)).toBe(false); expect(isEqual(false, true)).toBe(false); - expect(isEqual([1, 2], { 0: 1, 1: 2, length: 2 })).toBe(false); + expect(isEqual([1, 2], { length: 2, 0: 1, 1: 2 })).toBe(false); expect( isEqual( () => {}, @@ -327,6 +400,18 @@ describe('data-type', function () { expect(isIterable([0, 1])).toBe(true); expect(isIterable(new Map())).toBe(true); expect(isIterable(new Set())).toBe(true); + + // 类型守卫 + const a = { str: '', num: 1 }; + const set: unknown = 1; + if (isIterable(set)) { + // 1不可能是迭代器,所以该条件内的不会执行 + for (const v of set) { + a.num = v; + // @ts-expect-error + a.str = v; + } + } }); test('isPercent', function () { @@ -376,8 +461,61 @@ describe('data-type', function () { test('isArrayObj', function () { expect(isArrayObj(Object.assign([1, 2], { b: '1', c: '2' }))).toBe(true); expect(isArrayObj([])).toBe(false); - expect(isArrayObj({ 0: 1, 1: 2, length: 2, a: 1, b: 2 })).toBe(false); + expect(isArrayObj({ length: 2, 0: 1, 1: 2, a: 1, b: 2 })).toBe(false); expect(isArrayObj(document.querySelectorAll('.test'))).toBe(false); expect(isArrayObj(document.getElementsByClassName('test'))).toBe(false); }); + test('isUnavailable', function () { + expect(isUnavailable(null)).toBe(true); + expect(isUnavailable(undefined)).toBe(true); + expect(isUnavailable(NaN)).toBe(true); + expect(isUnavailable(1)).toBe(false); + expect(isUnavailable(0)).toBe(false); + expect(isUnavailable(false)).toBe(false); + expect(isUnavailable('')).toBe(false); + }); + test('isNullish', function () { + expect(isNullish(null)).toBe(true); + expect(isNullish(undefined)).toBe(true); + expect(isNullish(NaN)).toBe(false); + expect(isNullish(1)).toBe(false); + expect(isNullish(0)).toBe(false); + expect(isNullish(false)).toBe(false); + expect(isNullish('')).toBe(false); + expect(isNullish({})).toBe(false); + }); + test('isASCIIPunctuationSymbol', function () { + expect.assertions(108); + + const createCharList = (start: string, end: string): string[] => { + return createArray({ + fill: (c) => String.fromCharCode(c), + start: start.charCodeAt(0), + end: end.charCodeAt(0) + 1, + }); + }; + + expect(isASCIIPunctuationSymbol('')).toBe(false); + expect(isASCIIPunctuationSymbol('嘿')).toBe(false); + expect(isASCIIPunctuationSymbol('(')).toBe(false); + expect(isASCIIPunctuationSymbol('&&&&*%$#')).toBe(true); + expect(isASCIIPunctuationSymbol('87sdfs$#')).toBe(false); + + // 空格加上字符是95个字符 + const list = [ + [[' '], ' ', false], + [createCharList('a', 'z'), 'abcdefghijklmnopqrstuvwxyz', false], + [createCharList('A', 'Z'), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', false], + [createCharList('0', '9'), '0123456789', false], + [createCharList('!', '/'), '!"#$%&\'()*+,-./', true], + [createCharList(':', '@'), ':;<=>?@', true], + [createCharList('[', '`'), '[\\]^_`', true], + [createCharList('{', '~'), '{|}~', true], + ] as const; + + list.forEach(([arr, join, value]) => { + expect(arr.join('')).toBe(join); + arr.forEach((v) => expect(isASCIIPunctuationSymbol(v)).toBe(value)); + }); + }); }); diff --git a/__tests__/decorator.test.ts b/__tests__/decorator.test.ts index 9822fd6c..03e6c974 100644 --- a/__tests__/decorator.test.ts +++ b/__tests__/decorator.test.ts @@ -4,15 +4,15 @@ import * as dc from '../src/decorator'; describe('decorator', function () { test('Debounce', async () => { expect.assertions(3); - // eslint-disable-next-line @typescript-eslint/no-unused-vars + const Debounce = dc.Debounce; const now = Date.now(); class Test { + value: string | number = ''; times = 0; time = 0; - value: string | number = ''; @Debounce(1000) test(value: string | number) { @@ -39,15 +39,15 @@ describe('decorator', function () { }); test('Throttle', async () => { expect.assertions(2); - // eslint-disable-next-line @typescript-eslint/no-unused-vars + const Throttle = dc.Throttle; // const now = Date.now(); class Test { + value: string | number = ''; times = 0; time = 0; - value: string | number = ''; @Throttle(100) test(value: string | number) { @@ -75,7 +75,7 @@ describe('decorator', function () { test('Polling', async () => { expect.assertions(1); - // eslint-disable-next-line @typescript-eslint/no-unused-vars + const Polling = dc.Polling; class Test { @@ -103,7 +103,7 @@ describe('decorator', function () { }); test('Polling 2', async () => { expect.assertions(2); - // eslint-disable-next-line @typescript-eslint/no-unused-vars + const Polling = dc.Polling; class Test { diff --git a/__tests__/generator.test.ts b/__tests__/generator.test.ts index 3b91e199..2d3f6cf5 100644 --- a/__tests__/generator.test.ts +++ b/__tests__/generator.test.ts @@ -1,8 +1,8 @@ import { - createTimeCountUpGen, - idGen, createTimeCountDownGen, + createTimeCountUpGen, randomItemGen, + idGen, } from '../src/generator'; describe('generator', function () { jest.useFakeTimers(); @@ -54,7 +54,7 @@ describe('generator', function () { } expect(ids).toEqual([0, 1, 2]); - expect(gen.next()).toEqual({ done: true, value: undefined }); + expect(gen.next()).toEqual({ value: undefined, done: true }); }); test('倒序生成', () => { @@ -65,7 +65,7 @@ describe('generator', function () { } expect(ids).toEqual([0, 1, 2].reverse()); - expect(gen.next()).toEqual({ done: true, value: undefined }); + expect(gen.next()).toEqual({ value: undefined, done: true }); }); test('转成数组', () => { expect([...idGen(0, 1, 3)]).toEqual([0, 1, 2]); @@ -104,7 +104,7 @@ describe('generator', function () { // 停止 t.return(); - expect(t.next()).toEqual({ done: true, value: undefined }); + expect(t.next()).toEqual({ value: undefined, done: true }); // return 不接收任何参数 // @ts-expect-error @@ -154,7 +154,7 @@ describe('generator', function () { const list = [1, 2, 3, 4, 5]; const g = randomItemGen(list); const res = list.map(() => g.next().value); - expect(g.next()).toEqual({ done: true, value: undefined }); + expect(g.next()).toEqual({ value: undefined, done: true }); expect(list.every((it) => res.includes(it))).toBeTruthy(); expect(res).not.toEqual(list); expect(res.sort()).toEqual(list); @@ -163,6 +163,6 @@ describe('generator', function () { expectInRange(rand.next().value, [1, 3]); // 1|2|3 expectInRange(rand.next().value, [1, 3]); // 1|2|3 expectInRange(rand.next().value, [1, 3]); // 1|2|3 - expect(rand.next()).toEqual({ done: true, value: undefined }); + expect(rand.next()).toEqual({ value: undefined, done: true }); }); }); diff --git a/__tests__/get-angle.html b/__tests__/get-angle.html index 75d21a2c..1d1e4fbb 100644 --- a/__tests__/get-angle.html +++ b/__tests__/get-angle.html @@ -1,4 +1,4 @@ - + diff --git a/__tests__/number.test.ts b/__tests__/number.test.ts index 3aaaf51a..5d4686fe 100644 --- a/__tests__/number.test.ts +++ b/__tests__/number.test.ts @@ -1,20 +1,20 @@ +import type { Tuple } from '@tool-pack/types'; import * as Num from '../src/number'; -import { Tuple } from '@tool-pack/types'; const { - strip, getNumberLenAfterDot, - getCommonPow, toNonExponential, - getSafeNum, - plus, - minus, - times, - divide, - numToFixed, - forEachNum, forEachNumRight, numberToChinese, chineseToNumber, + getCommonPow, + getSafeNum, + numToFixed, + forEachNum, + divide, + strip, + minus, + times, + plus, } = Num; describe('number', function () { test('strip', () => { @@ -30,12 +30,11 @@ describe('number', function () { expect(0.09999999999999998).toBe(0.09999999999999998); expect(strip(0.09999999999999998)).toBe(0.1); - // eslint-disable-next-line @typescript-eslint/no-loss-of-precision expect(strip(20000000000.222222222)).not.toBe(20000000000.222222222); - // eslint-disable-next-line @typescript-eslint/no-loss-of-precision + expect(20000000000.222222222).toBe(20000000000.222222222); // 不够精准,js无法表示那么长的数据,或许改考虑用bigint - // eslint-disable-next-line @typescript-eslint/no-loss-of-precision + expect((20000000000.222222222).toString()).toBe('20000000000.22222'); }); test('getNumberLenAfterDot', () => { @@ -159,7 +158,7 @@ describe('number', function () { expect(arr).toEqual([0, 1, 2]); forEachNum(7, (index) => arr.push(index)); expect(arr.length).toEqual(10); - forEachNum(3, (index): void | false => { + forEachNum(3, (index): false | void => { arr.push(index); if (index === 1) return false; }); @@ -171,7 +170,7 @@ describe('number', function () { expect(arr).toEqual([0, 1, 2].reverse()); forEachNumRight(7, (index) => arr.push(index)); expect(arr.length).toEqual(10); - forEachNumRight(3, (index): void | false => { + forEachNumRight(3, (index): false | void => { arr.push(index); if (index === 1) return false; }); @@ -221,4 +220,94 @@ describe('number', function () { 123456789, ); }); + + test('formatBytes', () => { + const formatBytes = Num.formatBytes; + + expect(formatBytes(0)).toBe('0B'); + expect(formatBytes(1)).toBe('1B'); + expect(formatBytes(-1)).toBe('-1B'); + + expect(formatBytes(1024)).toBe('1KB'); + expect(formatBytes(1024 * 1024)).toBe('1MB'); + expect(formatBytes(1024 * 1024 * 1024)).toBe('1GB'); + expect(formatBytes(1024 * 1024 * 1024 * 1024)).toBe('1TB'); + expect(formatBytes(1024 * 1024 * 1024 * 1024 * 1024)).toBe('1PB'); + expect(formatBytes(1024 ** 6)).toBe('1EB'); + expect(formatBytes(1024 ** 7)).toBe('1ZB'); + expect(formatBytes(1024 ** 8)).toBe('1YB'); + + expect(formatBytes(1024 * 512 + 1000)).toBe('512.98KB'); + + // 指定单位 + expect(formatBytes(1024 * 512, { unit: 'MB' })).toBe('0.5MB'); + expect(formatBytes(1024 * 512, { unit: 'GB' })).toBe('0GB'); + // 指定小数位 + expect(formatBytes(1024 * 512, { fractionDigits: 5, unit: 'GB' })).toBe('0.00049GB'); + expect(formatBytes(1, { fractionDigits: 9, unit: 'GB' })).toBe('0.000000001GB'); + // 使用科学计数法 + expect(formatBytes(1, { fractionDigits: 9, exponential: true, unit: 'GB' })).toBe('1e-9GB'); + }); + test('shortenNumber', () => { + const fn = Num.shortenNumber; + const k = 1000; + expect(fn(0)).toBe('0'); + expect(fn(1)).toBe('1'); + expect(fn(-1)).toBe('-1'); + + expect(fn(k)).toBe('1K'); + expect(fn(k * k)).toBe('1M'); + expect(fn(k * k * k)).toBe('1G'); + expect(fn(k * k * k * k)).toBe('1T'); + expect(fn(k * k * k * k * k)).toBe('1P'); + expect(fn(k ** 6)).toBe('1E'); + expect(fn(k ** 7)).toBe('1Z'); + expect(fn(-(k ** 7))).toBe('-1Z'); + expect(fn(k ** 8)).toBe('1Y'); + + expect(fn(k * 512 + k * 0.98)).toBe('512.98K'); + + // 指定单位 + expect(fn(k * 0.5 * k, { unit: 'M' })).toBe('0.5M'); + expect(fn(k * 0.5 * k, { unit: 'G' })).toBe('0G'); + // 指定小数位 + expect(fn(k * 0.49 * k, { fractionDigits: 5, unit: 'G' })).toBe('0.00049G'); + expect(fn(1, { fractionDigits: 9, unit: 'G' })).toBe('0.000000001G'); + // 使用科学计数法 + expect(fn(1, { fractionDigits: 9, exponential: true, unit: 'G' })).toBe('1e-9G'); + + // 超过 5 位才进位 + expect(fn(-1, { maxLength: 5 })).toBe('-1'); + expect(fn(100, { maxLength: 5 })).toBe('100'); + expect(fn(100_00, { maxLength: 5 })).toBe('10000'); + expect(fn(100_000, { maxLength: 5 })).toBe('100K'); + expect(fn(1_000_000, { maxLength: 5 })).toBe('1000K'); + expect(fn(10_000_000, { maxLength: 5 })).toBe('10M'); + expect(fn(100_000_000, { maxLength: 5 })).toBe('100M'); + expect(fn(1_000_000_000, { maxLength: 5 })).toBe('1000M'); + expect(fn(10_000_000_000, { maxLength: 5 })).toBe('10G'); + expect(fn(1_000_000_000_000, { maxLength: 5 })).toBe('1000G'); + expect(fn(10_000_000_000_000, { maxLength: 5 })).toBe('10T'); + expect(fn(100_000_000_000_000, { maxLength: 5 })).toBe('100T'); + expect(fn(1_000_000_000_000_000, { maxLength: 5 })).toBe('1000T'); + expect(fn(100_000_000_000_000_000, { maxLength: 5 })).toBe('100P'); + expect(fn(1_000_000_000_000_000_000_000, { maxLength: 5 })).toBe('1000E'); + expect(fn(1_000_000_000_000_000_000_000_000, { maxLength: 5 })).toBe('1000Z'); + expect(fn(1_000_000_000_000_000_000_000_000_000, { maxLength: 5 })).toBe('1000Y'); + // 最大单位为 Y + expect(fn(1_000_000_000_000_000_000_000_000_000_000, { exponential: true, maxLength: 5 })).toBe( + '1e+6Y', + ); + + expect(fn(100_000, { maxLength: 6 })).toBe('100000'); + expect(fn(1_000_000, { maxLength: 6 })).toBe('1000K'); + expect(fn(90_000_000, { maxLength: 6 })).toBe('90000K'); + expect(fn(800_000_000, { maxLength: 6 })).toBe('800M'); + + // 指定1k=1024 + const kb = 1024; + expect(fn(kb * 0.5 * kb, { kSize: kb })).toBe('512K'); + expect(fn(kb * 0.5 * kb, { kSize: kb, unit: 'M' })).toBe('0.5M'); + expect(fn(kb * 50 * kb, { kSize: kb, unit: 'K' })).toBe('51200K'); + }); }); diff --git a/__tests__/object/common.test.ts b/__tests__/object/common.test.ts index c01114c8..30141fd7 100644 --- a/__tests__/object/common.test.ts +++ b/__tests__/object/common.test.ts @@ -2,16 +2,15 @@ import * as cm from '../../src/object/common'; import * as arr from '../../src/array'; import { forEachNum } from '../../src'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars function expectType(_value: T) {} -// eslint-disable-next-line @typescript-eslint/no-unused-vars + export function expectError(_value: T) {} describe('object', function () { test('deepMerge', () => { const deepMerge = cm.deepMerge; // 对象合并 - const a = { one: 1, two: 2, three: 3 }; + const a = { three: 3, one: 1, two: 2 }; const b = { one: 11, four: 4, five: 5 }; expect(deepMerge(a, b)).toEqual(Object.assign({}, a, b)); @@ -29,8 +28,7 @@ describe('object', function () { Fn.prototype.b = 200; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error const d = new Fn(); expect(deepMerge(a, d)).toEqual(Object.assign({}, a, d)); // 不会合并继承属性 @@ -42,19 +40,21 @@ describe('object', function () { test('getReversedObj', async () => { const fn = cm.getReversedObj; - const obj = { a: 'aa', b: 'bb' }; - expect(fn(obj)).toEqual({ aa: 'a', bb: 'b' }); + const revObj = fn({ a: 'aa', b: 'bb' }); + const newObj: typeof revObj = { aa: 'a', bb: 'b' }; + expect(revObj).toEqual({ aa: 'a', bb: 'b' }); + expect(newObj).toEqual({ aa: 'a', bb: 'b' }); }); test('omit', () => { const omit = cm.omit; - expect(omit({ a: 12, b: true, c: 'c' }, ['a'])).toEqual({ b: true, c: 'c' }); - expect(omit({ a: 12, b: true, c: 'c' }, ['a', 'b'])).toEqual({ c: 'c' }); + expect(omit({ b: true, c: 'c', a: 12 }, ['a'])).toEqual({ b: true, c: 'c' }); + expect(omit({ b: true, c: 'c', a: 12 }, ['a', 'b'])).toEqual({ c: 'c' }); expect(omit({ c: 'c' }, ['c'])).toEqual({}); const obj: { [k: string]: number } = {}; forEachNum(10000, (index) => (obj[index] = index)); - const keys = arr.createArray({ len: 500, fill: (v) => String(v) }); + const keys = arr.createArray({ fill: (v) => String(v), len: 500 }); // console.time('run'); const result = omit(obj, keys); expect(Object.keys(result).length).toEqual(9500); @@ -62,7 +62,7 @@ describe('object', function () { }); test('defaults', () => { const defaults = cm.defaults; - const origin = { a: 12, b: undefined, c: 3, d: null, 0: undefined }; + const origin = { b: undefined, 0: undefined, d: null, a: 12, c: 3 }; // 0个参数 expect(defaults({ ...origin })).toEqual(origin); expect(defaults({ ...origin }, null)).toEqual(origin); @@ -131,25 +131,25 @@ describe('object', function () { expect(getInsKeys(obj3).sort()).toEqual(['a', 'b']); }); const commonUpdate = (fn: Function) => { - expect(fn({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { d: 4 })).toEqual({ + expect(fn({ b: undefined, a: 12, c: 3 }, { a: 1 }, { b: 2 }, { d: 4 })).toEqual({ a: 1, b: 2, c: 3, }); - expect(fn({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { c: undefined })).toEqual({ + expect(fn({ b: undefined, a: 12, c: 3 }, { a: 1 }, { b: 2 }, { c: undefined })).toEqual({ + c: undefined, a: 1, b: 2, - c: undefined, }); - expect(fn({ a: 12, b: undefined, c: 3 }, { aa: 2, bb: 2, dd: 123 }, { c: undefined })).toEqual({ - a: 12, + expect(fn({ b: undefined, a: 12, c: 3 }, { dd: 123, aa: 2, bb: 2 }, { c: undefined })).toEqual({ b: undefined, c: undefined, + a: 12, }); - expect(fn({ a: 12, b: undefined, c: 3 }, null as any, undefined as any)).toEqual({ - a: 12, + expect(fn({ b: undefined, a: 12, c: 3 }, null as any, undefined as any)).toEqual({ b: undefined, + a: 12, c: 3, }); @@ -192,20 +192,20 @@ describe('object', function () { test('renameObjKey', () => { const renameObjKey = cm.renameObjKey; - expect(renameObjKey({ a: 12, b: undefined, c: 3 }, { test: 'a', bb: 'b' })).toEqual({ - test: 12, + expect(renameObjKey({ b: undefined, a: 12, c: 3 }, { test: 'a', bb: 'b' })).toEqual({ bb: undefined, + test: 12, c: 3, }); - expect(renameObjKey({ a: 12, b: undefined, c: 3 }, { test: 'aa' as any, bb: 'b' })).toEqual({ - a: 12, + expect(renameObjKey({ b: undefined, a: 12, c: 3 }, { test: 'aa' as any, bb: 'b' })).toEqual({ bb: undefined, + a: 12, c: 3, }); - expect(renameObjKey({ a: 1, b: 2 }, { a: 'a', aa: 'a', aaa: 'a' })).toEqual({ - a: 1, - aa: 1, + expect(renameObjKey({ a: 1, b: 2 }, { aaa: 'a', aa: 'a', a: 'a' })).toEqual({ aaa: 1, + aa: 1, + a: 1, b: 2, }); }); @@ -213,7 +213,7 @@ describe('object', function () { test('hasOwn', () => { const hasOwn = cm.hasOwn; - const obj = { a: 1, b: 2, '[object Object]': 1 } as const; + const obj = { '[object Object]': 1, a: 1, b: 2 } as const; expect(hasOwn(obj, 'a')).toBeTruthy(); expect(hasOwn(obj, 'c')).toBeFalsy(); @@ -233,7 +233,7 @@ describe('object', function () { // 对象属性交换 expect(swap({ a: 1, b: 2 }, 'a', 'b')).toEqual({ b: 1, a: 2 }); - expect(swap({ a: 1, b: 2 }, 'a', 'c' as any)).toEqual({ c: 1, b: 2, a: undefined }); + expect(swap({ a: 1, b: 2 }, 'a', 'c' as any)).toEqual({ a: undefined, c: 1, b: 2 }); // 数组item交换 expect(swap([1, 2], 1, 0)).toEqual([2, 1]); @@ -244,11 +244,12 @@ describe('object', function () { const likeKeys = cm.likeKeys; expect(likeKeys([1, 2, 3, 4, 5, 6, 7], '0')).toEqual(['0']); expect(likeKeys([1, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1], '0')).toEqual(['0', '10']); + // eslint-disable-next-line perfectionist/sort-objects expect(likeKeys({ test: 1, test2: 2, test3: 3 }, 'test')).toEqual(['test', 'test2', 'test3']); const map = new Map([ + ['hello', 'world'], ['aa', 1], ['bb', 2], - ['hello', 'world'], ]); expect(likeKeys(map, /a+|b+/)).toEqual(['aa', 'bb']); }); diff --git a/__tests__/object/iterate.test.ts b/__tests__/object/iterate.test.ts index 6e930348..b61b601b 100644 --- a/__tests__/object/iterate.test.ts +++ b/__tests__/object/iterate.test.ts @@ -1,9 +1,9 @@ -import { forEachObj } from '../../src/object/iterate'; import * as cm from '../../src/object'; -import { omit } from '@mxssfd/core'; +import { omit } from '../../src'; describe('object.iterate', function () { test('forEachObj', () => { + const forEachObj = cm.forEachObj; const testFn = (obj: object) => { let times = 0; forEachObj(obj, (v, k) => { @@ -15,8 +15,8 @@ describe('object.iterate', function () { expect(times).toEqual(Object.keys(obj).length); }; - testFn({ a: 1, b: '2', c: true }); - testFn({ a: 1, b: '2', c: { test: 1231 } }); + testFn({ c: true, b: '2', a: 1 }); + testFn({ c: { test: 1231 }, b: '2', a: 1 }); let times = 0; const done = forEachObj({ a: 1, b: 2, c: 3 }, () => { times++; @@ -65,7 +65,7 @@ describe('object.iterate', function () { }); test('reduceObj', () => { const reduceObj = cm.reduceObj; - const obj = { a: 1, b: 2, c: '3' }; + const obj = { c: '3', a: 1, b: 2 }; const result = reduceObj(obj, (r, v, k) => ((r[v] = k), r), {} as Record); expect(result).toEqual({ 1: 'a', 2: 'b', 3: 'c' }); expect(result === obj).toEqual(false); @@ -78,11 +78,14 @@ describe('object.iterate', function () { }, {} as Record, ); - const result3 = Object.keys(obj).reduce((r, key) => { - const v = obj[key as keyof typeof obj]; - r[key] = v + '1'; - return r; - }, {} as Record); + const result3 = Object.keys(obj).reduce( + (r, key) => { + const v = obj[key as keyof typeof obj]; + r[key] = v + '1'; + return r; + }, + {} as Record, + ); expect(result2).toEqual({ a: '11', @@ -94,7 +97,7 @@ describe('object.iterate', function () { test('objFilter', () => { const fn = cm.filterObj; - const obj = { a: '', b: 123, c: 0, d: undefined, e: false, f: NaN, g: null }; + const obj = { d: undefined, e: false, g: null, b: 123, f: NaN, a: '', c: 0 }; expect(fn(obj)).toEqual({ b: 123 }); expect(fn(obj, (v) => v !== undefined)).toEqual(omit(obj, ['d'])); }); diff --git a/__tests__/object/path.test.ts b/__tests__/object/path.test.ts index 8fbae08e..49a224d2 100644 --- a/__tests__/object/path.test.ts +++ b/__tests__/object/path.test.ts @@ -49,12 +49,12 @@ describe('object.path', function () { a: { b: { c: true } }, }); expect(fn({ a: { b: { c: 123 } } }, 'b' as any, true)).toEqual({ - b: true, a: { b: { c: 123 } }, + b: true, }); expect(fn({ a: { b: { c: 123 } } }, 'b.c' as any, true)).toEqual({ - b: { c: true }, a: { b: { c: 123 } }, + b: { c: true }, }); expect(fn({ a: 'hello' }, 'a[0]' as any, true)).toEqual({ a: { 0: true } }); expect(fn({ a: 0 }, 'a[0][b][c]' as any, true)).toEqual({ a: { 0: { b: { c: true } } } }); @@ -107,12 +107,14 @@ describe('object.path', function () { ['[a][b][0]', 1], ['[a][b][1]', 2], ]); + // eslint-disable-next-line perfectionist/sort-objects expect(fn({ a: { b: [1, 2, { c: 3, cc: 5 }] } })).toEqual([ ['[a][b][0]', 1], ['[a][b][1]', 2], ['[a][b][2][c]', 3], ['[a][b][2][cc]', 5], ]); + // eslint-disable-next-line perfectionist/sort-objects expect(fn({ a: { b: [1, 2, { c: 3, cc: 5 }] } }, 'obj')).toEqual([ ['obj[a][b][0]', 1], ['obj[a][b][1]', 2], @@ -130,7 +132,7 @@ describe('object.path', function () { expect(fn(['a.0=1', 'a.1=2'])).toEqual({ a: ['1', '2'] }); expect(fn(['a.[0]=1', 'a.[1]=2'])).toEqual({ a: ['1', '2'] }); expect(fn(['a.[b]=1', 'a.[c]=2'])).toEqual({ a: Object.assign([], { b: '1', c: '2' }) }); - expect(fn(['a.[b]=1', 'a.[c]=2'])).not.toEqual({ a: Object.assign([], { b: 1, c: '2' }) }); + expect(fn(['a.[b]=1', 'a.[c]=2'])).not.toEqual({ a: Object.assign([], { c: '2', b: 1 }) }); expect(fn(['a[]=1', 'a[]=2'])).toEqual({ a: ['1', '2'] }); // TODO 暂不支持多层路径 diff --git a/__tests__/object/pick.test.ts b/__tests__/object/pick.test.ts index 482fb1b7..61450b04 100644 --- a/__tests__/object/pick.test.ts +++ b/__tests__/object/pick.test.ts @@ -11,7 +11,7 @@ describe('object.pick', function () { const testPickByKeys = (fn: typeof cm.pickByKeys) => { return () => { - const obj = { a: 1, b: '2', c: ['12313', 111], d: false, e: { a: 1 }, f: undefined }; + const obj = { c: ['12313', 111], f: undefined, e: { a: 1 }, d: false, b: '2', a: 1 }; expect(fn(obj, [])).toEqual({}); expect(fn(obj, ['a'])).toEqual({ a: 1 }); expect(fn(obj, ['b'])).toEqual({ b: obj.b }); @@ -31,10 +31,9 @@ describe('object.pick', function () { } return 'test'; }), - ).toEqual({ a: 2, b: 'test' }); + ).toEqual({ b: 'test', a: 2 }); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error expect(fn(new TestExtends(), ['a', 'c'])).toEqual({ a: 1, c: 3 }); const a = { a: 1 }; @@ -50,7 +49,7 @@ describe('object.pick', function () { }); const testPickRename = (fn: typeof cm.pickRename) => { return () => { - const obj = { a: 1, b: '2', c: ['12313', 111], d: false, e: { a: 1 }, f: undefined }; + const obj = { c: ['12313', 111], f: undefined, e: { a: 1 }, d: false, b: '2', a: 1 }; expect(fn(obj, {})).toEqual({}); expect(fn(obj, { A: 'a' })).toEqual({ A: 1 }); expect(fn(obj, { B: 'b' })).toEqual({ B: obj.b }); @@ -70,10 +69,9 @@ describe('object.pick', function () { } return 'test'; }), - ).toEqual({ A: 2, B: 'test' }); + ).toEqual({ B: 'test', A: 2 }); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error expect(fn(new TestExtends(), { aa: 'a', cc: 'c' })).toEqual({ aa: 1, cc: 3 }); }; }; @@ -85,7 +83,7 @@ describe('object.pick', function () { const fn = cm.pick; // pickByKeys testPickByKeys(fn)(); - let obj = { a: 1, b: '2', c: ['12313', 111], d: false, e: { a: 1 }, f: undefined }; + let obj = { c: ['12313', 111], f: undefined, e: { a: 1 }, d: false, b: '2', a: 1 }; expect( fn(obj, ['a', 'b'], (_v, k) => { if (k === 'a') { @@ -93,11 +91,11 @@ describe('object.pick', function () { } return 'test'; }), - ).toEqual({ a: 2, b: 'test' }); + ).toEqual({ b: 'test', a: 2 }); // pickRename testPickRename(fn)(); - obj = { a: 1, b: '2', c: ['12313', 111], d: false, e: { a: 1 }, f: undefined }; + obj = { c: ['12313', 111], f: undefined, e: { a: 1 }, d: false, b: '2', a: 1 }; expect( fn(obj, { A: 'a', B: 'b' }, (_v, k) => { if (k === 'a') { @@ -105,7 +103,7 @@ describe('object.pick', function () { } return 'test'; }), - ).toEqual({ A: 2, B: 'test' }); + ).toEqual({ B: 'test', A: 2 }); const nObj = fn(obj, { A: 'a', B: 'a' }, () => { return 2; }); @@ -113,7 +111,7 @@ describe('object.pick', function () { }); test('pickUpdated', () => { const fn = cm.pickUpdated; - const obj1 = { a: 12, b: undefined, c: 3 }; + const obj1 = { b: undefined, a: 12, c: 3 }; expect(fn(obj1, [{ a: 1 }, { b: 2 }, { d: 3 }])).toEqual({ a: 1, b: 2 }); expect(fn(obj1, [{ a: 1 }, { a: 2 }, { a: 5 }])).toEqual({ a: 5 }); expect(fn(obj1, [{ a: 1 }, { a: 2 }, { a: 12 }])).toEqual({}); @@ -152,7 +150,7 @@ describe('object.pick', function () { pickDiff(a, [b, { a: { id: 1 } }, { b: { id: 11 } }], (v1, v2) => { return v1 && v1.id === v2.id; }), - ).toEqual({ a: { id: 1 }, b: { id: 11 } }); + ).toEqual({ b: { id: 11 }, a: { id: 1 } }); }); test('pickExternal', () => { const { pickExternal } = cm; diff --git a/__tests__/object/tree.test.ts b/__tests__/object/tree.test.ts index 3fcc96b1..ad1b0c81 100644 --- a/__tests__/object/tree.test.ts +++ b/__tests__/object/tree.test.ts @@ -6,7 +6,7 @@ describe('tree', function () { expect(cm.getTreeMaxDeep({ a: 1 })).toBe(2); expect(cm.getTreeMaxDeep(null as any)).toBe(0); expect(cm.getTreeMaxDeep({ a: { b: 1 } })).toBe(3); - const obj: any = { a: { a2: 1 }, b: 1, c: { c2: { c3: 123, c32: {} } } }; + const obj: any = { c: { c2: { c3: 123, c32: {} } }, a: { a2: 1 }, b: 1 }; expect(cm.getTreeMaxDeep(obj)).toBe(4); expect(cm.getTreeMaxDeep([])).toBe(1); expect(cm.getTreeMaxDeep([1, 2, 4, 5])).toBe(2); @@ -16,10 +16,9 @@ describe('tree', function () { this.test = { a: 1, b: 2 }; } - Fn.prototype.c = { a: { b: 2, c: { d: 123 } } }; + Fn.prototype.c = { a: { c: { d: 123 }, b: 2 } }; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error const fn = new Fn(); expect(cm.getTreeMaxDeep(fn)).toBe(3); }); @@ -28,27 +27,27 @@ describe('tree', function () { expect(cm.getTreeNodeLen({}, 0)).toBe(1); expect(cm.getTreeNodeLen({})).toBe(0); expect(cm.getTreeNodeLen({ a: 1, b: 2, c: 3 })).toBe(3); - expect(cm.getTreeNodeLen({ a: 1, b: 2, c: 3, d: { d1: 123, d2: 1, d3: 123 } })).toBe(4); + expect(cm.getTreeNodeLen({ d: { d1: 123, d3: 123, d2: 1 }, a: 1, b: 2, c: 3 })).toBe(4); expect( - cm.getTreeNodeLen({ a: 1, b: { b2: 2, b3: 3 }, c: 3, d: { d1: 123, d2: 1, d3: 123 } }), + cm.getTreeNodeLen({ d: { d1: 123, d3: 123, d2: 1 }, b: { b2: 2, b3: 3 }, a: 1, c: 3 }), ).toBe(4); expect( - cm.getTreeNodeLen({ a: 1, b: { b2: 2, b3: 3 }, c: 3, d: { d1: 123, d2: 1, d3: 123 } }, 2), + cm.getTreeNodeLen({ d: { d1: 123, d3: 123, d2: 1 }, b: { b2: 2, b3: 3 }, a: 1, c: 3 }, 2), ).toBe(5); expect(cm.getTreeNodeLen({ a: { a2: 1 }, b: { b2: 2 }, c: { c2: 3 }, d: { d1: 4 } }, 2)).toBe( 4, ); expect( cm.getTreeNodeLen( - { a: { a2: 1, a3: { a4: 4 } }, b: { b2: 2 }, c: { c2: 3 }, d: { d1: 4 } }, + { a: { a3: { a4: 4 }, a2: 1 }, b: { b2: 2 }, c: { c2: 3 }, d: { d1: 4 } }, 3, ), ).toBe(1); expect( cm.getTreeNodeLen( { - a: { a2: 1, a3: { a4: 4 } }, - b: { b2: 2, b3: { b4: 4 } }, + a: { a3: { a4: 4 }, a2: 1 }, + b: { b3: { b4: 4 }, b2: 2 }, c: { c2: 3 }, d: { d1: 4 }, }, @@ -62,10 +61,9 @@ describe('tree', function () { this.test = { a: 1, b: 2 }; } - Fn.prototype.c = { a: { b: 2, c: { d: 123 } } }; + Fn.prototype.c = { a: { c: { d: 123 }, b: 2 } }; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore + // @ts-expect-error const fn = new Fn(); expect(cm.getTreeNodeLen(fn, 2)).toBe(2); }); diff --git a/__tests__/promise.test.ts b/__tests__/promise.test.ts index 517c5fcd..78266b7e 100644 --- a/__tests__/promise.test.ts +++ b/__tests__/promise.test.ts @@ -1,4 +1,4 @@ -import { sleep, inRange } from '../src'; +import { inRange, sleep } from '../src'; import * as cm from '../src/promise'; describe('promise', function () { @@ -283,4 +283,22 @@ describe('promise', function () { expect(mock.mock.calls.map((i) => i[0])).toEqual(['hello world foo bar', undefined]); }); }); + test('nextTick', async () => { + const nextTick = cm.nextTick; + const fn = jest.fn(); + + expect(fn.mock.calls.length).toBe(0); + await nextTick().then(fn); + expect(fn.mock.calls.length).toBe(1); + + nextTick(fn); + await sleep(0); + expect(fn.mock.calls.length).toBe(2); + + // 中断 + const abort = nextTick(fn); + abort(); + await sleep(0); + expect(fn.mock.calls.length).toBe(2); + }); }); diff --git a/__tests__/random.test.ts b/__tests__/random.test.ts index df7823c0..66f08cd0 100644 --- a/__tests__/random.test.ts +++ b/__tests__/random.test.ts @@ -1,14 +1,14 @@ -import * as cm from '../src/random'; import { - forEachNum, - omit, createArray, - unique, isArrayLike, + forEachNum, isHEXColor, isRGBColor, inRange, + unique, + omit, } from '../src'; +import * as cm from '../src/random'; describe('random', function () { test('randomFloat', () => { @@ -112,7 +112,7 @@ describe('random', function () { const arr6 = fn(0.2, 0.4, 300); expect(arr6.length).toBe(300); expect(arr6.every((i) => i === 0.2)).toBeTruthy(); - const arr8 = createArray({ len: 200, fill: () => fn() }); + const arr8 = createArray({ fill: () => fn(), len: 200 }); expect(arr8.length).toBe(200); expect(arr8.every((i) => i >= 0 && i < Number.MAX_SAFE_INTEGER)).toBeTruthy(); @@ -130,7 +130,7 @@ describe('random', function () { }); const arr2 = createArray({ len: 20 }); - const results = createArray({ len: 1000, fill: () => fn(arr2) }); + const results = createArray({ fill: () => fn(arr2), len: 1000 }); expect(results.length).toBe(1000); arr2.forEach((it) => { @@ -141,14 +141,14 @@ describe('random', function () { test('randomRGB', () => { const fn = cm.randomRGB; - const rgbList = createArray({ len: 100, fill: () => fn() }); + const rgbList = createArray({ fill: () => fn(), len: 100 }); rgbList.forEach((it) => { expect(isRGBColor(it)).toBeTruthy(); }); }); test('randomRGBA', () => { const fn = cm.randomRGBA; - const rgbList = createArray({ len: 10000, fill: () => fn() }); + const rgbList = createArray({ fill: () => fn(), len: 10000 }); rgbList.forEach((it) => { const flag = isRGBColor(it); expect(flag).toBeTruthy(); @@ -190,7 +190,7 @@ describe('random', function () { expect(fn([])).toEqual([]); expect(() => fn(undefined as any)).toThrowError(); - const arrLike = { 0: 1, 1: 'a', 2: true, 3: '3', 4: '4', 5: '5', length: 6 }; + const arrLike = { length: 6, 2: true, 1: 'a', 3: '3', 4: '4', 5: '5', 0: 1 }; const newArrLike = fn(arrLike); expect(isArrayLike(arrLike)).toBeTruthy(); expect(arrLike.length).toBe(newArrLike.length); diff --git a/__tests__/string.test.ts b/__tests__/string.test.ts index bb71d1e8..fd7d3ec1 100644 --- a/__tests__/string.test.ts +++ b/__tests__/string.test.ts @@ -1,6 +1,5 @@ import * as cm from '../src/string'; -const { formatNumber, strTemplate, removeStrByNum, smartRepeat, capitalize, fromCamel, toCamel } = - cm; +const { removeStrByNum, formatNumber, strTemplate, smartRepeat, capitalize, camelCase } = cm; describe('string', function () { test('formatNumber', () => { @@ -60,55 +59,39 @@ describe('string', function () { expect(capitalize('ab')).toBe('Ab'); expect(capitalize('Ab')).toBe('Ab'); expect(capitalize('aa')).toBe('Aa'); + expect(capitalize('AAA')).toBe('Aaa'); // edge expect(capitalize('')).toBe(''); }); - test('fromCamel', () => { - // 默认下划线分割 - expect(fromCamel('a')).toBe('a'); - expect(fromCamel('A')).toBe('a'); - expect(fromCamel('Test')).toBe('test'); - expect(fromCamel('TEST')).toBe('test'); - expect(fromCamel('testCamel')).toBe('test_camel'); - expect(fromCamel('TestCamelString')).toBe('test_camel_string'); - expect(fromCamel('TestCamelSTring')).toBe('test_camel_string'); - - // 自定义分割字符 - expect(fromCamel('TestCamelSTring', '-')).toBe('test-camel-string'); - - // 转大写 - expect(fromCamel('TestCamelSTring', '-', true)).toBe('TEST-CAMEL-STRING'); - }); - - test('toCamel', () => { - expect(toCamel('A')).toBe('a'); - // 转大驼峰 - expect(toCamel('A', undefined, true)).toBe('A'); - - expect(toCamel('a')).toBe('a'); - // 转大驼峰 - expect(toCamel('a', undefined, true)).toBe('A'); - - expect(toCamel('1')).toBe('1'); - - expect(toCamel('ab')).toBe('ab'); - // 转大驼峰 - expect(toCamel('ab', undefined, true)).toBe('Ab'); - - // 默认选项 - expect(toCamel('aa_bb')).toBe('aaBb'); - expect(toCamel('test_camel_string')).toBe('testCamelString'); - expect(toCamel('test__camel_string')).toBe('testCamelString'); - - // 默认分隔符,转大驼峰 - expect(toCamel('test_camel_string', undefined, true)).toBe('TestCamelString'); - - // 正则匹配分隔符 - expect(toCamel('test-camel_string', /[-_]/)).toBe('testCamelString'); - - // edge - expect(toCamel('', '')).toBe(''); + test('camelCase', () => { + expect(camelCase('')).toBe(''); + expect(camelCase('a')).toBe('a'); + expect(camelCase('A')).toBe('a'); + expect(camelCase('helloWorld')).toBe('helloWorld'); + expect(camelCase('HELLO-WORLD')).toBe('helloWorld'); + expect(camelCase('hello-World')).toBe('helloWorld'); + expect(camelCase('hello World')).toBe('helloWorld'); + expect(camelCase('hello world')).toBe('helloWorld'); + expect(camelCase('Hello world')).toBe('helloWorld'); + expect(camelCase('Hello world')).toBe('helloWorld'); + expect(camelCase('Hello___world')).toBe('helloWorld'); + + expect(camelCase('aBBcde-f__g h')).toBe('aBbcdeFGH'); + expect(camelCase('abc0Abc0')).toBe('abc0Abc0'); + + expect(camelCase('Auv')).toBe('auv'); + expect(camelCase('a-u-v')).toBe('aUV'); + expect(camelCase('Auv')).toBe('auv'); + expect(camelCase(' Auv')).toBe('auv'); + expect(camelCase(' auv')).toBe('auv'); + expect(camelCase('-Auv')).toBe('auv'); + expect(camelCase('_Auv')).toBe('auv'); + + expect(camelCase('无hello')).toBe('无hello'); + expect(camelCase('无 hello')).toBe('无Hello'); + expect(camelCase('无Hello')).toBe('无Hello'); + expect(camelCase('&^%%$Hello')).toBe('hello'); }); describe('getStringLen', function () { const fn = cm.getStringLen; @@ -176,7 +159,7 @@ describe('string', function () { it('start,end', () => { expect(hideString('helloworld')).toBe('**********'); - expect(hideString('helloworld', { start: 0, replacement: '*' })).toBe('**********'); + expect(hideString('helloworld', { replacement: '*', start: 0 })).toBe('**********'); expect(hideString('helloworld', { start: 0, end: 0 })).toBe('helloworld'); @@ -198,7 +181,7 @@ describe('string', function () { expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: 1, end: -1 })).toBe('👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦'); expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: -12, end: -1 })).toBe('👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦'); - expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: -12, end: -1, replacementLen: 1 })).toBe( + expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { replacementLen: 1, start: -12, end: -1 })).toBe( '👨‍👨‍👧‍👦*👨‍👨‍👧‍👦', ); }); @@ -218,35 +201,118 @@ describe('string', function () { expect(hideString('👨‍👨‍👧‍👦helloworld👨‍👨‍👧‍👦', { start: 1, len: 10 })).toBe('👨‍👨‍👧‍👦**********👨‍👨‍👧‍👦'); expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: 1, len: 11 })).toBe('👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦'); - expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: 1, len: 11, replacementLen: 1 })).toBe( + expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { replacementLen: 1, start: 1, len: 11 })).toBe( '👨‍👨‍👧‍👦*👨‍👨‍👧‍👦', ); }); it('len,end', () => { expect(hideString('helloworld')).toBe('**********'); - expect(hideString('helloworld', { len: 10, end: 10, replacement: '*' })).toBe('**********'); + expect(hideString('helloworld', { replacement: '*', len: 10, end: 10 })).toBe('**********'); - expect(hideString('helloworld', { len: 0, end: 10 })).toBe('helloworld'); + expect(hideString('helloworld', { end: 10, len: 0 })).toBe('helloworld'); - expect(hideString('helloworld', { len: 8, end: -1 })).toBe('h********d'); + expect(hideString('helloworld', { end: -1, len: 8 })).toBe('h********d'); expect(hideString('helloworld', { len: 8, end: 9 })).toBe('h********d'); expect(hideString('👨‍👨‍👧‍👦helloworld👨‍👨‍👧‍👦', { len: 10, end: -1 })).toBe('👨‍👨‍👧‍👦**********👨‍👨‍👧‍👦'); expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { len: 11, end: -1 })).toBe('👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦'); - expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { len: 11, end: -1, replacementLen: 1 })).toBe('👨‍👨‍👧‍👦*👨‍👨‍👧‍👦'); + expect(hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { replacementLen: 1, len: 11, end: -1 })).toBe('👨‍👨‍👧‍👦*👨‍👨‍👧‍👦'); }); }); test('getClassNames', () => { const getClassNames = cm.getClassNames; expect(getClassNames('a', 'b')).toBe('a b'); - expect(getClassNames({ a: true, b: false, c: true })).toBe('a c'); - expect(getClassNames('a', 'b', { a: true, b: false, c: true })).toBe('a b c'); - expect(getClassNames(' ', 'a', ' ', 'b', ' ', 'c', { a: true, b: '', c: true })).toBe( - 'a b c', + expect(getClassNames('a', 'b', undefined)).toBe('a b'); + expect(getClassNames('a', 'b', null)).toBe('a b'); + expect(getClassNames('a', 'b')).toBe('a b'); + expect(getClassNames({ b: false, a: true, c: true })).toBe('a c'); + expect(getClassNames('a', 'b', { b: false, a: true, c: true })).toBe('a c'); + expect(getClassNames(' ', 'a', ' ', 'b', ' ', 'c', { a: true, c: true, b: '' })).toBe( + 'a c', ); expect(getClassNames({ a: true, b: ' ', c: '' })).toBe('a b'); expect(getClassNames({ a: true, b: 1, c: 0 })).toBe('a b'); + + expect(getClassNames({ a: true, b: 1 }, { b: 0 })).toBe('a'); + }); + test('kebabCase', () => { + const kebabCase = cm.kebabCase; + + expect(kebabCase('')).toBe(''); + expect(kebabCase('a')).toBe('a'); + expect(kebabCase('A')).toBe('a'); + expect(kebabCase('aBBcde-fFF__g h')).toBe('a-bbcde-f-ff-g-h'); + expect(kebabCase('APPStyle')).toBe('appstyle'); + expect(kebabCase('APP_Style')).toBe('app-style'); + expect(kebabCase('abc0Abc0')).toBe('abc0-abc0'); + + expect(kebabCase('AUV')).toBe('auv'); + expect(kebabCase('AUV_AUV')).toBe('auv-auv'); + expect(kebabCase('Auv')).toBe('auv'); + expect(kebabCase(' Auv')).toBe('auv'); + expect(kebabCase('-Auv')).toBe('auv'); + expect(kebabCase('_Auv')).toBe('auv'); + + expect(kebabCase('无hello')).toBe('无hello'); + expect(kebabCase('无 hello')).toBe('无-hello'); + expect(kebabCase('无Hello')).toBe('无-hello'); + expect(kebabCase('&^%%$Hello')).toBe('hello'); + }); + + test('pascalCase', () => { + const pascalCase = cm.pascalCase; + + expect(pascalCase('')).toBe(''); + expect(pascalCase('a')).toBe('A'); + expect(pascalCase('A')).toBe('A'); + expect(pascalCase('helloWorld')).toBe('HelloWorld'); + expect(pascalCase('hello-World')).toBe('HelloWorld'); + expect(pascalCase('hello-World')).toBe('HelloWorld'); + expect(pascalCase('hello World')).toBe('HelloWorld'); + expect(pascalCase('hello world')).toBe('HelloWorld'); + expect(pascalCase('Hello world')).toBe('HelloWorld'); + expect(pascalCase('Hello world')).toBe('HelloWorld'); + expect(pascalCase('Hello___world')).toBe('HelloWorld'); + + expect(pascalCase('aBBcde-f__g h')).toBe('ABbcdeFGH'); + expect(pascalCase('abc0Abc0')).toBe('Abc0Abc0'); + + expect(pascalCase('Auv')).toBe('Auv'); + expect(pascalCase('a-u-v')).toBe('AUV'); + expect(pascalCase('Auv')).toBe('Auv'); + expect(pascalCase(' Auv')).toBe('Auv'); + expect(pascalCase(' auv')).toBe('Auv'); + expect(pascalCase('-Auv')).toBe('Auv'); + expect(pascalCase('_Auv')).toBe('Auv'); + + expect(pascalCase('无hello')).toBe('无hello'); + expect(pascalCase('无 hello')).toBe('无Hello'); + expect(pascalCase('无Hello')).toBe('无Hello'); + expect(pascalCase('&^%%$Hello')).toBe('Hello'); + }); + test('snakeCase', () => { + const snakeCase = cm.snakeCase; + + expect(snakeCase('')).toBe(''); + expect(snakeCase('a')).toBe('a'); + expect(snakeCase('A')).toBe('a'); + expect(snakeCase('aBBcde-fFF__g h')).toBe('a_bbcde_f_ff_g_h'); + expect(snakeCase('APPStyle')).toBe('appstyle'); + expect(snakeCase('APP_Style')).toBe('app_style'); + expect(snakeCase('abc0Abc0')).toBe('abc0_abc0'); + + expect(snakeCase('AUV')).toBe('auv'); + expect(snakeCase('AUV_AUV')).toBe('auv_auv'); + expect(snakeCase('Auv')).toBe('auv'); + expect(snakeCase(' Auv')).toBe('auv'); + expect(snakeCase('-Auv')).toBe('auv'); + expect(snakeCase('_Auv')).toBe('auv'); + + expect(snakeCase('无hello')).toBe('无hello'); + expect(snakeCase('无 hello')).toBe('无_hello'); + expect(snakeCase('无Hello')).toBe('无_hello'); + expect(snakeCase('&^%%$Hello')).toBe('hello'); }); }); diff --git a/__tests__/time.test.ts b/__tests__/time.test.ts index a90a99b7..451dc646 100644 --- a/__tests__/time.test.ts +++ b/__tests__/time.test.ts @@ -1,34 +1,40 @@ import { - msToDateStr, - strToDate, - formatDate, - createTimeCountUp, + getMonthTheNthWeekday, createTimeCountDown, - getEndOfMonth, - dateDiff, - isSameTime, - inSameWeek, - yearDiff, + formatMilliseconds, + getTimePeriodConst, + parseFormattedDate, + createTimeCountUp, calcRelativeDate, getMilliseconds, - getMonthTheNthWeekday, - getTimePeriodConst, - howLongAgo, + getStartOfMonth, getStartOfDate, getStartOfWeek, - getStartOfNextWeek, + getEndOfMonth, + getEndOfWeek, + isNextMonth, + formatDate, + isSameTime, + inSameWeek, + howLongAgo, + isSameDate, + strToDate, + dateDiff, + yearDiff, + dateAdd, } from '../src/time'; -import { chunk, createArray, inRange } from '@mxssfd/core'; +import { createArray, inRange, chunk } from '../src'; describe('time', function () { jest.useFakeTimers(); // 启用模拟定时器 - test('msToDates', () => { - expect(msToDateStr(1000, 'd天hh时')).toBe('0天00时'); - expect(msToDateStr(1000)).toBe('0天00时00分01秒'); - expect(msToDateStr(60 * 1000)).toBe('0天00时01分00秒'); - expect(msToDateStr(60 * 60 * 1000)).toBe('0天01时00分00秒'); - expect(msToDateStr(60 * 60 * 24 * 1000)).toBe('1天00时00分00秒'); + test('formatMilliseconds', () => { + expect(formatMilliseconds(1000, 'd天hh时')).toBe('0天00时'); + expect(formatMilliseconds(1000)).toBe('0天00时00分01秒'); + expect(formatMilliseconds(60 * 1000)).toBe('0天00时01分00秒'); + expect(formatMilliseconds(60 * 60 * 1000)).toBe('0天01时00分00秒'); + expect(formatMilliseconds(60 * 60 * 24 * 1000)).toBe('1天00时00分00秒'); + expect(formatMilliseconds(2555, 'mm分ss秒')).toBe('00分02秒'); }); test('strToDate', () => { const t1 = strToDate('2020-02-02 10:10:10')!.getTime(); @@ -108,8 +114,8 @@ describe('time', function () { // 自定义季节所在月份范围 const seasonRanges: number[][] = chunk(createArray({ start: 1, len: 12 }), 3); - expect(formatDate(new Date('2020-01-12'), 'q', { seasonNames, seasonRanges })).toBe('spring'); - expect(formatDate(new Date('2020-12-12'), 'q', { seasonNames, seasonRanges })).toBe('winter'); + expect(formatDate(new Date('2020-01-12'), 'q', { seasonRanges, seasonNames })).toBe('spring'); + expect(formatDate(new Date('2020-12-12'), 'q', { seasonRanges, seasonNames })).toBe('winter'); // 自定义星期名字 const weekNames = ['sunday', 'monday']; @@ -122,6 +128,17 @@ describe('time', function () { '2021-11-24 18:00:00:0000', ); }); + test('parseFormattedDate', () => { + const parse = (...args: Parameters): string => + formatDate(parseFormattedDate(...args)); + + expect(parse('2019-12-12 10:10:10')).toBe('2019-12-12 10:10:10'); + expect(parse('2019-12-12')).toBe('2019-12-12 00:00:00'); + expect(parse('2019年12月12日', 'yyyy年MM月dd日')).toBe('2019-12-12 00:00:00'); + expect(parse('12月12日', 'yyyy年MM月dd日')).toBe('0120-12-01 00:00:00'); + + expect(parse('2023-12')).toBe('2023-12-01 00:00:00'); + }); test('createTimeCountUp', () => { const timeCountUp = createTimeCountUp(); expect(timeCountUp()).toBe(0); @@ -144,6 +161,7 @@ describe('time', function () { // ---- 暂停与重启 ---- const tcu = createTimeCountUp(); + tcu.play(); expect(tcu()).toBe(0); // await sleep(1); jest.advanceTimersByTime(1); @@ -185,6 +203,7 @@ describe('time', function () { // ---- 暂停与重启 ---- const tcd = createTimeCountDown(100); + tcd.play(); expect(tcd()).toBe(100); // await sleep(1); jest.advanceTimersByTime(1); @@ -225,6 +244,58 @@ describe('time', function () { // ); }); + test('dateAdd', () => { + // 2023-12-16 + const date = new Date(2023, 11, 16); + + expect(formatDate(dateAdd(date, 1, 'year'))).toBe('2024-12-16 00:00:00'); + expect(formatDate(dateAdd(date, -1, 'year'))).toBe('2022-12-16 00:00:00'); + expect(formatDate(dateAdd(date, 1, 'month'))).toBe('2024-01-16 00:00:00'); + expect(formatDate(dateAdd(date, -1, 'month'))).toBe('2023-11-16 00:00:00'); + expect(formatDate(dateAdd(date, 1, 'week'))).toBe('2023-12-23 00:00:00'); + expect(formatDate(dateAdd(date, -1, 'week'))).toBe('2023-12-09 00:00:00'); + expect(formatDate(dateAdd(date, 1, 'date'))).toBe('2023-12-17 00:00:00'); + expect(formatDate(dateAdd(date, -1, 'date'))).toBe('2023-12-15 00:00:00'); + expect(formatDate(dateAdd(date, 1))).toBe('2023-12-17 00:00:00'); + expect(formatDate(dateAdd(date, 1, 'hours'))).toBe('2023-12-16 01:00:00'); + expect(formatDate(dateAdd(date, -1, 'hours'))).toBe('2023-12-15 23:00:00'); + expect(formatDate(dateAdd(date, 1, 'minutes'))).toBe('2023-12-16 00:01:00'); + expect(formatDate(dateAdd(date, -1, 'minutes'))).toBe('2023-12-15 23:59:00'); + expect(formatDate(dateAdd(date, 1, 'seconds'))).toBe('2023-12-16 00:00:01'); + expect(formatDate(dateAdd(date, -1, 'seconds'))).toBe('2023-12-15 23:59:59'); + expect(formatDate(dateAdd(date, 1000, 'milliseconds'))).toBe('2023-12-16 00:00:01'); + expect(formatDate(dateAdd(date, -1000, 'milliseconds'))).toBe('2023-12-15 23:59:59'); + + expect(formatDate(dateAdd(date, { year: 1 }))).toBe('2024-12-16 00:00:00'); + expect(formatDate(dateAdd(date, { year: -1 }))).toBe('2022-12-16 00:00:00'); + expect(formatDate(dateAdd(date, { month: 1 }))).toBe('2024-01-16 00:00:00'); + expect(formatDate(dateAdd(date, { month: -1 }))).toBe('2023-11-16 00:00:00'); + expect(formatDate(dateAdd(date, { week: 1 }))).toBe('2023-12-23 00:00:00'); + expect(formatDate(dateAdd(date, { week: -1 }))).toBe('2023-12-09 00:00:00'); + expect(formatDate(dateAdd(date, { date: 1 }))).toBe('2023-12-17 00:00:00'); + expect(formatDate(dateAdd(date, { date: -1 }))).toBe('2023-12-15 00:00:00'); + expect(formatDate(dateAdd(date, { hours: 1 }))).toBe('2023-12-16 01:00:00'); + expect(formatDate(dateAdd(date, { hours: -1 }))).toBe('2023-12-15 23:00:00'); + expect(formatDate(dateAdd(date, { minutes: 1 }))).toBe('2023-12-16 00:01:00'); + expect(formatDate(dateAdd(date, { minutes: -1 }))).toBe('2023-12-15 23:59:00'); + expect(formatDate(dateAdd(date, { seconds: 1 }))).toBe('2023-12-16 00:00:01'); + expect(formatDate(dateAdd(date, { seconds: -1 }))).toBe('2023-12-15 23:59:59'); + expect(formatDate(dateAdd(date, { milliseconds: 1000 }))).toBe('2023-12-16 00:00:01'); + expect(formatDate(dateAdd(date, { milliseconds: -1000 }))).toBe('2023-12-15 23:59:59'); + + const add = { + milliseconds: -1000, + minutes: 1, + seconds: 1, + hours: -1, + month: 1, + year: 1, + week: 1, + date: 1, + }; + expect(formatDate(dateAdd(date, add))).toBe('2025-01-23 23:01:00'); + }); + test('getEndOfMonth', async () => { expect(getEndOfMonth(new Date('2021-1')).getDate()).toBe(31); expect(getEndOfMonth(new Date('2021-2')).getDate()).toBe(28); @@ -239,9 +310,45 @@ describe('time', function () { expect(getEndOfMonth(new Date('2021-11')).getDate()).toBe(30); expect(getEndOfMonth(new Date('2021-12')).getDate()).toBe(31); expect(getEndOfMonth(new Date('2020-2')).getDate()).toBe(29); + expect(getEndOfMonth(new Date(2023, 4, 31)).getDate()).toBe(31); expect(formatDate(getEndOfMonth(new Date('2020/02/10 10:00:00')))).toBe('2020-02-29 00:00:00'); expect(formatDate(getEndOfMonth(new Date('2020/12/10 10:00:00')))).toBe('2020-12-31 00:00:00'); expect(formatDate(getEndOfMonth(new Date('2023/12/10 10:00:00')))).toBe('2023-12-31 00:00:00'); + + expect(getEndOfMonth(new Date('2021-1'), -1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-2'), -1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-3'), -1).getDate()).toBe(28); + expect(getEndOfMonth(new Date('2021-4'), -1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-5'), -1).getDate()).toBe(30); + expect(getEndOfMonth(new Date('2021-6'), -1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-7'), -1).getDate()).toBe(30); + expect(getEndOfMonth(new Date('2021-8'), -1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-9'), -1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-10'), -1).getDate()).toBe(30); + expect(getEndOfMonth(new Date('2021-11'), -1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-12'), -1).getDate()).toBe(30); + + expect(getEndOfMonth(new Date('2021-1'), 1).getDate()).toBe(28); + expect(getEndOfMonth(new Date('2021-2'), 1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-3'), 1).getDate()).toBe(30); + expect(getEndOfMonth(new Date('2021-4'), 1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-5'), 1).getDate()).toBe(30); + expect(getEndOfMonth(new Date('2021-6'), 1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-7'), 1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-8'), 1).getDate()).toBe(30); + expect(getEndOfMonth(new Date('2021-9'), 1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-10'), 1).getDate()).toBe(30); + expect(getEndOfMonth(new Date('2021-11'), 1).getDate()).toBe(31); + expect(getEndOfMonth(new Date('2021-12'), 1).getDate()).toBe(31); + }); + test('getStartOfMonth', async () => { + const getStart = (date: string, offset = 0) => + formatDate(getStartOfMonth(parseFormattedDate(date), offset)); + expect(getStart('2023-01-11 19:25:00')).toBe('2023-01-01 00:00:00'); + expect(getStart('2023-10-01 12:25:00')).toBe('2023-10-01 00:00:00'); + expect(getStart('2023-12-30 02:25:00')).toBe('2023-12-01 00:00:00'); + expect(getStart('2023-12-30 02:25:00', 1)).toBe('2024-01-01 00:00:00'); + expect(getStart('2023-12-30 02:25:00', -1)).toBe('2023-11-01 00:00:00'); }); test('getMonthTheNthWeekday', async () => { // const fn = t.getMonthTheLastWeekDay; @@ -326,10 +433,10 @@ describe('time', function () { expect(fn({ hours: 1 })).toBe(fn({ minutes: 60 })); expect(fn({ days: 1 })).toBe(fn({ hours: 24 })); expect(fn({ days: 1.5 })).toBe(fn({ hours: 36 })); - expect(fn({ days: 1, hours: 1, seconds: 10 })).toBe( + expect(fn({ seconds: 10, hours: 1, days: 1 })).toBe( 10 * 1000 + 1000 * 60 * 60 + 1000 * 60 * 60 * 24, ); - expect(fn({ days: 1, hours: 1, seconds: 10 })).toBe( + expect(fn({ seconds: 10, hours: 1, days: 1 })).toBe( fn({ days: 1 }) + fn({ hours: 1 }) + fn({ seconds: 10 }), ); expect(fn({ days: 2 })).toBe(fn({ days: 1 }) * 2); @@ -351,29 +458,29 @@ describe('time', function () { // 上个星期天 const lastSunday = strToDate('2022-07-10')!; - expect(inSameWeek({ now: monday, date: lastSunday })).toBe(false); - expect(inSameWeek({ now: monday, date: lastSunday, weekStart: 'Mon' })).toBe(false); - expect(inSameWeek({ now: monday, date: lastSunday, weekStart: 'Sun' })).toBe(true); + expect(inSameWeek({ date: lastSunday, now: monday })).toBe(false); + expect(inSameWeek({ date: lastSunday, weekStart: 'Mon', now: monday })).toBe(false); + expect(inSameWeek({ date: lastSunday, weekStart: 'Sun', now: monday })).toBe(true); // 星期一到星期六 for (let i = 0; i < 6; i++) { const time = strToDate(('2022-07-' + (11 + i)) as `${number}-${number}-${number}`)!; expect(inSameWeek({ now: monday, date: time })).toBe(true); - expect(inSameWeek({ now: monday, date: time, weekStart: 'Mon' })).toBe(true); - expect(inSameWeek({ now: monday, date: time, weekStart: 'Sun' })).toBe(true); + expect(inSameWeek({ weekStart: 'Mon', now: monday, date: time })).toBe(true); + expect(inSameWeek({ weekStart: 'Sun', now: monday, date: time })).toBe(true); } // 这个星期天 const curSunday = strToDate('2022-07-17')!; - expect(inSameWeek({ now: monday, date: curSunday })).toBe(true); - expect(inSameWeek({ now: monday, date: curSunday, weekStart: 'Mon' })).toBe(true); - expect(inSameWeek({ now: monday, date: curSunday, weekStart: 'Sun' })).toBe(false); + expect(inSameWeek({ date: curSunday, now: monday })).toBe(true); + expect(inSameWeek({ weekStart: 'Mon', date: curSunday, now: monday })).toBe(true); + expect(inSameWeek({ weekStart: 'Sun', date: curSunday, now: monday })).toBe(false); // 星期六 const curThu = strToDate('2022-07-16')!; expect(inSameWeek({ now: curSunday, date: curThu })).toBe(true); - expect(inSameWeek({ now: curSunday, date: curThu, weekStart: 'Mon' })).toBe(true); - expect(inSameWeek({ now: curSunday, date: curThu, weekStart: 'Sun' })).toBe(false); + expect(inSameWeek({ weekStart: 'Mon', now: curSunday, date: curThu })).toBe(true); + expect(inSameWeek({ weekStart: 'Sun', now: curSunday, date: curThu })).toBe(false); // 与当天对比 expect(inSameWeek({ date: new Date() })).toBe(true); @@ -404,15 +511,15 @@ describe('time', function () { const timePeriodConst = getTimePeriodConst(); expect(timePeriodConst).toEqual({ - millisecond: 1, - second: 1000, - minute: 60 * 1000, - hour: 60 * 60 * 1000, - day: 24 * 60 * 60 * 1000, - week: 7 * 24 * 60 * 60 * 1000, - month: 30 * 24 * 60 * 60 * 1000, season: (365 / 4) * 24 * 60 * 60 * 1000, + month: 30 * 24 * 60 * 60 * 1000, year: 365 * 24 * 60 * 60 * 1000, + week: 7 * 24 * 60 * 60 * 1000, + day: 24 * 60 * 60 * 1000, + hour: 60 * 60 * 1000, + minute: 60 * 1000, + millisecond: 1, + second: 1000, } satisfies typeof timePeriodConst); }); test('howLongAgo', () => { @@ -473,16 +580,15 @@ describe('time', function () { // 使用filter替换季数 expect( howLongAgo(date, { - now: new Date('2023/10/8 00:00:00'), filter: (res, diff) => res.endsWith('季前') ? ~~(diff / getTimePeriodConst().season) + ' seasons ago' : res, + now: new Date('2023/10/8 00:00:00'), }), ).toBe('2 seasons ago'); // 混合 expect( howLongAgo(date, { - now: new Date('2023/4/7 02:10:00'), filter: (res, diff) => { if (res.endsWith('小时前')) { const tpc = getTimePeriodConst(); @@ -490,6 +596,7 @@ describe('time', function () { } return res; }, + now: new Date('2023/4/7 02:10:00'), }), ).toBe('2小时10分钟前'); @@ -498,45 +605,99 @@ describe('time', function () { d.setHours(d.getHours() - 8); expect(howLongAgo(d, { templates })).toBe('8 hours ago'); }); + test('howLongAgo 2', () => { + const last = new Date('2023-05-23T15:35:19.000Z'); + const now = new Date('2023-05-25T13:30:45.904Z'); + // 虽然计算没错,但不符合常理 + expect(howLongAgo(last, { now })).toBe('1天前'); + }); test('getDateBegin', () => { expect(formatDate(getStartOfDate(new Date('2023/04/19 12:10:50')))).toBe('2023-04-19 00:00:00'); }); test('getStartOfWeek', () => { - expect(formatDate(getStartOfWeek(new Date('2023/04/19')))).toBe('2023-04-17 00:00:00'); - expect(formatDate(getStartOfWeek(new Date('2023/04/20')))).toBe('2023-04-17 00:00:00'); - expect(formatDate(getStartOfWeek(new Date('2023/04/16')))).toBe('2023-04-10 00:00:00'); - expect(formatDate(getStartOfWeek(new Date('2023/04/10')))).toBe('2023-04-10 00:00:00'); + const getStart = (date: string, options?: Parameters[1]) => + formatDate(getStartOfWeek(new Date(date), options)); + + expect(getStart('2023/12/05', { firstDay: 3 })).toBe('2023-11-29 00:00:00'); + /* 当前星期 */ + // firstDay 为星期一 + expect(getStart('2023/04/19', { firstDay: 1 })).toBe('2023-04-17 00:00:00'); + expect(getStart('2023/04/20', { firstDay: 1 })).toBe('2023-04-17 00:00:00'); + expect(getStart('2023/04/16', { firstDay: 1 })).toBe('2023-04-10 00:00:00'); + expect(getStart('2023/04/10', { firstDay: 1 })).toBe('2023-04-10 00:00:00'); + + // firstDay 为星期日 + expect(getStart('2023/04/19', { firstDay: 0 })).toBe('2023-04-16 00:00:00'); + expect(getStart('2023/04/16', { firstDay: 0 })).toBe('2023-04-16 00:00:00'); + expect(getStart('2023/04/09', { firstDay: 0 })).toBe('2023-04-09 00:00:00'); + expect(getStart('2023/04/10', { firstDay: 0 })).toBe('2023-04-09 00:00:00'); + + // firstDay 为星期三 + expect(getStart('2023/04/16', { firstDay: 3 })).toBe('2023-04-12 00:00:00'); + expect(getStart('2023/04/12', { firstDay: 3 })).toBe('2023-04-12 00:00:00'); + expect(getStart('2023/12/05', { firstDay: 3 })).toBe('2023-11-29 00:00:00'); + expect(getStart('2023/12/27', { firstDay: 3 })).toBe('2023-12-27 00:00:00'); + + expect(getStart('2023/12/05', { firstDay: 4 })).toBe('2023-11-30 00:00:00'); + expect(getStart('2023/12/05', { firstDay: 5 })).toBe('2023-12-01 00:00:00'); + expect(getStart('2023/12/01', { firstDay: 6 })).toBe('2023-11-25 00:00:00'); + expect(getStart('2023/12/08', { firstDay: 6 })).toBe('2023-12-02 00:00:00'); + + /* 上个星期 */ + // firstDay 为星期一 + expect(getStart('2023/04/19', { weekOffset: -1, firstDay: 1 })).toBe('2023-04-10 00:00:00'); + expect(getStart('2023/04/16', { weekOffset: -1, firstDay: 1 })).toBe('2023-04-03 00:00:00'); + // firstDay 为星期日 + expect(getStart('2023/04/19', { weekOffset: -1, firstDay: 0 })).toBe('2023-04-09 00:00:00'); + expect(getStart('2023/04/02', { weekOffset: -1, firstDay: 0 })).toBe('2023-03-26 00:00:00'); + + /* 下个星期 */ + // firstDay 为星期一 + expect(getStart('2023/04/19', { weekOffset: 1, firstDay: 1 })).toBe('2023-04-24 00:00:00'); + expect(getStart('2023/04/20', { weekOffset: 1, firstDay: 1 })).toBe('2023-04-24 00:00:00'); + expect(getStart('2023/04/16', { weekOffset: 1, firstDay: 1 })).toBe('2023-04-17 00:00:00'); + expect(getStart('2023/04/10', { weekOffset: 1, firstDay: 1 })).toBe('2023-04-17 00:00:00'); + // firstDay 为星期日 + expect(getStart('2023/04/19', { weekOffset: 1, firstDay: 0 })).toBe('2023-04-23 00:00:00'); + expect(getStart('2023/04/16', { weekOffset: 1, firstDay: 0 })).toBe('2023-04-23 00:00:00'); + expect(getStart('2023/04/09', { weekOffset: 1, firstDay: 0 })).toBe('2023-04-16 00:00:00'); + expect(getStart('2023/04/10', { weekOffset: 1, firstDay: 0 })).toBe('2023-04-16 00:00:00'); + }); + test('getEndOfWeek', () => { + const getEnd = (date: string, options?: Parameters[1]) => + formatDate(getEndOfWeek(new Date(date), options)); + + // 星期一为星期第一天 + expect(getEnd('2023/04/19', { firstDay: 1 })).toBe('2023-04-23 00:00:00'); + expect(getEnd('2023/04/20', { firstDay: 1 })).toBe('2023-04-23 00:00:00'); + expect(getEnd('2023/04/16', { firstDay: 1 })).toBe('2023-04-16 00:00:00'); + expect(getEnd('2023/04/10', { firstDay: 1 })).toBe('2023-04-16 00:00:00'); + + expect(getEnd('2023/04/10', { weekOffset: 2, firstDay: 1 })).toBe('2023-04-30 00:00:00'); + + // 星期天为星期第一天 + expect(getEnd('2023/04/19')).toBe('2023-04-22 00:00:00'); + expect(getEnd('2023/04/16')).toBe('2023-04-22 00:00:00'); + expect(getEnd('2023/04/09')).toBe('2023-04-15 00:00:00'); + }); + test('isNextMonth', () => { + const isNext = (date: string, base: string) => + isNextMonth(parseFormattedDate(date), parseFormattedDate(base)); - expect(formatDate(getStartOfWeek(new Date('2023/04/19'), 'SunDay'))).toBe( - '2023-04-16 00:00:00', - ); - expect(formatDate(getStartOfWeek(new Date('2023/04/16'), 'SunDay'))).toBe( - '2023-04-16 00:00:00', - ); - expect(formatDate(getStartOfWeek(new Date('2023/04/09'), 'SunDay'))).toBe( - '2023-04-09 00:00:00', - ); - expect(formatDate(getStartOfWeek(new Date('2023/04/10'), 'SunDay'))).toBe( - '2023-04-09 00:00:00', - ); + expect(isNext('2024-02', '2024-01')).toBe(true); + expect(isNext('2024-01', '2023-12')).toBe(true); + expect(isNext('2024-03', '2024-02')).toBe(true); + + expect(isNext('2024-01', '2024-12')).toBe(false); }); - test('getStartOfNextWeek', () => { - expect(formatDate(getStartOfNextWeek(new Date('2023/04/19')))).toBe('2023-04-24 00:00:00'); - expect(formatDate(getStartOfNextWeek(new Date('2023/04/20')))).toBe('2023-04-24 00:00:00'); - expect(formatDate(getStartOfNextWeek(new Date('2023/04/16')))).toBe('2023-04-17 00:00:00'); - expect(formatDate(getStartOfNextWeek(new Date('2023/04/10')))).toBe('2023-04-17 00:00:00'); - - expect(formatDate(getStartOfNextWeek(new Date('2023/04/19'), 'SunDay'))).toBe( - '2023-04-23 00:00:00', - ); - expect(formatDate(getStartOfNextWeek(new Date('2023/04/16'), 'SunDay'))).toBe( - '2023-04-23 00:00:00', - ); - expect(formatDate(getStartOfNextWeek(new Date('2023/04/09'), 'SunDay'))).toBe( - '2023-04-16 00:00:00', - ); - expect(formatDate(getStartOfNextWeek(new Date('2023/04/10'), 'SunDay'))).toBe( - '2023-04-16 00:00:00', - ); + test('isSameDate', () => { + const isSame = (date1: string, date2?: string) => + isSameDate(parseFormattedDate(date1), date2 ? parseFormattedDate(date2) : undefined); + + expect(isSame('2024-01-17', '2024-01-17')).toBe(true); + expect(isSame('2024-01-17 00:00:00', '2024-01-17 12:00:00')).toBe(true); + expect(isSame('2024-01-17', '2024-02-17')).toBe(false); + expect(isSame('2024-01-17', '2023-12-17')).toBe(false); + expect(isSame('2024-01-17')).toBe(false); }); }); diff --git a/__tests__/url/model.test.ts b/__tests__/url/model.test.ts index 4d37be8e..ba1df2f1 100644 --- a/__tests__/url/model.test.ts +++ b/__tests__/url/model.test.ts @@ -1,4 +1,4 @@ -import { UrlModel } from '../../src/url/model'; +import { UrlModel } from '../../src/url/UrlModel'; describe('url.model', function () { const url = diff --git a/__tests__/url/parse.test.ts b/__tests__/url/parse.test.ts index dd5a7eda..87f811d5 100644 --- a/__tests__/url/parse.test.ts +++ b/__tests__/url/parse.test.ts @@ -18,16 +18,16 @@ describe('url.parse', function () { 'test/aaa=1213123?a=1123&b[0]=1&b[1]=2&d[d]=1&d[e]=2?t=1231&b=123123&a%5B%5D=123&a%5B%5D=on&b%5B0%5D=on&b%5B1%5D=on&c=1&c=2&c=3&d=1,2,3,4,5&pid=19&pname=%E7%8E%AF%E7%90%83%E8%B4%B8%E6%98%93%E9%A1%B9%E7%9B%AE%E5%9F%BA%E5%9D%91%E5%9C%B0%E9%93%812%E5%8F%B7%E7%BA%BF%E9%9A%A7%E9%81%93%E7%BB%93%E6%9E%84%E8%87%AA%E5%8A%A8%E5%8C%96%E7%9B%91%E6%B5%8B#test?hash=1&hash2=2'; const obj = getUrlQueryObj(url) as any; expect(obj).toEqual({ - aaa: '1213123', - a: ['1123', '123', 'on'], + d: Object.assign(['1,2,3,4,5'], { d: '1', e: '2' }), + pname: '环球贸易项目基坑地铁2号线隧道结构自动化监测', b: ['on', 'on', '123123'], + a: ['1123', '123', 'on'], c: ['1', '2', '3'], - d: Object.assign(['1,2,3,4,5'], { d: '1', e: '2' }), + aaa: '1213123', + hash2: '2', t: '1231', pid: '19', - pname: '环球贸易项目基坑地铁2号线隧道结构自动化监测', hash: '1', - hash2: '2', }); expect(obj.pname).toEqual('环球贸易项目基坑地铁2号线隧道结构自动化监测'); expect(u.parseUrlQueryObj()).toEqual({}); diff --git a/__tests__/url/url.test.ts b/__tests__/url/url.test.ts index 616d254d..70f78360 100644 --- a/__tests__/url/url.test.ts +++ b/__tests__/url/url.test.ts @@ -1,7 +1,8 @@ -import * as u from '../../src/url/url'; +import * as u from '../../src/url'; describe('url.url', function () { test('stringifyUrlQuery', () => { + // eslint-disable-next-line perfectionist/sort-objects expect(u.stringifyUrlQuery({ a: 1, b: 2, c: [3, 33], d: { f: '5', g: '6' } })).toBe( 'a=1&b=2&c[0]=3&c[1]=33&d[f]=5&d[g]=6', ); @@ -9,7 +10,9 @@ describe('url.url', function () { u.stringifyUrlQuery({ a: 1, b: 2, + // eslint-disable-next-line perfectionist/sort-objects c: [3, 33], + // eslint-disable-next-line perfectionist/sort-objects d: { f: '5', g: '6', h: undefined }, e: undefined, }), diff --git a/commitlint.config.js b/commitlint.config.js index b2711daf..95f9de24 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -17,6 +17,7 @@ module.exports = { 'revert', // feat(pencil): add ‘graphiteWidth’ option (撤销之前的commit) 'merge', // 合并分支, 例如: merge(前端页面): feature-xxxx修改线程地址 'release', // 发布 + 'perf', // 优化 ], ], }, diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..96df51f6 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,160 @@ +const perfectionistRecommended = require('eslint-plugin-perfectionist/configs/recommended-line-length'); +const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended'); +const perfectionist = require('eslint-plugin-perfectionist'); +const prettier = require('eslint-plugin-prettier'); +const tsEslint = require('typescript-eslint'); +// const eslint = require('@eslint/js'); +//const { FlatCompat } = require('@eslint/eslintrc'); + +//const compat = new FlatCompat({ +// baseDirectory: __dirname +//}); + +const DOMGlobals = ['window', 'document']; +const NodeGlobals = ['module', 'require']; + +const banConstEnum = { + message: 'Please use non-const enums. This project automatically inlines enums.', + selector: 'TSEnumDeclaration[const=true]', +}; + +module.exports = tsEslint.config( + { + rules: { + 'perfectionist/sort-imports': [ + 'error', + { + 'newlines-between': 'never', + type: 'line-length', + order: 'desc', + groups: [], + }, + ], + // Enforce the use of 'import type' for importing types + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + fixStyle: 'inline-type-imports', + disallowTypeAnnotations: false, + }, + ], + // 优先使用 interface 而不是 type + '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], + // most of the codebase are expected to be env agnostic + 'no-restricted-globals': ['error', ...DOMGlobals, ...NodeGlobals], + 'no-console': ['error', { allow: ['warn', 'error', 'info'] }], + + // Enforce the use of top-level import type qualifier when an import only has specifiers with inline type qualifiers + '@typescript-eslint/no-import-type-side-effects': 'error', + // code to indicate intentional type errors, improving code clarity and maintainability. + '@typescript-eslint/prefer-ts-expect-error': 'error', + // This rule enforces the preference for using '@ts-expect-error' comments in TypeScript + 'no-restricted-syntax': ['error', banConstEnum], + 'perfectionist/sort-exports': 'off', + 'no-debugger': 'error', + 'sort-imports': 'off', + // 禁止 == 判断 + eqeqeq: 'error', + }, + extends: [ + // eslint.configs.recommended, + tsEslint.configs.base, + eslintPluginPrettierRecommended, + perfectionistRecommended, + ], + plugins: { + // 'import-x': importX, + perfectionist, + prettier, + }, + files: ['**/*.js', '**/*.ts', '**/*.tsx'], + }, + + // tests, no restrictions (runs in Node / Vitest with jsdom) + { + rules: { + 'no-restricted-globals': 'off', + 'no-restricted-syntax': 'off', + 'no-console': 'off', + }, + files: ['**/__tests__/**', 'packages/dts-test/**'], + languageOptions: { + globals: {}, + }, + plugins: {}, + }, + + // JavaScript files + { + rules: { + // We only do `no-unused-vars` checks for js files, TS files are checked by TypeScript itself. + 'no-unused-vars': ['error', { args: 'none', vars: 'all' }], + }, + files: ['*.js'], + }, + { + rules: { + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + eqeqeq: 'off', + }, + files: ['**/__tests__/**'], + }, + { + rules: { + '@typescript-eslint/no-var-requires': 'off', + eqeqeq: 'off', + }, + files: ['**/scripts/**.[jt]s', 'rollup.config.js'], + }, + + // Node scripts + { + rules: { + 'no-restricted-syntax': ['error', banConstEnum], + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + 'no-restricted-globals': 'off', + 'no-console': 'off', + 'no-undef': 'off', + }, + files: [ + 'eslint.config.js', + 'rollup*.config.js', + 'scripts/**', + './*.{js,ts}', + 'packages/*/*.js', + '.prettierrc.js', + 'jest.config.js', + 'commitlint.config.js', + ], + }, + + { + ignores: [ + '*.sh', + 'node_modules', + '*.md', + '*.woff', + '*.ttf', + '.vscode', + '.idea', + 'dist', + '/public', + '/docs', + '.husky', + '.local', + '/bin', + '.eslintrc.js', + 'prettier.config.js', + '/src/mock/*', + 'coverage', + '.github', + 'pnpm-lock.yaml', + '.output', + '*.d.ts', + 'temp', + ], + }, +); diff --git a/package.json b/package.json index cae871ea..331974e6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@tool-pack/basic", - "version": "0.0.18", - "packageManager": "pnpm@7.1.0", + "version": "0.9.6", + "packageManager": "pnpm@9.3.0", "sideEffects": false, "description": "🛠 typescript javascript basic utils functions / 基础工具函数", "scripts": { @@ -10,15 +10,15 @@ "check-deps": "ncu", "test": "jest", "cov": "jest --coverage", - "prepare": "husky install && npm run pkg:init", + "prepare:废弃 script,会被 npm publish 触发": "husky install && npm run pkg:init", "husky-msg-init": "husky add .husky/pre-commit \"npx lint-staged --allow-empty \"$1\"\"&husky add .husky/commit-msg \"npx commitlint --edit \"$1\"\"", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", "ts-check": "tsc --noEmit && tsc -p ./tsconfig.node.json --noEmit", - "lint-check": "eslint .", + "lint-check": "eslint \"**/*.ts\"", "prettier-check": "prettier ./ --check", "check-all": "run-p ts-check lint-check prettier-check", "typedoc:build": "typedoc", - "typedoc:deploy": "gh-pages -d docs-html", + "typedoc:deploy": "gh-pages -d docs-dist", "build": "esno scripts/build.ts -t", "release": "esno scripts/release.ts", "yalc:publish": "yalc publish", @@ -49,53 +49,55 @@ }, "homepage": "https://github.com/js-tool-pack/basic#readme", "devDependencies": { - "@babel/core": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/parser": "^7.21.4", - "@babel/preset-typescript": "^7.21.4", - "@babel/types": "^7.21.4", - "@commitlint/cli": "^17.6.1", - "@commitlint/config-conventional": "^17.6.1", - "@microsoft/api-extractor": "^7.34.4", + "@babel/core": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/preset-typescript": "^7.24.7", + "@babel/types": "^7.24.7", + "@commitlint/cli": "^19.3.0", + "@commitlint/config-conventional": "^19.2.2", + "@microsoft/api-extractor": "^7.47.0", "@mxssfd/core": "5.0.1-beta.1", - "@mxssfd/typedoc-theme": "^1.1.1", - "@rollup/plugin-json": "^6.0.0", - "@types/babel__generator": "^7.6.4", - "@types/fs-extra": "^11.0.1", - "@types/jest": "^29.5.1", - "@types/minimist": "^1.2.2", - "@types/node": "^18.15.11", - "@types/semver": "^7.3.13", - "@typescript-eslint/eslint-plugin": "^5.59.0", - "@typescript-eslint/parser": "^5.59.0", - "chalk": "^5.2.0", - "conventional-changelog-cli": "^2.2.2", - "core-js": "^3.30.1", - "enquirer": "^2.3.6", - "eslint": "^8.38.0", - "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^4.2.1", - "esno": "^0.16.3", - "execa": "^7.1.1", - "fs-extra": "^11.1.1", - "gh-pages": "^5.0.0", - "husky": "^8.0.3", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", - "lint-staged": "^13.2.1", + "@mxssfd/typedoc-theme": "^1.1.5", + "@rollup/plugin-json": "^6.1.0", + "@types/babel__generator": "^7.6.8", + "@types/fs-extra": "^11.0.4", + "@types/jest": "^29.5.12", + "@types/minimist": "^1.2.5", + "@types/node": "^20.14.4", + "@types/semver": "^7.5.8", + "@typescript-eslint/eslint-plugin": "^7.13.1", + "@typescript-eslint/parser": "^7.13.1", + "chalk": "^5.3.0", + "conventional-changelog-cli": "^5.0.0", + "core-js": "^3.37.1", + "enquirer": "^2.4.1", + "eslint": "^9.5.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-perfectionist": "^2.11.0", + "eslint-plugin-prettier": "^5.1.3", + "esno": "^4.7.0", + "execa": "^9.2.0", + "fs-extra": "^11.2.0", + "gh-pages": "^6.1.1", + "husky": "^9.0.11", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "lint-staged": "^15.2.7", "minimist": "^1.2.8", - "npm-check-updates": "^16.10.8", + "npm-check-updates": "^16.14.20", "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", - "rimraf": "^4.4.1", - "rollup": "^3.20.6", + "prettier": "^3.3.2", + "rimraf": "^5.0.7", + "rollup": "^4.18.0", "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-typescript2": "^0.34.1", - "semver": "^7.5.0", - "ts-jest": "^29.1.0", - "tslib": "^2.5.0", - "typedoc": "^0.24.4", - "typescript": "^5.0.4" + "rollup-plugin-typescript2": "^0.36.0", + "semver": "^7.6.2", + "ts-jest": "^29.1.5", + "tslib": "^2.6.3", + "typedoc": "^0.26.2", + "typescript": "~5.4.5", + "typescript-eslint": "^7.13.1" }, "files": [ "dist", @@ -104,14 +106,18 @@ ], "main": "dist/basic.cjs.js", "module": "dist/basic.esm-bundler.js", - "types": "dist/basic.d.ts", + "types": "./dist/basic.d.ts", "exports": { ".": { "import": { + "types": "./dist/basic.d.ts", "node": "./dist/basic.cjs.js", "default": "./dist/basic.esm-bundler.js" }, - "require": "./dist/basic.cjs.js" + "require": { + "types": "./dist/basic.d.ts", + "default": "./dist/basic.cjs.js" + } } }, "buildOptions": { @@ -128,6 +134,6 @@ "registry": "https://registry.npmjs.org/" }, "dependencies": { - "@tool-pack/types": "^0.0.2" + "@tool-pack/types": "^0.3.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b60fa761..262e98ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,3318 +1,6400 @@ -lockfileVersion: 5.4 - -specifiers: - '@babel/core': ^7.21.4 - '@babel/generator': ^7.21.4 - '@babel/parser': ^7.21.4 - '@babel/preset-typescript': ^7.21.4 - '@babel/types': ^7.21.4 - '@commitlint/cli': ^17.6.1 - '@commitlint/config-conventional': ^17.6.1 - '@microsoft/api-extractor': ^7.34.4 - '@mxssfd/core': 5.0.1-beta.1 - '@mxssfd/typedoc-theme': ^1.1.1 - '@rollup/plugin-json': ^6.0.0 - '@tool-pack/types': ^0.0.2 - '@types/babel__generator': ^7.6.4 - '@types/fs-extra': ^11.0.1 - '@types/jest': ^29.5.1 - '@types/minimist': ^1.2.2 - '@types/node': ^18.15.11 - '@types/semver': ^7.3.13 - '@typescript-eslint/eslint-plugin': ^5.59.0 - '@typescript-eslint/parser': ^5.59.0 - chalk: ^5.2.0 - conventional-changelog-cli: ^2.2.2 - core-js: ^3.30.1 - enquirer: ^2.3.6 - eslint: ^8.38.0 - eslint-config-prettier: ^8.8.0 - eslint-plugin-prettier: ^4.2.1 - esno: ^0.16.3 - execa: ^7.1.1 - fs-extra: ^11.1.1 - gh-pages: ^5.0.0 - husky: ^8.0.3 - jest: ^29.5.0 - jest-environment-jsdom: ^29.5.0 - lint-staged: ^13.2.1 - minimist: ^1.2.8 - npm-check-updates: ^16.10.8 - npm-run-all: ^4.1.5 - prettier: ^2.8.7 - rimraf: ^4.4.1 - rollup: ^3.20.6 - rollup-plugin-terser: ^7.0.2 - rollup-plugin-typescript2: ^0.34.1 - semver: ^7.5.0 - ts-jest: ^29.1.0 - tslib: ^2.5.0 - typedoc: ^0.24.4 - typescript: ^5.0.4 - -dependencies: - '@tool-pack/types': 0.0.2 - -devDependencies: - '@babel/core': 7.21.4 - '@babel/generator': 7.21.4 - '@babel/parser': 7.21.4 - '@babel/preset-typescript': 7.21.4_@babel+core@7.21.4 - '@babel/types': 7.21.4 - '@commitlint/cli': 17.6.1 - '@commitlint/config-conventional': 17.6.1 - '@microsoft/api-extractor': 7.34.4_@types+node@18.15.11 - '@mxssfd/core': 5.0.1-beta.1 - '@mxssfd/typedoc-theme': 1.1.1_typedoc@0.24.4 - '@rollup/plugin-json': 6.0.0_rollup@3.20.6 - '@types/babel__generator': 7.6.4 - '@types/fs-extra': 11.0.1 - '@types/jest': 29.5.1 - '@types/minimist': 1.2.2 - '@types/node': 18.15.11 - '@types/semver': 7.3.13 - '@typescript-eslint/eslint-plugin': 5.59.0_wsbkzerfphvgr4lle7vmeh64yi - '@typescript-eslint/parser': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy - chalk: 5.2.0 - conventional-changelog-cli: 2.2.2 - core-js: 3.30.1 - enquirer: 2.3.6 - eslint: 8.38.0 - eslint-config-prettier: 8.8.0_eslint@8.38.0 - eslint-plugin-prettier: 4.2.1_mrzcadguhkbme6yx3ehduvsjxu - esno: 0.16.3 - execa: 7.1.1 - fs-extra: 11.1.1 - gh-pages: 5.0.0 - husky: 8.0.3 - jest: 29.5.0_@types+node@18.15.11 - jest-environment-jsdom: 29.5.0 - lint-staged: 13.2.1_enquirer@2.3.6 - minimist: 1.2.8 - npm-check-updates: 16.10.8 - npm-run-all: 4.1.5 - prettier: 2.8.7 - rimraf: 4.4.1 - rollup: 3.20.6 - rollup-plugin-terser: 7.0.2_rollup@3.20.6 - rollup-plugin-typescript2: 0.34.1_7z4wb4mnpapsgobacn7mivmt6i - semver: 7.5.0 - ts-jest: 29.1.0_ein22xsozyc5ohjtbndctplfiq - tslib: 2.5.0 - typedoc: 0.24.4_typescript@5.0.4 - typescript: 5.0.4 +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@tool-pack/types': + specifier: ^0.3.0 + version: 0.3.0 + devDependencies: + '@babel/core': + specifier: ^7.24.7 + version: 7.24.7 + '@babel/generator': + specifier: ^7.24.7 + version: 7.24.7 + '@babel/parser': + specifier: ^7.24.7 + version: 7.24.7 + '@babel/preset-typescript': + specifier: ^7.24.7 + version: 7.24.7(@babel/core@7.24.7) + '@babel/types': + specifier: ^7.24.7 + version: 7.24.7 + '@commitlint/cli': + specifier: ^19.3.0 + version: 19.3.0(@types/node@20.14.4)(typescript@5.4.5) + '@commitlint/config-conventional': + specifier: ^19.2.2 + version: 19.2.2 + '@microsoft/api-extractor': + specifier: ^7.47.0 + version: 7.47.0(@types/node@20.14.4) + '@mxssfd/core': + specifier: 5.0.1-beta.1 + version: 5.0.1-beta.1 + '@mxssfd/typedoc-theme': + specifier: ^1.1.5 + version: 1.1.5(typedoc@0.26.2(typescript@5.4.5)) + '@rollup/plugin-json': + specifier: ^6.1.0 + version: 6.1.0(rollup@4.18.0) + '@types/babel__generator': + specifier: ^7.6.8 + version: 7.6.8 + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 + '@types/jest': + specifier: ^29.5.12 + version: 29.5.12 + '@types/minimist': + specifier: ^1.2.5 + version: 1.2.5 + '@types/node': + specifier: ^20.14.4 + version: 20.14.4 + '@types/semver': + specifier: ^7.5.8 + version: 7.5.8 + '@typescript-eslint/eslint-plugin': + specifier: ^7.13.1 + version: 7.13.1(@typescript-eslint/parser@7.13.1(eslint@9.5.0)(typescript@5.4.5))(eslint@9.5.0)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^7.13.1 + version: 7.13.1(eslint@9.5.0)(typescript@5.4.5) + chalk: + specifier: ^5.3.0 + version: 5.3.0 + conventional-changelog-cli: + specifier: ^5.0.0 + version: 5.0.0(conventional-commits-filter@5.0.0) + core-js: + specifier: ^3.37.1 + version: 3.37.1 + enquirer: + specifier: ^2.4.1 + version: 2.4.1 + eslint: + specifier: ^9.5.0 + version: 9.5.0 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@9.5.0) + eslint-plugin-perfectionist: + specifier: ^2.11.0 + version: 2.11.0(eslint@9.5.0)(typescript@5.4.5) + eslint-plugin-prettier: + specifier: ^5.1.3 + version: 5.1.3(eslint-config-prettier@9.1.0(eslint@9.5.0))(eslint@9.5.0)(prettier@3.3.2) + esno: + specifier: ^4.7.0 + version: 4.7.0 + execa: + specifier: ^9.2.0 + version: 9.2.0 + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 + gh-pages: + specifier: ^6.1.1 + version: 6.1.1 + husky: + specifier: ^9.0.11 + version: 9.0.11 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)) + jest-environment-jsdom: + specifier: ^29.7.0 + version: 29.7.0 + lint-staged: + specifier: ^15.2.7 + version: 15.2.7 + minimist: + specifier: ^1.2.8 + version: 1.2.8 + npm-check-updates: + specifier: ^16.14.20 + version: 16.14.20 + npm-run-all: + specifier: ^4.1.5 + version: 4.1.5 + prettier: + specifier: ^3.3.2 + version: 3.3.2 + rimraf: + specifier: ^5.0.7 + version: 5.0.7 + rollup: + specifier: ^4.18.0 + version: 4.18.0 + rollup-plugin-terser: + specifier: ^7.0.2 + version: 7.0.2(rollup@4.18.0) + rollup-plugin-typescript2: + specifier: ^0.36.0 + version: 0.36.0(rollup@4.18.0)(typescript@5.4.5) + semver: + specifier: ^7.6.2 + version: 7.6.2 + ts-jest: + specifier: ^29.1.5 + version: 29.1.5(@babel/core@7.24.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(jest@29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)))(typescript@5.4.5) + tslib: + specifier: ^2.6.3 + version: 2.6.3 + typedoc: + specifier: ^0.26.2 + version: 0.26.2(typescript@5.4.5) + typescript: + specifier: ~5.4.5 + version: 5.4.5 + typescript-eslint: + specifier: ^7.13.1 + version: 7.13.1(eslint@9.5.0)(typescript@5.4.5) packages: - /@ampproject/remapping/2.2.1: - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - /@babel/code-frame/7.21.4: - resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.18.6 - dev: true - /@babel/compat-data/7.21.4: - resolution: {integrity: sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==} + '@babel/compat-data@7.24.7': + resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==} engines: {node: '>=6.9.0'} - dev: true - /@babel/core/7.21.4: - resolution: {integrity: sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==} + '@babel/core@7.24.7': + resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==} engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.21.4 - '@babel/helper-compilation-targets': 7.21.4_@babel+core@7.21.4 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helpers': 7.21.0 - '@babel/parser': 7.21.4 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.21.4 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/generator/7.21.4: - resolution: {integrity: sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==} + '@babel/generator@7.24.7': + resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.4 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - jsesc: 2.5.2 - dev: true - /@babel/helper-annotate-as-pure/7.18.6: - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} + '@babel/helper-annotate-as-pure@7.24.7': + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.4 - dev: true - /@babel/helper-compilation-targets/7.21.4_@babel+core@7.21.4: - resolution: {integrity: sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==} + '@babel/helper-compilation-targets@7.24.7': + resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.21.4 - '@babel/core': 7.21.4 - '@babel/helper-validator-option': 7.21.0 - browserslist: 4.21.5 - lru-cache: 5.1.1 - semver: 6.3.0 - dev: true - /@babel/helper-create-class-features-plugin/7.21.4_@babel+core@7.21.4: - resolution: {integrity: sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==} + '@babel/helper-create-class-features-plugin@7.24.7': + resolution: {integrity: sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-member-expression-to-functions': 7.21.0 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-replace-supers': 7.20.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/helper-split-export-declaration': 7.18.6 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/helper-environment-visitor/7.18.9: - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + '@babel/helper-environment-visitor@7.24.7': + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-function-name/7.21.0: - resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} + '@babel/helper-function-name@7.24.7': + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.20.7 - '@babel/types': 7.21.4 - dev: true - /@babel/helper-hoist-variables/7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + '@babel/helper-hoist-variables@7.24.7': + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.4 - dev: true - /@babel/helper-member-expression-to-functions/7.21.0: - resolution: {integrity: sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==} + '@babel/helper-member-expression-to-functions@7.24.7': + resolution: {integrity: sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.4 - dev: true - /@babel/helper-module-imports/7.21.4: - resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==} + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.4 - dev: true - /@babel/helper-module-transforms/7.21.2: - resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==} + '@babel/helper-module-transforms@7.24.7': + resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-simple-access': 7.20.2 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.21.4 - transitivePeerDependencies: - - supports-color - dev: true + peerDependencies: + '@babel/core': ^7.0.0 - /@babel/helper-optimise-call-expression/7.18.6: - resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} + '@babel/helper-optimise-call-expression@7.24.7': + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.4 - dev: true - /@babel/helper-plugin-utils/7.20.2: - resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} + '@babel/helper-plugin-utils@7.24.7': + resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==} engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-replace-supers/7.20.7: - resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} + '@babel/helper-replace-supers@7.24.7': + resolution: {integrity: sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-member-expression-to-functions': 7.21.0 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.21.4 - transitivePeerDependencies: - - supports-color - dev: true + peerDependencies: + '@babel/core': ^7.0.0 - /@babel/helper-simple-access/7.20.2: - resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.4 - dev: true - /@babel/helper-skip-transparent-expression-wrappers/7.20.0: - resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.4 - dev: true - /@babel/helper-split-export-declaration/7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.21.4 - dev: true - /@babel/helper-string-parser/7.19.4: - resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} + '@babel/helper-string-parser@7.24.7': + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-validator-identifier/7.19.1: - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-validator-option/7.21.0: - resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} + '@babel/helper-validator-option@7.24.7': + resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==} engines: {node: '>=6.9.0'} - dev: true - /@babel/helpers/7.21.0: - resolution: {integrity: sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==} + '@babel/helpers@7.24.7': + resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.21.4 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/highlight/7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.19.1 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true - /@babel/parser/7.21.4: - resolution: {integrity: sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==} + '@babel/parser@7.24.7': + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} engines: {node: '>=6.0.0'} hasBin: true - dependencies: - '@babel/types': 7.21.4 - dev: true - /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.21.4: + '@babel/plugin-syntax-async-generators@7.8.4': resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-bigint/7.8.3_@babel+core@7.21.4: + '@babel/plugin-syntax-bigint@7.8.3': resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.21.4: + '@babel/plugin-syntax-class-properties@7.12.13': resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.21.4: + '@babel/plugin-syntax-import-meta@7.10.4': resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.21.4: + '@babel/plugin-syntax-json-strings@7.8.3': resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-jsx/7.21.4_@babel+core@7.21.4: - resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} + '@babel/plugin-syntax-jsx@7.24.7': + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-logical-assignment-operators/7.10.4_@babel+core@7.21.4: + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-nullish-coalescing-operator/7.8.3_@babel+core@7.21.4: + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-numeric-separator/7.10.4_@babel+core@7.21.4: + '@babel/plugin-syntax-numeric-separator@7.10.4': resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-object-rest-spread/7.8.3_@babel+core@7.21.4: + '@babel/plugin-syntax-object-rest-spread@7.8.3': resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-optional-catch-binding/7.8.3_@babel+core@7.21.4: + '@babel/plugin-syntax-optional-catch-binding@7.8.3': resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-optional-chaining/7.8.3_@babel+core@7.21.4: + '@babel/plugin-syntax-optional-chaining@7.8.3': resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.21.4: + '@babel/plugin-syntax-top-level-await@7.14.5': resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-syntax-typescript/7.21.4_@babel+core@7.21.4: - resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==} + '@babel/plugin-syntax-typescript@7.24.7': + resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - /@babel/plugin-transform-modules-commonjs/7.21.2_@babel+core@7.21.4: - resolution: {integrity: sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==} + '@babel/plugin-transform-modules-commonjs@7.24.7': + resolution: {integrity: sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.20.2 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/plugin-transform-typescript/7.21.3_@babel+core@7.21.4: - resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==} + '@babel/plugin-transform-typescript@7.24.7': + resolution: {integrity: sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.21.4_@babel+core@7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-typescript': 7.21.4_@babel+core@7.21.4 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/preset-typescript/7.21.4_@babel+core@7.21.4: - resolution: {integrity: sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==} + '@babel/preset-typescript@7.24.7': + resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-validator-option': 7.21.0 - '@babel/plugin-syntax-jsx': 7.21.4_@babel+core@7.21.4 - '@babel/plugin-transform-modules-commonjs': 7.21.2_@babel+core@7.21.4 - '@babel/plugin-transform-typescript': 7.21.3_@babel+core@7.21.4 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/template/7.20.7: - resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} + '@babel/template@7.24.7': + resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.21.4 - '@babel/parser': 7.21.4 - '@babel/types': 7.21.4 - dev: true - /@babel/traverse/7.21.4: - resolution: {integrity: sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==} + '@babel/traverse@7.24.7': + resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.21.4 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.21.4 - '@babel/types': 7.21.4 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/types/7.21.4: - resolution: {integrity: sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==} + '@babel/types@7.24.7': + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.19.4 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: true - /@bcoe/v8-coverage/0.2.3: + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true - /@colors/colors/1.5.0: + '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - requiresBuild: true - dev: true - optional: true - /@commitlint/cli/17.6.1: - resolution: {integrity: sha512-kCnDD9LE2ySiTnj/VPaxy4/oRayRcdv4aCuVxtoum8SxIU7OADHc0nJPQfheE8bHcs3zZdWzDMWltRosuT13bg==} - engines: {node: '>=v14'} + '@commitlint/cli@19.3.0': + resolution: {integrity: sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==} + engines: {node: '>=v18'} hasBin: true - dependencies: - '@commitlint/format': 17.4.4 - '@commitlint/lint': 17.6.1 - '@commitlint/load': 17.5.0 - '@commitlint/read': 17.5.1 - '@commitlint/types': 17.4.4 - execa: 5.1.1 - lodash.isfunction: 3.0.9 - resolve-from: 5.0.0 - resolve-global: 1.0.0 - yargs: 17.7.1 - transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - dev: true - /@commitlint/config-conventional/17.6.1: - resolution: {integrity: sha512-ng/ybaSLuTCH9F+7uavSOnEQ9EFMl7lHEjfAEgRh1hwmEe8SpLKpQeMo2aT1IWvHaGMuTb+gjfbzoRf2IR23NQ==} - engines: {node: '>=v14'} - dependencies: - conventional-changelog-conventionalcommits: 5.0.0 - dev: true + '@commitlint/config-conventional@19.2.2': + resolution: {integrity: sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==} + engines: {node: '>=v18'} - /@commitlint/config-validator/17.4.4: - resolution: {integrity: sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/types': 17.4.4 - ajv: 8.12.0 - dev: true + '@commitlint/config-validator@19.0.3': + resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} + engines: {node: '>=v18'} - /@commitlint/ensure/17.4.4: - resolution: {integrity: sha512-AHsFCNh8hbhJiuZ2qHv/m59W/GRE9UeOXbkOqxYMNNg9pJ7qELnFcwj5oYpa6vzTSHtPGKf3C2yUFNy1GGHq6g==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/types': 17.4.4 - lodash.camelcase: 4.3.0 - lodash.kebabcase: 4.1.1 - lodash.snakecase: 4.1.1 - lodash.startcase: 4.4.0 - lodash.upperfirst: 4.3.1 - dev: true + '@commitlint/ensure@19.0.3': + resolution: {integrity: sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==} + engines: {node: '>=v18'} - /@commitlint/execute-rule/17.4.0: - resolution: {integrity: sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==} - engines: {node: '>=v14'} - dev: true + '@commitlint/execute-rule@19.0.0': + resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} + engines: {node: '>=v18'} - /@commitlint/format/17.4.4: - resolution: {integrity: sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/types': 17.4.4 - chalk: 4.1.2 - dev: true - - /@commitlint/is-ignored/17.4.4: - resolution: {integrity: sha512-Y3eo1SFJ2JQDik4rWkBC4tlRIxlXEFrRWxcyrzb1PUT2k3kZ/XGNuCDfk/u0bU2/yS0tOA/mTjFsV+C4qyACHw==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/types': 17.4.4 - semver: 7.3.8 - dev: true - - /@commitlint/lint/17.6.1: - resolution: {integrity: sha512-VARJ9kxH64isgwVnC+ABPafCYzqxpsWJIpDaTuI0gh8aX4GQ0i7cn9tvxtFNfJj4ER2BAJeWJ0vURdNYjK2RQQ==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/is-ignored': 17.4.4 - '@commitlint/parse': 17.4.4 - '@commitlint/rules': 17.6.1 - '@commitlint/types': 17.4.4 - dev: true - - /@commitlint/load/17.5.0: - resolution: {integrity: sha512-l+4W8Sx4CD5rYFsrhHH8HP01/8jEP7kKf33Xlx2Uk2out/UKoKPYMOIRcDH5ppT8UXLMV+x6Wm5osdRKKgaD1Q==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/config-validator': 17.4.4 - '@commitlint/execute-rule': 17.4.0 - '@commitlint/resolve-extends': 17.4.4 - '@commitlint/types': 17.4.4 - '@types/node': 18.15.11 - chalk: 4.1.2 - cosmiconfig: 8.1.3 - cosmiconfig-typescript-loader: 4.3.0_zulaepqzabcjiyzbkdbfeduf6u - lodash.isplainobject: 4.0.6 - lodash.merge: 4.6.2 - lodash.uniq: 4.5.0 - resolve-from: 5.0.0 - ts-node: 10.9.1_bhanhq442dy43ncydsavgi4jfi - typescript: 5.0.4 - transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' - dev: true - - /@commitlint/message/17.4.2: - resolution: {integrity: sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==} - engines: {node: '>=v14'} - dev: true - - /@commitlint/parse/17.4.4: - resolution: {integrity: sha512-EKzz4f49d3/OU0Fplog7nwz/lAfXMaDxtriidyGF9PtR+SRbgv4FhsfF310tKxs6EPj8Y+aWWuX3beN5s+yqGg==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/types': 17.4.4 - conventional-changelog-angular: 5.0.13 - conventional-commits-parser: 3.2.4 - dev: true - - /@commitlint/read/17.5.1: - resolution: {integrity: sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/top-level': 17.4.0 - '@commitlint/types': 17.4.4 - fs-extra: 11.1.1 - git-raw-commits: 2.0.11 - minimist: 1.2.8 - dev: true + '@commitlint/format@19.3.0': + resolution: {integrity: sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==} + engines: {node: '>=v18'} - /@commitlint/resolve-extends/17.4.4: - resolution: {integrity: sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/config-validator': 17.4.4 - '@commitlint/types': 17.4.4 - import-fresh: 3.3.0 - lodash.mergewith: 4.6.2 - resolve-from: 5.0.0 - resolve-global: 1.0.0 - dev: true + '@commitlint/is-ignored@19.2.2': + resolution: {integrity: sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==} + engines: {node: '>=v18'} - /@commitlint/rules/17.6.1: - resolution: {integrity: sha512-lUdHw6lYQ1RywExXDdLOKxhpp6857/4c95Dc/1BikrHgdysVUXz26yV0vp1GL7Gv+avx9WqZWTIVB7pNouxlfw==} - engines: {node: '>=v14'} - dependencies: - '@commitlint/ensure': 17.4.4 - '@commitlint/message': 17.4.2 - '@commitlint/to-lines': 17.4.0 - '@commitlint/types': 17.4.4 - execa: 5.1.1 - dev: true + '@commitlint/lint@19.2.2': + resolution: {integrity: sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==} + engines: {node: '>=v18'} - /@commitlint/to-lines/17.4.0: - resolution: {integrity: sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==} - engines: {node: '>=v14'} - dev: true + '@commitlint/load@19.2.0': + resolution: {integrity: sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==} + engines: {node: '>=v18'} - /@commitlint/top-level/17.4.0: - resolution: {integrity: sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==} - engines: {node: '>=v14'} - dependencies: - find-up: 5.0.0 - dev: true + '@commitlint/message@19.0.0': + resolution: {integrity: sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==} + engines: {node: '>=v18'} - /@commitlint/types/17.4.4: - resolution: {integrity: sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==} - engines: {node: '>=v14'} - dependencies: - chalk: 4.1.2 - dev: true + '@commitlint/parse@19.0.3': + resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} + engines: {node: '>=v18'} - /@cspotcode/source-map-support/0.8.1: - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - dev: true + '@commitlint/read@19.2.1': + resolution: {integrity: sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==} + engines: {node: '>=v18'} - /@esbuild-kit/cjs-loader/2.4.2: - resolution: {integrity: sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==} - dependencies: - '@esbuild-kit/core-utils': 3.1.0 - get-tsconfig: 4.5.0 - dev: true + '@commitlint/resolve-extends@19.1.0': + resolution: {integrity: sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==} + engines: {node: '>=v18'} - /@esbuild-kit/core-utils/3.1.0: - resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==} - dependencies: - esbuild: 0.17.17 - source-map-support: 0.5.21 - dev: true + '@commitlint/rules@19.0.3': + resolution: {integrity: sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==} + engines: {node: '>=v18'} - /@esbuild-kit/esm-loader/2.5.5: - resolution: {integrity: sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==} - dependencies: - '@esbuild-kit/core-utils': 3.1.0 - get-tsconfig: 4.5.0 - dev: true + '@commitlint/to-lines@19.0.0': + resolution: {integrity: sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==} + engines: {node: '>=v18'} + + '@commitlint/top-level@19.0.0': + resolution: {integrity: sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==} + engines: {node: '>=v18'} + + '@commitlint/types@19.0.3': + resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} + engines: {node: '>=v18'} + + '@conventional-changelog/git-client@1.0.1': + resolution: {integrity: sha512-PJEqBwAleffCMETaVm/fUgHldzBE35JFk3/9LL6NUA5EXa3qednu+UT6M7E5iBu3zIQZCULYIiZ90fBYHt6xUw==} + engines: {node: '>=18'} + peerDependencies: + conventional-commits-filter: ^5.0.0 + conventional-commits-parser: ^6.0.0 + peerDependenciesMeta: + conventional-commits-filter: + optional: true + conventional-commits-parser: + optional: true - /@esbuild/android-arm/0.17.17: - resolution: {integrity: sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==} + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-arm64/0.17.17: - resolution: {integrity: sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==} + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} cpu: [arm64] os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-x64/0.17.17: - resolution: {integrity: sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==} + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} cpu: [x64] os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/darwin-arm64/0.17.17: - resolution: {integrity: sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==} + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@esbuild/darwin-x64/0.17.17: - resolution: {integrity: sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==} + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] - requiresBuild: true - dev: true - optional: true - /@esbuild/freebsd-arm64/0.17.17: - resolution: {integrity: sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==} + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/freebsd-x64/0.17.17: - resolution: {integrity: sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==} + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-arm/0.17.17: - resolution: {integrity: sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==} + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} - cpu: [arm] + cpu: [arm64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-arm64/0.17.17: - resolution: {integrity: sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==} + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} - cpu: [arm64] + cpu: [arm] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-ia32/0.17.17: - resolution: {integrity: sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==} + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-loong64/0.17.17: - resolution: {integrity: sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==} + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-mips64el/0.17.17: - resolution: {integrity: sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==} + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-ppc64/0.17.17: - resolution: {integrity: sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==} + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-riscv64/0.17.17: - resolution: {integrity: sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==} + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-s390x/0.17.17: - resolution: {integrity: sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==} + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} cpu: [s390x] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-x64/0.17.17: - resolution: {integrity: sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==} + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/netbsd-x64/0.17.17: - resolution: {integrity: sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==} + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/openbsd-x64/0.17.17: - resolution: {integrity: sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==} + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/sunos-x64/0.17.17: - resolution: {integrity: sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==} + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-arm64/0.17.17: - resolution: {integrity: sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==} + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-ia32/0.17.17: - resolution: {integrity: sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==} + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} cpu: [ia32] os: [win32] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-x64/0.17.17: - resolution: {integrity: sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==} + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} cpu: [x64] os: [win32] - requiresBuild: true - dev: true - optional: true - /@eslint-community/eslint-utils/4.4.0_eslint@8.38.0: + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.38.0 - eslint-visitor-keys: 3.4.0 - dev: true - /@eslint-community/regexpp/4.5.0: - resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==} + '@eslint-community/regexpp@4.10.1': + resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true - /@eslint/eslintrc/2.0.2: - resolution: {integrity: sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.5.1 - globals: 13.20.0 - ignore: 5.2.4 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true + '@eslint/config-array@0.16.0': + resolution: {integrity: sha512-/jmuSd74i4Czf1XXn7wGRWZCuyaUZ330NH1Bek0Pplatt4Sy1S5haN21SCLLdbeKslQ+S0wEJ+++v5YibSi+Lg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /@eslint/js/8.38.0: - resolution: {integrity: sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /@gar/promisify/1.1.3: - resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} - dev: true + '@eslint/js@9.5.0': + resolution: {integrity: sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /@humanwhocodes/config-array/0.11.8: - resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@gar/promisify@1.1.3': + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} - /@humanwhocodes/module-importer/1.0.1: + '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - dev: true - /@humanwhocodes/object-schema/1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - dev: true + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} + engines: {node: '>=18.18'} - /@hutson/parse-repository-url/3.0.2: - resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} - engines: {node: '>=6.9.0'} - dev: true + '@hutson/parse-repository-url@5.0.0': + resolution: {integrity: sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==} + engines: {node: '>=10.13.0'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} - /@istanbuljs/load-nyc-config/1.1.0: + '@istanbuljs/load-nyc-config@1.1.0': resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - dev: true - /@istanbuljs/schema/0.1.3: + '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} - dev: true - /@jest/console/29.5.0: - resolution: {integrity: sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==} + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@types/node': 18.15.11 - chalk: 4.1.2 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - slash: 3.0.0 - dev: true - /@jest/core/29.5.0: - resolution: {integrity: sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==} + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - dependencies: - '@jest/console': 29.5.0 - '@jest/reporters': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.15.11 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.8.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.5.0 - jest-config: 29.5.0_@types+node@18.15.11 - jest-haste-map: 29.5.0 - jest-message-util: 29.5.0 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-resolve-dependencies: 29.5.0 - jest-runner: 29.5.0 - jest-runtime: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - jest-watcher: 29.5.0 - micromatch: 4.0.5 - pretty-format: 29.5.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - supports-color - - ts-node - dev: true - /@jest/environment/29.5.0: - resolution: {integrity: sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==} + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/fake-timers': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.15.11 - jest-mock: 29.5.0 - dev: true - /@jest/expect-utils/29.5.0: - resolution: {integrity: sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==} + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.4.3 - dev: true - /@jest/expect/29.5.0: - resolution: {integrity: sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==} + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - expect: 29.5.0 - jest-snapshot: 29.5.0 - transitivePeerDependencies: - - supports-color - dev: true - /@jest/fake-timers/29.5.0: - resolution: {integrity: sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==} + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.5.0 - '@sinonjs/fake-timers': 10.0.2 - '@types/node': 18.15.11 - jest-message-util: 29.5.0 - jest-mock: 29.5.0 - jest-util: 29.5.0 - dev: true - /@jest/globals/29.5.0: - resolution: {integrity: sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==} + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.5.0 - '@jest/expect': 29.5.0 - '@jest/types': 29.5.0 - jest-mock: 29.5.0 - transitivePeerDependencies: - - supports-color - dev: true - /@jest/reporters/29.5.0: - resolution: {integrity: sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==} + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 18.15.11 - chalk: 4.1.2 - collect-v8-coverage: 1.0.1 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 5.2.1 - istanbul-lib-report: 3.0.0 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.5 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - jest-worker: 29.5.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.1.0 - transitivePeerDependencies: - - supports-color - dev: true - /@jest/schemas/29.4.3: - resolution: {integrity: sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==} + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@sinclair/typebox': 0.25.24 - dev: true - /@jest/source-map/29.4.3: - resolution: {integrity: sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==} + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jridgewell/trace-mapping': 0.3.18 - callsites: 3.1.0 - graceful-fs: 4.2.11 - dev: true - /@jest/test-result/29.5.0: - resolution: {integrity: sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==} + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.5.0 - '@jest/types': 29.5.0 - '@types/istanbul-lib-coverage': 2.0.4 - collect-v8-coverage: 1.0.1 - dev: true - /@jest/test-sequencer/29.5.0: - resolution: {integrity: sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==} + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.5.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - slash: 3.0.0 - dev: true - /@jest/transform/29.5.0: - resolution: {integrity: sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==} + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.21.4 - '@jest/types': 29.5.0 - '@jridgewell/trace-mapping': 0.3.18 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - jest-regex-util: 29.4.3 - jest-util: 29.5.0 - micromatch: 4.0.5 - pirates: 4.0.5 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - dev: true - /@jest/types/29.5.0: - resolution: {integrity: sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==} + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.4.3 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.1 - '@types/node': 18.15.11 - '@types/yargs': 17.0.24 - chalk: 4.1.2 - dev: true - - /@jridgewell/gen-mapping/0.3.3: - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - /@jridgewell/resolve-uri/3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} - dev: true - /@jridgewell/resolve-uri/3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - dev: true - /@jridgewell/set-array/1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/source-map/0.3.3: - resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==} - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - /@jridgewell/sourcemap-codec/1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} - /@jridgewell/sourcemap-codec/1.4.15: + '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true - /@jridgewell/trace-mapping/0.3.18: - resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - /@jridgewell/trace-mapping/0.3.9: + '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.1 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /@microsoft/api-extractor-model/7.26.4_@types+node@18.15.11: - resolution: {integrity: sha512-PDCgCzXDo+SLY5bsfl4bS7hxaeEtnXj7XtuzEE+BtALp7B5mK/NrS2kHWU69pohgsRmEALycQdaQPXoyT2i5MQ==} - dependencies: - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.55.2_@types+node@18.15.11 - transitivePeerDependencies: - - '@types/node' - dev: true + '@microsoft/api-extractor-model@7.29.2': + resolution: {integrity: sha512-hAYajOjQan3uslhKJRwvvHIdLJ+ZByKqdSsJ/dgHFxPtEbdKpzMDO8zuW4K5gkSMYl5D0LbNwxkhxr51P2zsmw==} - /@microsoft/api-extractor/7.34.4_@types+node@18.15.11: - resolution: {integrity: sha512-HOdcci2nT40ejhwPC3Xja9G+WSJmWhCUKKryRfQYsmE9cD+pxmBaKBKCbuS9jUcl6bLLb4Gz+h7xEN5r0QiXnQ==} + '@microsoft/api-extractor@7.47.0': + resolution: {integrity: sha512-LT8yvcWNf76EpDC+8/ArTVSYePvuDQ+YbAUrsTcpg3ptiZ93HIcMCozP/JOxDt+rrsFfFHcpfoselKfPyRI0GQ==} hasBin: true - dependencies: - '@microsoft/api-extractor-model': 7.26.4_@types+node@18.15.11 - '@microsoft/tsdoc': 0.14.2 - '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.55.2_@types+node@18.15.11 - '@rushstack/rig-package': 0.3.18 - '@rushstack/ts-command-line': 4.13.2 - colors: 1.2.5 - lodash: 4.17.21 - resolve: 1.22.2 - semver: 7.3.8 - source-map: 0.6.1 - typescript: 4.8.4 - transitivePeerDependencies: - - '@types/node' - dev: true - /@microsoft/tsdoc-config/0.16.2: - resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} - dependencies: - '@microsoft/tsdoc': 0.14.2 - ajv: 6.12.6 - jju: 1.4.0 - resolve: 1.19.0 - dev: true + '@microsoft/tsdoc-config@0.17.0': + resolution: {integrity: sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==} - /@microsoft/tsdoc/0.14.2: - resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} - dev: true + '@microsoft/tsdoc@0.15.0': + resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} - /@mxssfd/core/5.0.1-beta.1: + '@mxssfd/core@5.0.1-beta.1': resolution: {integrity: sha512-aGB3QcJRnMeIH5LBrRpcvskrm1y4iw9oj/KxYPgizzBVUomKU5y4ZMiIqQDw+myZIJHRmdFIXbrwijIsdy73zQ==} - dependencies: - '@mxssfd/types': 5.0.1-beta.1 - dev: true - /@mxssfd/typedoc-theme/1.1.1_typedoc@0.24.4: - resolution: {integrity: sha512-XhXy2MDoMJFeHgbE0cTxpB3K8AizQMJcm6gvf9lqNwfN6+ZfDnmIZub6lCuDgpL0O0fvckKTq7fGSP6XIU/17Q==} + '@mxssfd/typedoc-theme@1.1.5': + resolution: {integrity: sha512-5u1I8ZJib0lR9g7EwO1yJ9vGY9mS+U1JR+mAgdw0Ky9lPYOmlKSDU1VvgrAUeydWmJtskBg61e10VVPOXUj19w==} engines: {node: '>= 14'} peerDependencies: - typedoc: ^0.24.1 - dependencies: - typedoc: 0.24.4_typescript@5.0.4 - dev: true + typedoc: ^0.26.2 - /@mxssfd/types/5.0.1-beta.1: + '@mxssfd/types@5.0.1-beta.1': resolution: {integrity: sha512-tO7P3jbKP1M3Z5AJysdbfpzFeR3R+r1HVI4XcoJxRkYhgNDhnWCsUO9QYN3zaROVUp0xVGRvt0aU8qJzbF8Vlg==} - dev: true - /@nodelib/fs.scandir/2.1.5: + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - /@nodelib/fs.stat/2.0.5: + '@nodelib/fs.stat@2.0.5': resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true - /@nodelib/fs.walk/1.2.8: + '@nodelib/fs.walk@1.2.8': resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 - dev: true - /@npmcli/fs/2.1.2: + '@npmcli/fs@2.1.2': resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - '@gar/promisify': 1.1.3 - semver: 7.5.0 - dev: true - /@npmcli/fs/3.1.0: - resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==} + '@npmcli/fs@3.1.1': + resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - semver: 7.5.0 - dev: true - /@npmcli/git/4.0.4: - resolution: {integrity: sha512-5yZghx+u5M47LghaybLCkdSyFzV/w4OuH12d96HO389Ik9CDsLaDZJVynSGGVJOLn6gy/k7Dz5XYcplM3uxXRg==} + '@npmcli/git@4.1.0': + resolution: {integrity: sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - '@npmcli/promise-spawn': 6.0.2 - lru-cache: 7.18.3 - npm-pick-manifest: 8.0.1 - proc-log: 3.0.0 - promise-inflight: 1.0.1 - promise-retry: 2.0.1 - semver: 7.5.0 - which: 3.0.0 - transitivePeerDependencies: - - bluebird - dev: true - /@npmcli/installed-package-contents/2.0.2: - resolution: {integrity: sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==} + '@npmcli/installed-package-contents@2.1.0': + resolution: {integrity: sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} hasBin: true - dependencies: - npm-bundled: 3.0.0 - npm-normalize-package-bin: 3.0.0 - dev: true - /@npmcli/move-file/2.0.1: + '@npmcli/move-file@2.0.1': resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} deprecated: This functionality has been moved to @npmcli/fs - dependencies: - mkdirp: 1.0.4 - rimraf: 3.0.2 - dev: true - /@npmcli/node-gyp/3.0.0: + '@npmcli/node-gyp@3.0.0': resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: true - /@npmcli/promise-spawn/6.0.2: + '@npmcli/promise-spawn@6.0.2': resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - which: 3.0.0 - dev: true - /@npmcli/run-script/6.0.0: - resolution: {integrity: sha512-ql+AbRur1TeOdl1FY+RAwGW9fcr4ZwiVKabdvm93mujGREVuVLbdkXRJDrkTXSdCjaxYydr1wlA2v67jxWG5BQ==} + '@npmcli/run-script@6.0.2': + resolution: {integrity: sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - '@npmcli/node-gyp': 3.0.0 - '@npmcli/promise-spawn': 6.0.2 - node-gyp: 9.3.1 - read-package-json-fast: 3.0.2 - which: 3.0.0 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - /@pnpm/config.env-replace/1.1.0: + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@pnpm/config.env-replace@1.1.0': resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} engines: {node: '>=12.22.0'} - dev: true - /@pnpm/network.ca-file/1.0.2: + '@pnpm/network.ca-file@1.0.2': resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} engines: {node: '>=12.22.0'} - dependencies: - graceful-fs: 4.2.10 - dev: true - /@pnpm/npm-conf/2.1.1: - resolution: {integrity: sha512-yfRcuupmxxeDOSxvw4g+wFCrGiPD0L32f5WMzqMXp7Rl93EOCdFiDcaSNnZ10Up9GdNqkj70UTa8hfhPFphaZA==} + '@pnpm/npm-conf@2.2.2': + resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} engines: {node: '>=12'} - dependencies: - '@pnpm/config.env-replace': 1.1.0 - '@pnpm/network.ca-file': 1.0.2 - config-chain: 1.1.13 - dev: true - /@rollup/plugin-json/6.0.0_rollup@3.20.6: - resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==} + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - dependencies: - '@rollup/pluginutils': 5.0.2_rollup@3.20.6 - rollup: 3.20.6 - dev: true - /@rollup/pluginutils/4.2.1: + '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} - dependencies: - estree-walker: 2.0.2 - picomatch: 2.3.1 - dev: true - /@rollup/pluginutils/5.0.2_rollup@3.20.6: - resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - dependencies: - '@types/estree': 1.0.1 - estree-walker: 2.0.2 - picomatch: 2.3.1 - rollup: 3.20.6 - dev: true - /@rushstack/node-core-library/3.55.2_@types+node@18.15.11: - resolution: {integrity: sha512-SaLe/x/Q/uBVdNFK5V1xXvsVps0y7h1sN7aSJllQyFbugyOaxhNRF25bwEDnicARNEjJw0pk0lYnJQ9Kr6ev0A==} + '@rollup/rollup-android-arm-eabi@4.18.0': + resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.18.0': + resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.18.0': + resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.18.0': + resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.18.0': + resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.18.0': + resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.18.0': + resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.18.0': + resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.18.0': + resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.18.0': + resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.18.0': + resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.18.0': + resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==} + cpu: [x64] + os: [win32] + + '@rushstack/node-core-library@5.4.1': + resolution: {integrity: sha512-WNnwdS8r9NZ/2K3u29tNoSRldscFa7SxU0RT+82B6Dy2I4Hl2MeCSKm4EXLXPKeNzLGvJ1cqbUhTLviSF8E6iA==} peerDependencies: '@types/node': '*' peerDependenciesMeta: '@types/node': optional: true - dependencies: - '@types/node': 18.15.11 - colors: 1.2.5 - fs-extra: 7.0.1 - import-lazy: 4.0.0 - jju: 1.4.0 - resolve: 1.22.2 - semver: 7.3.8 - z-schema: 5.0.5 - dev: true - /@rushstack/rig-package/0.3.18: - resolution: {integrity: sha512-SGEwNTwNq9bI3pkdd01yCaH+gAsHqs0uxfGvtw9b0LJXH52qooWXnrFTRRLG1aL9pf+M2CARdrA9HLHJys3jiQ==} - dependencies: - resolve: 1.22.2 - strip-json-comments: 3.1.1 - dev: true + '@rushstack/rig-package@0.5.2': + resolution: {integrity: sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==} - /@rushstack/ts-command-line/4.13.2: - resolution: {integrity: sha512-bCU8qoL9HyWiciltfzg7GqdfODUeda/JpI0602kbN5YH22rzTxyqYvv7aRLENCM7XCQ1VRs7nMkEqgJUOU8Sag==} - dependencies: - '@types/argparse': 1.0.38 - argparse: 1.0.10 - colors: 1.2.5 - string-argv: 0.3.1 - dev: true + '@rushstack/terminal@0.13.0': + resolution: {integrity: sha512-Ou44Q2s81BqJu3dpYedAX54am9vn245F0HzqVrfJCMQk5pGgoKKOBOjkbfZC9QKcGNaECh6pwH2s5noJt7X6ew==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/ts-command-line@4.22.0': + resolution: {integrity: sha512-Qj28t6MO3HRgAZ72FDeFsrpdE6wBWxF3VENgvrXh7JF2qIT+CrXiOJIesW80VFZB9QwObSpkB1ilx794fGQg6g==} + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@shikijs/core@1.9.1': + resolution: {integrity: sha512-EmUful2MQtY8KgCF1OkBtOuMcvaZEvmdubhW0UHCGXi21O9dRLeADVCj+k6ZS+de7Mz9d2qixOXJ+GLhcK3pXg==} + + '@sigstore/bundle@1.1.0': + resolution: {integrity: sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/protobuf-specs@0.2.1': + resolution: {integrity: sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/sign@1.0.0': + resolution: {integrity: sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - /@sigstore/protobuf-specs/0.1.0: - resolution: {integrity: sha512-a31EnjuIDSX8IXBUib3cYLDRlPMU36AWX4xS8ysLaNu4ZzUesDiPt83pgrW2X1YLMe5L2HbDyaKK5BrL4cNKaQ==} + '@sigstore/tuf@1.0.3': + resolution: {integrity: sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: true - /@sinclair/typebox/0.25.24: - resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} - dev: true + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - /@sindresorhus/is/5.3.0: - resolution: {integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==} + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} engines: {node: '>=14.16'} - dev: true - /@sinonjs/commons/2.0.0: - resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} - dependencies: - type-detect: 4.0.8 - dev: true + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} - /@sinonjs/fake-timers/10.0.2: - resolution: {integrity: sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==} - dependencies: - '@sinonjs/commons': 2.0.0 - dev: true + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - /@szmarczak/http-timer/5.0.1: + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@szmarczak/http-timer@5.0.1': resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} - dependencies: - defer-to-connect: 2.0.1 - dev: true - /@tool-pack/types/0.0.2: - resolution: {integrity: sha512-cbhzF9gkLZ4Xe9YmBqx8szLlFSQznELcWrAEe1mFA4D/lW7c7K78FH2v60K1Zib0tRMZ1cZfJMd4lJlh12/G9A==} - dev: false + '@tool-pack/types@0.3.0': + resolution: {integrity: sha512-JjiuX2YL67PnVesIexsSvKsZeAU+whjvXrUzqij5nXWLCuRGnRAIass1+t/tyZWDtOj1dAcdIccTlnGi/DLh9g==} - /@tootallnate/once/2.0.0: + '@tootallnate/once@2.0.0': resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} - dev: true - /@tsconfig/node10/1.0.9: - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - dev: true + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} - /@tsconfig/node12/1.0.11: + '@tsconfig/node12@1.0.11': resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - dev: true - /@tsconfig/node14/1.0.3: + '@tsconfig/node14@1.0.3': resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - dev: true - /@tsconfig/node16/1.0.3: - resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} - dev: true + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - /@tufjs/canonical-json/1.0.0: + '@tufjs/canonical-json@1.0.0': resolution: {integrity: sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: true - /@tufjs/models/1.0.3: - resolution: {integrity: sha512-mkFEqqRisi13DmR5pX4x+Zk97EiU8djTtpNW1GeuX410y/raAsq/T3ZCjwoRIZ8/cIBfW0olK/sywlAiWevDVw==} + '@tufjs/models@1.0.4': + resolution: {integrity: sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - '@tufjs/canonical-json': 1.0.0 - minimatch: 7.4.6 - dev: true - /@types/argparse/1.0.38: + '@types/argparse@1.0.38': resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} - dev: true - /@types/babel__core/7.20.0: - resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==} - dependencies: - '@babel/parser': 7.21.4 - '@babel/types': 7.21.4 - '@types/babel__generator': 7.6.4 - '@types/babel__template': 7.4.1 - '@types/babel__traverse': 7.18.3 - dev: true + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - /@types/babel__generator/7.6.4: - resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} - dependencies: - '@babel/types': 7.21.4 - dev: true + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} - /@types/babel__template/7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} - dependencies: - '@babel/parser': 7.21.4 - '@babel/types': 7.21.4 - dev: true + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - /@types/babel__traverse/7.18.3: - resolution: {integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==} - dependencies: - '@babel/types': 7.21.4 - dev: true + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} - /@types/estree/1.0.1: - resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} - dev: true + '@types/conventional-commits-parser@5.0.0': + resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} - /@types/fs-extra/11.0.1: - resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} - dependencies: - '@types/jsonfile': 6.1.1 - '@types/node': 18.15.11 - dev: true + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - /@types/graceful-fs/4.1.6: - resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} - dependencies: - '@types/node': 18.15.11 - dev: true + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} - /@types/http-cache-semantics/4.0.1: - resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} - dev: true + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - /@types/istanbul-lib-coverage/2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} - dev: true + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} - /@types/istanbul-lib-report/3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} - dependencies: - '@types/istanbul-lib-coverage': 2.0.4 - dev: true + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - /@types/istanbul-reports/3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} - dependencies: - '@types/istanbul-lib-report': 3.0.0 - dev: true + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - /@types/jest/29.5.1: - resolution: {integrity: sha512-tEuVcHrpaixS36w7hpsfLBLpjtMRJUE09/MHXn923LOVojDwyC14cWcfc0rDs0VEfUyYmt/+iX1kxxp+gZMcaQ==} - dependencies: - expect: 29.5.0 - pretty-format: 29.5.0 - dev: true + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - /@types/jsdom/20.0.1: - resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} - dependencies: - '@types/node': 18.15.11 - '@types/tough-cookie': 4.0.2 - parse5: 7.1.2 - dev: true + '@types/jest@29.5.12': + resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} - /@types/json-schema/7.0.11: - resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} - dev: true + '@types/jsdom@20.0.1': + resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} - /@types/jsonfile/6.1.1: - resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==} - dependencies: - '@types/node': 18.15.11 - dev: true + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - /@types/minimist/1.2.2: - resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} - dev: true + '@types/minimist@1.2.5': + resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} - /@types/node/18.15.11: - resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==} - dev: true + '@types/node@20.14.4': + resolution: {integrity: sha512-1ChboN+57suCT2t/f8lwtPY/k3qTpuD/qnqQuYoBg6OQOcPyaw7PiZVdGpaZYAvhDDtqrt0oAaM8+oSu1xsUGw==} - /@types/normalize-package-data/2.4.1: - resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} - dev: true + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} - /@types/prettier/2.7.2: - resolution: {integrity: sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==} - dev: true + '@types/semver-utils@1.1.3': + resolution: {integrity: sha512-T+YwkslhsM+CeuhYUxyAjWm7mJ5am/K10UX40RuA6k6Lc7eGtq8iY2xOzy7Vq0GOqhl/xZl5l2FwURZMTPTUww==} - /@types/semver/7.3.13: - resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} - dev: true + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - /@types/stack-utils/2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - dev: true + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - /@types/tough-cookie/4.0.2: - resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} - dev: true + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - /@types/yargs-parser/21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} - dev: true + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - /@types/yargs/17.0.24: - resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} - dependencies: - '@types/yargs-parser': 21.0.0 - dev: true + '@types/yargs@17.0.32': + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} - /@typescript-eslint/eslint-plugin/5.59.0_wsbkzerfphvgr4lle7vmeh64yi: - resolution: {integrity: sha512-p0QgrEyrxAWBecR56gyn3wkG15TJdI//eetInP3zYRewDh0XS+DhB3VUAd3QqvziFsfaQIoIuZMxZRB7vXYaYw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/eslint-plugin@7.13.1': + resolution: {integrity: sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - dependencies: - '@eslint-community/regexpp': 4.5.0 - '@typescript-eslint/parser': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy - '@typescript-eslint/scope-manager': 5.59.0 - '@typescript-eslint/type-utils': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy - '@typescript-eslint/utils': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy - debug: 4.3.4 - eslint: 8.38.0 - grapheme-splitter: 1.0.4 - ignore: 5.2.4 - natural-compare-lite: 1.4.0 - semver: 7.5.0 - tsutils: 3.21.0_typescript@5.0.4 - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/parser/5.59.0_voubu7prgxjfsfbgx5d4sqnwiy: - resolution: {integrity: sha512-qK9TZ70eJtjojSUMrrEwA9ZDQ4N0e/AuoOIgXuNBorXYcBDk397D2r5MIe1B3cok/oCtdNC5j+lUUpVB+Dpb+w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/parser@7.13.1': + resolution: {integrity: sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.59.0 - '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/typescript-estree': 5.59.0_typescript@5.0.4 - debug: 4.3.4 - eslint: 8.38.0 - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/scope-manager/5.59.0: - resolution: {integrity: sha512-tsoldKaMh7izN6BvkK6zRMINj4Z2d6gGhO2UsI8zGZY3XhLq1DndP3Ycjhi1JwdwPRwtLMW4EFPgpuKhbCGOvQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/visitor-keys': 5.59.0 - dev: true + '@typescript-eslint/scope-manager@7.13.1': + resolution: {integrity: sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==} + engines: {node: ^18.18.0 || >=20.0.0} - /@typescript-eslint/type-utils/5.59.0_voubu7prgxjfsfbgx5d4sqnwiy: - resolution: {integrity: sha512-d/B6VSWnZwu70kcKQSCqjcXpVH+7ABKH8P1KNn4K7j5PXXuycZTPXF44Nui0TEm6rbWGi8kc78xRgOC4n7xFgA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/type-utils@7.13.1': + resolution: {integrity: sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: - eslint: '*' + eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.59.0_typescript@5.0.4 - '@typescript-eslint/utils': 5.59.0_voubu7prgxjfsfbgx5d4sqnwiy - debug: 4.3.4 - eslint: 8.38.0 - tsutils: 3.21.0_typescript@5.0.4 - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/types/5.59.0: - resolution: {integrity: sha512-yR2h1NotF23xFFYKHZs17QJnB51J/s+ud4PYU4MqdZbzeNxpgUr05+dNeCN/bb6raslHvGdd6BFCkVhpPk/ZeA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + '@typescript-eslint/types@7.13.1': + resolution: {integrity: sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==} + engines: {node: ^18.18.0 || >=20.0.0} - /@typescript-eslint/typescript-estree/5.59.0_typescript@5.0.4: - resolution: {integrity: sha512-sUNnktjmI8DyGzPdZ8dRwW741zopGxltGs/SAPgGL/AAgDpiLsCFLcMNSpbfXfmnNeHmK9h3wGmCkGRGAoUZAg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/typescript-estree@7.13.1': + resolution: {integrity: sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - dependencies: - '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/visitor-keys': 5.59.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.0 - tsutils: 3.21.0_typescript@5.0.4 - typescript: 5.0.4 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/utils/5.59.0_voubu7prgxjfsfbgx5d4sqnwiy: - resolution: {integrity: sha512-GGLFd+86drlHSvPgN/el6dRQNYYGOvRSDVydsUaQluwIW3HvbXuxyuD5JETvBt/9qGYe+lOrDk6gRrWOHb/FvA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/utils@7.13.1': + resolution: {integrity: sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0_eslint@8.38.0 - '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.59.0 - '@typescript-eslint/types': 5.59.0 - '@typescript-eslint/typescript-estree': 5.59.0_typescript@5.0.4 - eslint: 8.38.0 - eslint-scope: 5.1.1 - semver: 7.5.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: true + eslint: ^8.56.0 - /@typescript-eslint/visitor-keys/5.59.0: - resolution: {integrity: sha512-qZ3iXxQhanchCeaExlKPV3gDQFxMUmU35xfd5eCXB6+kUw1TUAbIy2n7QIrwz9s98DQLzNWyHp61fY0da4ZcbA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.59.0 - eslint-visitor-keys: 3.4.0 - dev: true + '@typescript-eslint/visitor-keys@7.13.1': + resolution: {integrity: sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==} + engines: {node: ^18.18.0 || >=20.0.0} - /JSONStream/1.3.5: + JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - dev: true - /abab/2.0.6: + abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - dev: true + deprecated: Use your platform's native atob() and btoa() methods instead - /abbrev/1.1.1: + abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - dev: true - /acorn-globals/7.0.1: + acorn-globals@7.0.1: resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} - dependencies: - acorn: 8.8.2 - acorn-walk: 8.2.0 - dev: true - /acorn-jsx/5.3.2_acorn@8.8.2: + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.8.2 - dev: true - /acorn-walk/8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + acorn-walk@8.3.3: + resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} engines: {node: '>=0.4.0'} - dev: true - /acorn/8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} + acorn@8.12.0: + resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==} engines: {node: '>=0.4.0'} hasBin: true - dev: true - /add-stream/1.0.0: + add-stream@1.0.0: resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} - dev: true - /agent-base/6.0.2: + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - /agentkeepalive/4.3.0: - resolution: {integrity: sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==} + agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} engines: {node: '>= 8.0.0'} - dependencies: - debug: 4.3.4 - depd: 2.0.0 - humanize-ms: 1.2.1 - transitivePeerDependencies: - - supports-color - dev: true - /aggregate-error/3.1.0: + aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - dev: true - /ajv/6.12.6: + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - dev: true - /ajv/8.12.0: + ajv@8.12.0: resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - dev: true - /ansi-align/3.0.1: + ajv@8.13.0: + resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==} + + ajv@8.16.0: + resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==} + + ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} - dependencies: - string-width: 4.2.3 - dev: true - /ansi-colors/4.1.3: + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - dev: true - /ansi-escapes/4.3.2: + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - dev: true - /ansi-regex/5.0.1: + ansi-escapes@6.2.1: + resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} + engines: {node: '>=14.16'} + + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - dev: true - /ansi-regex/6.0.1: + ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} - dev: true - - /ansi-sequence-parser/1.1.0: - resolution: {integrity: sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==} - dev: true - /ansi-styles/3.2.1: + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - dev: true - /ansi-styles/4.3.0: + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - /ansi-styles/5.2.0: + ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - dev: true - /ansi-styles/6.2.1: + ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - dev: true - /anymatch/3.1.3: + anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - dev: true - /aproba/2.0.0: + aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - dev: true - /are-we-there-yet/3.0.1: + are-we-there-yet@3.0.1: resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - delegates: 1.0.0 - readable-stream: 3.6.2 - dev: true + deprecated: This package is no longer supported. - /arg/4.1.3: + arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true - /argparse/1.0.10: + argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - /argparse/2.0.1: + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true - /array-buffer-byte-length/1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} - dependencies: - call-bind: 1.0.2 - is-array-buffer: 3.0.2 - dev: true + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} - /array-ify/1.0.0: + array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - dev: true - /array-union/1.0.2: + array-union@1.0.2: resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} engines: {node: '>=0.10.0'} - dependencies: - array-uniq: 1.0.3 - dev: true - /array-union/2.1.0: + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - dev: true - /array-uniq/1.0.3: + array-uniq@1.0.3: resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} engines: {node: '>=0.10.0'} - dev: true - /arrify/1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} - dev: true - - /astral-regex/2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} - dev: true + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} - /async/3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} - dev: true + async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} - /asynckit/0.4.0: + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: true - /available-typed-arrays/1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - dev: true - /babel-jest/29.5.0_@babel+core@7.21.4: - resolution: {integrity: sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==} + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 - dependencies: - '@babel/core': 7.21.4 - '@jest/transform': 29.5.0 - '@types/babel__core': 7.20.0 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.5.0_@babel+core@7.21.4 - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: true - /babel-plugin-istanbul/6.1.1: + babel-plugin-istanbul@6.1.1: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} - dependencies: - '@babel/helper-plugin-utils': 7.20.2 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - dev: true - /babel-plugin-jest-hoist/29.5.0: - resolution: {integrity: sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==} + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/template': 7.20.7 - '@babel/types': 7.21.4 - '@types/babel__core': 7.20.0 - '@types/babel__traverse': 7.18.3 - dev: true - /babel-preset-current-node-syntax/1.0.1_@babel+core@7.21.4: + babel-preset-current-node-syntax@1.0.1: resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.21.4 - '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.21.4 - '@babel/plugin-syntax-bigint': 7.8.3_@babel+core@7.21.4 - '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.21.4 - '@babel/plugin-syntax-import-meta': 7.10.4_@babel+core@7.21.4 - '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.21.4 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.21.4 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.21.4 - '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.21.4 - '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.21.4 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.21.4 - '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.21.4 - '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.21.4 - dev: true - - /babel-preset-jest/29.5.0_@babel+core@7.21.4: - resolution: {integrity: sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==} + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.21.4 - babel-plugin-jest-hoist: 29.5.0 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.21.4 - dev: true - /balanced-match/1.0.2: + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - /boxen/7.0.2: - resolution: {integrity: sha512-1Z4UJabXUP1/R9rLpoU3O2lEMnG3pPLAs/ZD2lF3t2q7qD5lM8rqbtnvtvm4N0wEyNlE+9yZVTVAGmd1V5jabg==} + boxen@7.1.1: + resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} engines: {node: '>=14.16'} - dependencies: - ansi-align: 3.0.1 - camelcase: 7.0.1 - chalk: 5.2.0 - cli-boxes: 3.0.0 - string-width: 5.1.2 - type-fest: 2.19.0 - widest-line: 4.0.1 - wrap-ansi: 8.1.0 - dev: true - /brace-expansion/1.1.11: + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - /brace-expansion/2.0.1: + brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - /braces/3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - /browserslist/4.21.5: - resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} + browserslist@4.23.1: + resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - dependencies: - caniuse-lite: 1.0.30001480 - electron-to-chromium: 1.4.368 - node-releases: 2.0.10 - update-browserslist-db: 1.0.11_browserslist@4.21.5 - dev: true - /bs-logger/0.2.6: + bs-logger@0.2.6: resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} engines: {node: '>= 6'} - dependencies: - fast-json-stable-stringify: 2.1.0 - dev: true - /bser/2.1.1: + bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - dependencies: - node-int64: 0.4.0 - dev: true - /buffer-from/1.1.2: + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /builtins/5.0.1: - resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} - dependencies: - semver: 7.5.0 - dev: true - /cacache/16.1.3: + cacache@16.1.3: resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - '@npmcli/fs': 2.1.2 - '@npmcli/move-file': 2.0.1 - chownr: 2.0.0 - fs-minipass: 2.1.0 - glob: 8.1.0 - infer-owner: 1.0.4 - lru-cache: 7.18.3 - minipass: 3.3.6 - minipass-collect: 1.0.2 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - mkdirp: 1.0.4 - p-map: 4.0.0 - promise-inflight: 1.0.1 - rimraf: 3.0.2 - ssri: 9.0.1 - tar: 6.1.13 - unique-filename: 2.0.1 - transitivePeerDependencies: - - bluebird - dev: true - /cacache/17.0.5: - resolution: {integrity: sha512-Y/PRQevNSsjAPWykl9aeGz8Pr+OI6BYM9fYDNMvOkuUiG9IhG4LEmaYrZZZvioMUEQ+cBCxT0v8wrnCURccyKA==} + cacache@17.1.4: + resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - '@npmcli/fs': 3.1.0 - fs-minipass: 3.0.1 - glob: 9.3.5 - lru-cache: 7.18.3 - minipass: 4.2.8 - minipass-collect: 1.0.2 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - p-map: 4.0.0 - promise-inflight: 1.0.1 - ssri: 10.0.3 - tar: 6.1.13 - unique-filename: 3.0.0 - transitivePeerDependencies: - - bluebird - dev: true - /cacheable-lookup/7.0.0: + cacheable-lookup@7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} engines: {node: '>=14.16'} - dev: true - /cacheable-request/10.2.9: - resolution: {integrity: sha512-CaAMr53AS1Tb9evO1BIWFnZjSr8A4pbXofpsNVWPMDZZj3ZQKHwsQG9BrTqQ4x5ZYJXz1T2b8LLtTZODxSpzbg==} + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} engines: {node: '>=14.16'} - dependencies: - '@types/http-cache-semantics': 4.0.1 - get-stream: 6.0.1 - http-cache-semantics: 4.1.1 - keyv: 4.5.2 - mimic-response: 4.0.0 - normalize-url: 8.0.0 - responselike: 3.0.0 - dev: true - /call-bind/1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.0 - dev: true + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} - /callsites/3.1.0: + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - dev: true - /camelcase-keys/6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - map-obj: 4.3.0 - quick-lru: 4.0.1 - dev: true - - /camelcase/5.3.1: + camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} - dev: true - /camelcase/6.3.0: + camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - dev: true - /camelcase/7.0.1: + camelcase@7.0.1: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} - dev: true - /caniuse-lite/1.0.30001480: - resolution: {integrity: sha512-q7cpoPPvZYgtyC4VaBSN0Bt+PJ4c4EYRf0DrduInOz2SkFpHD5p3LnvEpqBp7UnJn+8x1Ogl1s38saUxe+ihQQ==} - dev: true + caniuse-lite@1.0.30001636: + resolution: {integrity: sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==} - /chalk/2.4.2: + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - dev: true - /chalk/4.1.2: + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - /chalk/5.2.0: - resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: true - /char-regex/1.0.2: + char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} - dev: true - /chownr/2.0.0: + chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} - dev: true - /ci-info/3.8.0: - resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - dev: true - /cjs-module-lexer/1.2.2: - resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} - dev: true + cjs-module-lexer@1.3.1: + resolution: {integrity: sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==} - /clean-stack/2.2.0: + clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} - dev: true - /cli-boxes/3.0.0: + cli-boxes@3.0.0: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} - dev: true - /cli-cursor/3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: true + cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - /cli-table3/0.6.3: - resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} engines: {node: 10.* || >= 12.*} - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - dev: true - - /cli-truncate/2.1.0: - resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} - engines: {node: '>=8'} - dependencies: - slice-ansi: 3.0.0 - string-width: 4.2.3 - dev: true - - /cli-truncate/3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - slice-ansi: 5.0.0 - string-width: 5.1.2 - dev: true - /cliui/7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} - /cliui/8.0.1: + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - /co/4.6.0: + co@4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: true - /collect-v8-coverage/1.0.1: - resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} - dev: true + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} - /color-convert/1.9.3: + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: true - /color-convert/2.0.1: + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - /color-name/1.1.3: + color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true - /color-name/1.1.4: + color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - /color-support/1.1.3: + color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true - dev: true - /colorette/2.0.20: + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - dev: true - - /colors/1.2.5: - resolution: {integrity: sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==} - engines: {node: '>=0.1.90'} - dev: true - /combined-stream/1.0.8: + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: true - /commander/10.0.1: + commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} - dev: true - /commander/2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} - /commander/9.5.0: - resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} - engines: {node: ^12.20.0 || >=14} - requiresBuild: true - dev: true - optional: true + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - /commondir/1.0.1: + commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - dev: true - /compare-func/2.0.0: + compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - dependencies: - array-ify: 1.0.0 - dot-prop: 5.3.0 - dev: true - /concat-map/0.0.1: + concat-map@0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} - dev: true - /config-chain/1.1.13: + config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} - dependencies: - ini: 1.3.8 - proto-list: 1.2.4 - dev: true - /configstore/6.0.0: + configstore@6.0.0: resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} engines: {node: '>=12'} - dependencies: - dot-prop: 6.0.1 - graceful-fs: 4.2.11 - unique-string: 3.0.0 - write-file-atomic: 3.0.3 - xdg-basedir: 5.1.0 - dev: true - /console-control-strings/1.1.0: + console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - dev: true - /conventional-changelog-angular/5.0.13: - resolution: {integrity: sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==} - engines: {node: '>=10'} - dependencies: - compare-func: 2.0.0 - q: 1.5.1 - dev: true + conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} - /conventional-changelog-atom/2.0.8: - resolution: {integrity: sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true + conventional-changelog-angular@8.0.0: + resolution: {integrity: sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==} + engines: {node: '>=18'} - /conventional-changelog-cli/2.2.2: - resolution: {integrity: sha512-8grMV5Jo8S0kP3yoMeJxV2P5R6VJOqK72IiSV9t/4H5r/HiRqEBQ83bYGuz4Yzfdj4bjaAEhZN/FFbsFXr5bOA==} - engines: {node: '>=10'} + conventional-changelog-atom@5.0.0: + resolution: {integrity: sha512-WfzCaAvSCFPkznnLgLnfacRAzjgqjLUjvf3MftfsJzQdDICqkOOpcMtdJF3wTerxSpv2IAAjX8doM3Vozqle3g==} + engines: {node: '>=18'} + + conventional-changelog-cli@5.0.0: + resolution: {integrity: sha512-9Y8fucJe18/6ef6ZlyIlT2YQUbczvoQZZuYmDLaGvcSBP+M6h+LAvf7ON7waRxKJemcCII8Yqu5/8HEfskTxJQ==} + engines: {node: '>=18'} hasBin: true - dependencies: - add-stream: 1.0.0 - conventional-changelog: 3.1.25 - lodash: 4.17.21 - meow: 8.1.2 - tempfile: 3.0.0 - dev: true - /conventional-changelog-codemirror/2.0.8: - resolution: {integrity: sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true + conventional-changelog-codemirror@5.0.0: + resolution: {integrity: sha512-8gsBDI5Y3vrKUCxN6Ue8xr6occZ5nsDEc4C7jO/EovFGozx8uttCAyfhRrvoUAWi2WMm3OmYs+0mPJU7kQdYWQ==} + engines: {node: '>=18'} - /conventional-changelog-conventionalcommits/4.6.3: - resolution: {integrity: sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==} - engines: {node: '>=10'} - dependencies: - compare-func: 2.0.0 - lodash: 4.17.21 - q: 1.5.1 - dev: true + conventional-changelog-conventionalcommits@7.0.2: + resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} + engines: {node: '>=16'} - /conventional-changelog-conventionalcommits/5.0.0: - resolution: {integrity: sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==} - engines: {node: '>=10'} - dependencies: - compare-func: 2.0.0 - lodash: 4.17.21 - q: 1.5.1 - dev: true + conventional-changelog-conventionalcommits@8.0.0: + resolution: {integrity: sha512-eOvlTO6OcySPyyyk8pKz2dP4jjElYunj9hn9/s0OB+gapTO8zwS9UQWrZ1pmF2hFs3vw1xhonOLGcGjy/zgsuA==} + engines: {node: '>=18'} - /conventional-changelog-core/4.2.4: - resolution: {integrity: sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==} - engines: {node: '>=10'} - dependencies: - add-stream: 1.0.0 - conventional-changelog-writer: 5.0.1 - conventional-commits-parser: 3.2.4 - dateformat: 3.0.3 - get-pkg-repo: 4.2.1 - git-raw-commits: 2.0.11 - git-remote-origin-url: 2.0.0 - git-semver-tags: 4.1.1 - lodash: 4.17.21 - normalize-package-data: 3.0.3 - q: 1.5.1 - read-pkg: 3.0.0 - read-pkg-up: 3.0.0 - through2: 4.0.2 - dev: true + conventional-changelog-core@8.0.0: + resolution: {integrity: sha512-EATUx5y9xewpEe10UEGNpbSHRC6cVZgO+hXQjofMqpy+gFIrcGvH3Fl6yk2VFKh7m+ffenup2N7SZJYpyD9evw==} + engines: {node: '>=18'} - /conventional-changelog-ember/2.0.9: - resolution: {integrity: sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true + conventional-changelog-ember@5.0.0: + resolution: {integrity: sha512-RPflVfm5s4cSO33GH/Ey26oxhiC67akcxSKL8CLRT3kQX2W3dbE19sSOM56iFqUJYEwv9mD9r6k79weWe1urfg==} + engines: {node: '>=18'} - /conventional-changelog-eslint/3.0.9: - resolution: {integrity: sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true + conventional-changelog-eslint@6.0.0: + resolution: {integrity: sha512-eiUyULWjzq+ybPjXwU6NNRflApDWlPEQEHvI8UAItYW/h22RKkMnOAtfCZxMmrcMO1OKUWtcf2MxKYMWe9zJuw==} + engines: {node: '>=18'} - /conventional-changelog-express/2.0.6: - resolution: {integrity: sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true + conventional-changelog-express@5.0.0: + resolution: {integrity: sha512-D8Q6WctPkQpvr2HNCCmwU5GkX22BVHM0r4EW8vN0230TSyS/d6VQJDAxGb84lbg0dFjpO22MwmsikKL++Oo/oQ==} + engines: {node: '>=18'} - /conventional-changelog-jquery/3.0.11: - resolution: {integrity: sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==} - engines: {node: '>=10'} - dependencies: - q: 1.5.1 - dev: true + conventional-changelog-jquery@6.0.0: + resolution: {integrity: sha512-2kxmVakyehgyrho2ZHBi90v4AHswkGzHuTaoH40bmeNqUt20yEkDOSpw8HlPBfvEQBwGtbE+5HpRwzj6ac2UfA==} + engines: {node: '>=18'} - /conventional-changelog-jshint/2.0.9: - resolution: {integrity: sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==} - engines: {node: '>=10'} - dependencies: - compare-func: 2.0.0 - q: 1.5.1 - dev: true + conventional-changelog-jshint@5.0.0: + resolution: {integrity: sha512-gGNphSb/opc76n2eWaO6ma4/Wqu3tpa2w7i9WYqI6Cs2fncDSI2/ihOfMvXveeTTeld0oFvwMVNV+IYQIk3F3g==} + engines: {node: '>=18'} - /conventional-changelog-preset-loader/2.3.4: - resolution: {integrity: sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==} - engines: {node: '>=10'} - dev: true + conventional-changelog-preset-loader@5.0.0: + resolution: {integrity: sha512-SetDSntXLk8Jh1NOAl1Gu5uLiCNSYenB5tm0YVeZKePRIgDW9lQImromTwLa3c/Gae298tsgOM+/CYT9XAl0NA==} + engines: {node: '>=18'} - /conventional-changelog-writer/5.0.1: - resolution: {integrity: sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==} - engines: {node: '>=10'} + conventional-changelog-writer@8.0.0: + resolution: {integrity: sha512-TQcoYGRatlAnT2qEWDON/XSfnVG38JzA7E0wcGScu7RElQBkg9WWgZd1peCWFcWDh1xfb2CfsrcvOn1bbSzztA==} + engines: {node: '>=18'} hasBin: true - dependencies: - conventional-commits-filter: 2.0.7 - dateformat: 3.0.3 - handlebars: 4.7.7 - json-stringify-safe: 5.0.1 - lodash: 4.17.21 - meow: 8.1.2 - semver: 6.3.0 - split: 1.0.1 - through2: 4.0.2 - dev: true - - /conventional-changelog/3.1.25: - resolution: {integrity: sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==} - engines: {node: '>=10'} - dependencies: - conventional-changelog-angular: 5.0.13 - conventional-changelog-atom: 2.0.8 - conventional-changelog-codemirror: 2.0.8 - conventional-changelog-conventionalcommits: 4.6.3 - conventional-changelog-core: 4.2.4 - conventional-changelog-ember: 2.0.9 - conventional-changelog-eslint: 3.0.9 - conventional-changelog-express: 2.0.6 - conventional-changelog-jquery: 3.0.11 - conventional-changelog-jshint: 2.0.9 - conventional-changelog-preset-loader: 2.3.4 - dev: true - - /conventional-commits-filter/2.0.7: - resolution: {integrity: sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==} - engines: {node: '>=10'} - dependencies: - lodash.ismatch: 4.4.0 - modify-values: 1.0.1 - dev: true - /conventional-commits-parser/3.2.4: - resolution: {integrity: sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==} - engines: {node: '>=10'} + conventional-changelog@6.0.0: + resolution: {integrity: sha512-tuUH8H/19VjtD9Ig7l6TQRh+Z0Yt0NZ6w/cCkkyzUbGQTnUEmKfGtkC9gGfVgCfOL1Rzno5NgNF4KY8vR+Jo3w==} + engines: {node: '>=18'} + + conventional-commits-filter@5.0.0: + resolution: {integrity: sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==} + engines: {node: '>=18'} + + conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} + engines: {node: '>=16'} hasBin: true - dependencies: - JSONStream: 1.3.5 - is-text-path: 1.0.1 - lodash: 4.17.21 - meow: 8.1.2 - split2: 3.2.2 - through2: 4.0.2 - dev: true - /convert-source-map/1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true + conventional-commits-parser@6.0.0: + resolution: {integrity: sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==} + engines: {node: '>=18'} + hasBin: true - /convert-source-map/2.0.0: + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true - /core-js/3.30.1: - resolution: {integrity: sha512-ZNS5nbiSwDTq4hFosEDqm65izl2CWmLz0hARJMyNQBgkUZMIF51cQiMvIQKA6hvuaeWxQDP3hEedM1JZIgTldQ==} - requiresBuild: true - dev: true + core-js@3.37.1: + resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==} - /core-util-is/1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: true - - /cosmiconfig-typescript-loader/4.3.0_zulaepqzabcjiyzbkdbfeduf6u: - resolution: {integrity: sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==} - engines: {node: '>=12', npm: '>=6'} + cosmiconfig-typescript-loader@5.0.0: + resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} + engines: {node: '>=v16'} peerDependencies: '@types/node': '*' - cosmiconfig: '>=7' - ts-node: '>=10' - typescript: '>=3' - dependencies: - '@types/node': 18.15.11 - cosmiconfig: 8.1.3 - ts-node: 10.9.1_bhanhq442dy43ncydsavgi4jfi - typescript: 5.0.4 - dev: true - - /cosmiconfig/8.1.3: - resolution: {integrity: sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==} + cosmiconfig: '>=8.2' + typescript: '>=4' + + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} - dependencies: - import-fresh: 3.3.0 - js-yaml: 4.1.0 - parse-json: 5.2.0 - path-type: 4.0.0 - dev: true + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true - /create-require/1.1.1: + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true - /cross-spawn/6.0.5: + cross-spawn@6.0.5: resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.1 - shebang-command: 1.2.0 - which: 1.3.1 - dev: true - /cross-spawn/7.0.3: + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - /crypto-random-string/4.0.0: + crypto-random-string@4.0.0: resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} engines: {node: '>=12'} - dependencies: - type-fest: 1.4.0 - dev: true - /cssom/0.3.8: + cssom@0.3.8: resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} - dev: true - /cssom/0.5.0: + cssom@0.5.0: resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} - dev: true - /cssstyle/2.3.0: + cssstyle@2.3.0: resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} engines: {node: '>=8'} - dependencies: - cssom: 0.3.8 - dev: true - /dargs/7.0.0: - resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} - engines: {node: '>=8'} - dev: true + dargs@8.1.0: + resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} + engines: {node: '>=12'} - /data-urls/3.0.2: + data-urls@3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} - dependencies: - abab: 2.0.6 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 - dev: true - /dateformat/3.0.3: - resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} - dev: true + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} - /debug/4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' peerDependenciesMeta: supports-color: optional: true - dependencies: - ms: 2.1.2 - dev: true - - /decamelize-keys/1.1.1: - resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} - engines: {node: '>=0.10.0'} - dependencies: - decamelize: 1.2.0 - map-obj: 1.0.1 - dev: true - - /decamelize/1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - dev: true - /decimal.js/10.4.3: + decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} - dev: true - /decompress-response/6.0.0: + decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} - dependencies: - mimic-response: 3.1.0 - dev: true - /dedent/0.7.0: - resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dev: true + dedent@1.5.3: + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true - /deep-extend/0.6.0: + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} - dev: true - /deep-is/0.1.4: + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true - /deepmerge/4.3.1: + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - dev: true - /defer-to-connect/2.0.1: + defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} - dev: true - /define-properties/1.2.0: - resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - dependencies: - has-property-descriptors: 1.0.0 - object-keys: 1.1.1 - dev: true - /delayed-stream/1.0.0: + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - dev: true - /delegates/1.0.0: + delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} - dev: true - /depd/2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - dev: true - - /detect-newline/3.1.0: + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} - dev: true - /diff-sequences/29.4.3: - resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - /diff/4.0.2: + diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} - dev: true - /dir-glob/3.0.1: + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - /doctrine/3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - dev: true - - /domexception/4.0.0: + domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} engines: {node: '>=12'} - dependencies: - webidl-conversions: 7.0.0 - dev: true + deprecated: Use your platform's native DOMException instead - /dot-prop/5.3.0: + dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} - dependencies: - is-obj: 2.0.0 - dev: true - /dot-prop/6.0.1: + dot-prop@6.0.1: resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} engines: {node: '>=10'} - dependencies: - is-obj: 2.0.0 - dev: true - /eastasianwidth/0.2.0: + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - dev: true - /electron-to-chromium/1.4.368: - resolution: {integrity: sha512-e2aeCAixCj9M7nJxdB/wDjO6mbYX+lJJxSJCXDzlr5YPGYVofuJwGN9nKg2o6wWInjX6XmxRinn3AeJMK81ltw==} - dev: true + electron-to-chromium@1.4.803: + resolution: {integrity: sha512-61H9mLzGOCLLVsnLiRzCbc63uldP0AniRYPV3hbGVtONA1pI7qSGILdbofR7A8TMbOypDocEAjH/e+9k1QIe3g==} - /email-addresses/5.0.0: + email-addresses@5.0.0: resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==} - dev: true - /emittery/0.13.1: + emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} - dev: true - /emoji-regex/8.0.0: + emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true - /emoji-regex/9.2.2: + emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true - /encoding/0.1.13: + encoding@0.1.13: resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} - requiresBuild: true - dependencies: - iconv-lite: 0.6.3 - dev: true - optional: true - /enquirer/2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} - dependencies: - ansi-colors: 4.1.3 - dev: true - /entities/4.5.0: + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - dev: true - /env-paths/2.2.1: + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - dev: true - /err-code/2.0.3: + err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - dev: true - /error-ex/1.3.2: + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - /es-abstract/1.21.2: - resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==} + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} engines: {node: '>= 0.4'} - dependencies: - array-buffer-byte-length: 1.0.0 - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - es-set-tostringtag: 2.0.1 - es-to-primitive: 1.2.1 - function.prototype.name: 1.1.5 - get-intrinsic: 1.2.0 - get-symbol-description: 1.0.0 - globalthis: 1.0.3 - gopd: 1.0.1 - has: 1.0.3 - has-property-descriptors: 1.0.0 - has-proto: 1.0.1 - has-symbols: 1.0.3 - internal-slot: 1.0.5 - is-array-buffer: 3.0.2 - is-callable: 1.2.7 - is-negative-zero: 2.0.2 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-perfectionist@2.11.0: + resolution: {integrity: sha512-XrtBtiu5rbQv88gl+1e2RQud9te9luYNvKIgM9emttQ2zutHPzY/AQUucwxscDKV4qlTkvLTxjOFvxqeDpPorw==} + peerDependencies: + astro-eslint-parser: ^1.0.2 + eslint: '>=8.0.0' + svelte: '>=3.0.0' + svelte-eslint-parser: ^0.37.0 + vue-eslint-parser: '>=9.0.0' + peerDependenciesMeta: + astro-eslint-parser: + optional: true + svelte: + optional: true + svelte-eslint-parser: + optional: true + vue-eslint-parser: + optional: true + + eslint-plugin-prettier@5.1.3: + resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-scope@8.0.1: + resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.5.0: + resolution: {integrity: sha512-+NAOZFrW/jFTS3dASCGBxX1pkFD0/fsO+hfAkJ4TyYKwgsXZbqzrw+seCYFCcPCYXvnD67tAnglU7GQTz6kcVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + + esno@4.7.0: + resolution: {integrity: sha512-81owrjxIxOwqcABt20U09Wn8lpBo9K6ttqbGvQcB3VYNLJyaV1fvKkDtpZd3Rj5BX3WXiGiJCjUevKQGNICzJg==} + hasBin: true + + espree@10.1.0: + resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + execa@9.2.0: + resolution: {integrity: sha512-vpOyYg7UAVKLAWWtRS2gAdgkT7oJbCn0me3gmUmxZih4kd3MF/oo8kNTBTIbkO3yuuF5uB4ZCZfn8BOolITYhg==} + engines: {node: ^18.19.0 || >=20.5.0} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + exponential-backoff@3.1.1: + resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-memoize@2.5.2: + resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + filename-reserved-regex@2.0.0: + resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} + engines: {node: '>=4'} + + filenamify@4.3.0: + resolution: {integrity: sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==} + engines: {node: '>=8'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + + find-up-simple@1.0.0: + resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} + engines: {node: '>=18'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} + engines: {node: '>=18'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@3.2.1: + resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + engines: {node: '>=14'} + + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + fp-and-or@0.1.4: + resolution: {integrity: sha512-+yRYRhpnFPWXSly/6V4Lw9IfOV26uu30kynGJ03PW+MnjOEQe45RZ141QcS0aJehYBYA50GfCDnsRbFJdhssRw==} + engines: {node: '>=10'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gauge@4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-stdin@8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + + gh-pages@6.1.1: + resolution: {integrity: sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw==} + engines: {node: '>=10'} + hasBin: true + + git-raw-commits@4.0.0: + resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} + engines: {node: '>=16'} + hasBin: true + + git-raw-commits@5.0.0: + resolution: {integrity: sha512-I2ZXrXeOc0KrCvC7swqtIFXFN+rbjnC7b2T943tvemIOVNl+XP8YnA9UVwqFhzzLClnSA60KR/qEjLpXzs73Qg==} + engines: {node: '>=18'} + hasBin: true + + git-semver-tags@8.0.0: + resolution: {integrity: sha512-N7YRIklvPH3wYWAR2vysaqGLPRcpwQ0GKdlqTiVN5w1UmCdaeY3K8s6DMKRCh54DDdzyt/OAB6C8jgVtb7Y2Fg==} + engines: {node: '>=18'} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.1: + resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + + global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} + engines: {node: '>=10'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@6.1.0: + resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} + engines: {node: '>=0.10.0'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + + has-yarn@3.0.0: + resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hosted-git-info@5.2.1: + resolution: {integrity: sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + hosted-git-info@6.1.1: + resolution: {integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + html-encoding-sniffer@3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + human-signals@7.0.0: + resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==} + engines: {node: '>=18.18.0'} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + husky@9.0.11: + resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} + engines: {node: '>=18'} + hasBin: true + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ignore-walk@6.0.5: + resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + index-to-position@0.1.2: + resolution: {integrity: sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==} + engines: {node: '>=18'} + + infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + + ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-npm@6.0.0: + resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-text-path@2.0.0: + resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} + engines: {node: '>=8'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-yarn-global@0.4.1: + resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} + engines: {node: '>=12'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.2: + resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} + engines: {node: '>=14'} + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-jsdom@29.7.0: + resolution: {integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + + jsdom@20.0.3: + resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} + engines: {node: '>=14'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + json-parse-helpfulerror@1.0.3: + resolution: {integrity: sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonlines@0.1.1: + resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==} + + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + latest-version@7.0.0: + resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} + engines: {node: '>=14.16'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + lint-staged@15.2.7: + resolution: {integrity: sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==} + engines: {node: '>=18.12.0'} + hasBin: true + + listr2@8.2.1: + resolution: {integrity: sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==} + engines: {node: '>=18.0.0'} + + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash.upperfirst@4.3.1: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-update@6.0.0: + resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} + engines: {node: '>=18'} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + make-fetch-happen@10.2.1: + resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + make-fetch-happen@11.1.1: + resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + meow@12.1.1: + resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} + engines: {node: '>=16.10'} + + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + minimatch@3.0.8: + resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + + minipass-fetch@2.1.2: + resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + minipass-fetch@3.0.5: + resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-json-stream@1.0.1: + resolution: {integrity: sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + + node-gyp@9.4.1: + resolution: {integrity: sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==} + engines: {node: ^12.13 || ^14.13 || >=16} + hasBin: true + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + nopt@6.0.0: + resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-package-data@5.0.0: + resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + normalize-package-data@6.0.1: + resolution: {integrity: sha512-6rvCfeRW+OEZagAB4lMLSNuTNYZWLVtKccK79VSTf//yTY5VOCgcpH80O+bZK8Neps7pUnd5G+QlMg1yV/2iZQ==} + engines: {node: ^16.14.0 || >=18.0.0} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@8.0.1: + resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} + engines: {node: '>=14.16'} + + npm-bundled@3.0.1: + resolution: {integrity: sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-check-updates@16.14.20: + resolution: {integrity: sha512-sYbIhun4DrjO7NFOTdvs11nCar0etEhZTsEjL47eM0TuiGMhmYughRCxG2SpGRmGAQ7AkwN7bw2lWzoE7q6yOQ==} + engines: {node: '>=14.14'} + hasBin: true + + npm-install-checks@6.3.0: + resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-normalize-package-bin@3.0.1: + resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-package-arg@10.1.0: + resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-packlist@7.0.4: + resolution: {integrity: sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-pick-manifest@8.0.2: + resolution: {integrity: sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-registry-fetch@14.0.5: + resolution: {integrity: sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-run-all@4.1.5: + resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} + engines: {node: '>= 4'} + hasBin: true + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npmlog@6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + nwsapi@2.2.10: + resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json@8.1.1: + resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} + engines: {node: '>=14.16'} + + pacote@15.2.0: + resolution: {integrity: sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-github-url@1.0.2: + resolution: {integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==} + engines: {node: '>=0.10.0'} + hasBin: true + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-json@8.1.0: + resolution: {integrity: sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==} + engines: {node: '>=18'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pidtree@0.3.1: + resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} + engines: {node: '>=0.10'} + hasBin: true + + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + + pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.3.2: + resolution: {integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + pretty-ms@9.0.0: + resolution: {integrity: sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==} + engines: {node: '>=18'} + + proc-log@3.0.0: + resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + prompts-ncu@3.0.0: + resolution: {integrity: sha512-qyz9UxZ5MlPKWVhWrCmSZ1ahm2GVYdjLb8og2sg0IPth1KRuhcggHGuijz0e41dkx35p1t1q3GRISGH7QGALFA==} + engines: {node: '>= 14'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pupa@3.1.0: + resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==} + engines: {node: '>=12.20'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + rc-config-loader@4.1.3: + resolution: {integrity: sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + read-package-json-fast@3.0.2: + resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + read-package-json@6.0.4: + resolution: {integrity: sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + deprecated: This package is no longer supported. Please use @npmcli/package-json instead. + + read-package-up@11.0.0: + resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} + engines: {node: '>=18'} + + read-pkg@3.0.0: + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} + engines: {node: '>=4'} + + read-pkg@9.0.1: + resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} + engines: {node: '>=18'} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + + registry-auth-token@5.0.2: + resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + + remote-git-tags@3.0.0: + resolution: {integrity: sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==} + engines: {node: '>=8'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@5.0.7: + resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==} + engines: {node: '>=14.18'} + hasBin: true + + rollup-plugin-terser@7.0.2: + resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser + peerDependencies: + rollup: ^2.0.0 + + rollup-plugin-typescript2@0.36.0: + resolution: {integrity: sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==} + peerDependencies: + rollup: '>=1.26.3' + typescript: '>=2.4.0' + + rollup@4.18.0: + resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + semver-diff@4.0.0: + resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} + engines: {node: '>=12'} + + semver-utils@1.1.4: + resolution: {integrity: sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + serialize-javascript@4.0.0: + resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + + shiki@1.9.1: + resolution: {integrity: sha512-8PDkgb5ja3nfujTjvC4VytL6wGOGCtFAClUb2r3QROevYXxcq+/shVJK5s6gy0HZnjaJgFxd6BpPqpRfqne5rA==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sigstore@1.9.0: + resolution: {integrity: sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@7.0.0: + resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} + engines: {node: '>= 10'} + + socks@2.8.3: + resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spawn-please@2.0.2: + resolution: {integrity: sha512-KM8coezO6ISQ89c1BzyWNtcn2V2kAVtwIXd3cN/V5a0xPYc1F/vydrRc01wsKFEQ/p+V1a4sw4z2yMITIXrgGw==} + engines: {node: '>=14'} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.18: + resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + ssri@10.0.6: + resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ssri@9.0.1: + resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string-width@7.1.0: + resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} + engines: {node: '>=18'} + + string.prototype.padend@3.1.6: + resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} + engines: {node: '>= 0.4'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-json-comments@5.0.1: + resolution: {integrity: sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==} + engines: {node: '>=14.16'} + + strip-outer@1.0.1: + resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} + engines: {node: '>=0.10.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + synckit@0.8.8: + resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + engines: {node: ^14.18.0 || >=16.0.0} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + temp-dir@3.0.0: + resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} + engines: {node: '>=14.16'} + + tempfile@5.0.0: + resolution: {integrity: sha512-bX655WZI/F7EoTDw9JvQURqAXiPHi8o8+yFxPF2lWYyz1aHnmMRuXWqL6YB6GmeO0o4DIYWHLgGNi/X64T+X4Q==} + engines: {node: '>=14.18'} + + terser@5.31.1: + resolution: {integrity: sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-extensions@2.4.0: + resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} + engines: {node: '>=8'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + + trim-repeated@1.0.0: + resolution: {integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==} + engines: {node: '>=0.10.0'} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-jest@29.1.5: + resolution: {integrity: sha512-UuClSYxM7byvvYfyWdFI+/2UxMmwNyJb0NPkZPQE2hew3RurV7l7zURgOHAd/1I1ZdPpe3GUsXNXAcN8TFKSIg==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + 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 + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + tsx@4.15.6: + resolution: {integrity: sha512-is0VQQlfNZRHEuSSTKA6m4xw74IU4AizmuB6lAYLRt9XtuyeQnyJYexhNZOPCB59SqC4JzmSzPnHGBXxf3k0hA==} + engines: {node: '>=18.0.0'} + hasBin: true + + tuf-js@1.1.7: + resolution: {integrity: sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-fest@4.20.1: + resolution: {integrity: sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==} + engines: {node: '>=16'} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typedoc@0.26.2: + resolution: {integrity: sha512-q/t+M+PZqhN9gPWLBZ3CCvP+KT8O1tyYkSzEYbcQ6mo89avdIrMlBEl3vfo5BgSzwC6Lbmq0W64E8RkY+eVsLA==} + engines: {node: '>= 18'} + hasBin: true + peerDependencies: + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x + + typescript-eslint@7.13.1: + resolution: {integrity: sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + typescript@5.4.2: + resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + uglify-js@3.18.0: + resolution: {integrity: sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==} + engines: {node: '>=0.8.0'} + hasBin: true + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unique-filename@2.0.1: + resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-slug@3.0.0: + resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + + update-browserslist-db@1.0.16: + resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-notifier@6.0.2: + resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} + engines: {node: '>=14.16'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + engines: {node: '>=10.12.0'} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + w3c-xmlserializer@4.0.0: + resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} + engines: {node: '>=14'} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@3.0.1: + resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + widest-line@4.0.1: + resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} + engines: {node: '>=12'} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@2.4.5: + resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + + yoctocolors@2.0.2: + resolution: {integrity: sha512-Ct97huExsu7cWeEjmrXlofevF8CvzUglJ4iGUet5B8xn1oumtAZBpHU4GzYuoE6PVqcZ5hghtBrSlhwHuR1Jmw==} + engines: {node: '>=18'} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + + '@babel/compat-data@7.24.7': {} + + '@babel/core@7.24.7': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helpers': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + convert-source-map: 2.0.0 + debug: 4.3.5 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.24.7': + dependencies: + '@babel/types': 7.24.7 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/helper-annotate-as-pure@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-compilation-targets@7.24.7': + dependencies: + '@babel/compat-data': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + browserslist: 4.23.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-environment-visitor@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-function-name@7.24.7': + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/helper-hoist-variables@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-member-expression-to-functions@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-plugin-utils@7.24.7': {} + + '@babel/helper-replace-supers@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-optimise-call-expression': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-split-export-declaration@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-string-parser@7.24.7': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/helper-validator-option@7.24.7': {} + + '@babel/helpers@7.24.7': + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + + '@babel/parser@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-transform-modules-commonjs@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-transform-typescript': 7.24.7(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.24.7': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/traverse@7.24.7': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + debug: 4.3.5 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.24.7': + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@bcoe/v8-coverage@0.2.3': {} + + '@colors/colors@1.5.0': + optional: true + + '@commitlint/cli@19.3.0(@types/node@20.14.4)(typescript@5.4.5)': + dependencies: + '@commitlint/format': 19.3.0 + '@commitlint/lint': 19.2.2 + '@commitlint/load': 19.2.0(@types/node@20.14.4)(typescript@5.4.5) + '@commitlint/read': 19.2.1 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - typescript + + '@commitlint/config-conventional@19.2.2': + dependencies: + '@commitlint/types': 19.0.3 + conventional-changelog-conventionalcommits: 7.0.2 + + '@commitlint/config-validator@19.0.3': + dependencies: + '@commitlint/types': 19.0.3 + ajv: 8.16.0 + + '@commitlint/ensure@19.0.3': + dependencies: + '@commitlint/types': 19.0.3 + lodash.camelcase: 4.3.0 + lodash.kebabcase: 4.1.1 + lodash.snakecase: 4.1.1 + lodash.startcase: 4.4.0 + lodash.upperfirst: 4.3.1 + + '@commitlint/execute-rule@19.0.0': {} + + '@commitlint/format@19.3.0': + dependencies: + '@commitlint/types': 19.0.3 + chalk: 5.3.0 + + '@commitlint/is-ignored@19.2.2': + dependencies: + '@commitlint/types': 19.0.3 + semver: 7.6.2 + + '@commitlint/lint@19.2.2': + dependencies: + '@commitlint/is-ignored': 19.2.2 + '@commitlint/parse': 19.0.3 + '@commitlint/rules': 19.0.3 + '@commitlint/types': 19.0.3 + + '@commitlint/load@19.2.0(@types/node@20.14.4)(typescript@5.4.5)': + dependencies: + '@commitlint/config-validator': 19.0.3 + '@commitlint/execute-rule': 19.0.0 + '@commitlint/resolve-extends': 19.1.0 + '@commitlint/types': 19.0.3 + chalk: 5.3.0 + cosmiconfig: 9.0.0(typescript@5.4.5) + cosmiconfig-typescript-loader: 5.0.0(@types/node@20.14.4)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5) + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + lodash.uniq: 4.5.0 + transitivePeerDependencies: + - '@types/node' + - typescript + + '@commitlint/message@19.0.0': {} + + '@commitlint/parse@19.0.3': + dependencies: + '@commitlint/types': 19.0.3 + conventional-changelog-angular: 7.0.0 + conventional-commits-parser: 5.0.0 + + '@commitlint/read@19.2.1': + dependencies: + '@commitlint/top-level': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + git-raw-commits: 4.0.0 + minimist: 1.2.8 + + '@commitlint/resolve-extends@19.1.0': + dependencies: + '@commitlint/config-validator': 19.0.3 + '@commitlint/types': 19.0.3 + global-directory: 4.0.1 + import-meta-resolve: 4.1.0 + lodash.mergewith: 4.6.2 + resolve-from: 5.0.0 + + '@commitlint/rules@19.0.3': + dependencies: + '@commitlint/ensure': 19.0.3 + '@commitlint/message': 19.0.0 + '@commitlint/to-lines': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + + '@commitlint/to-lines@19.0.0': {} + + '@commitlint/top-level@19.0.0': + dependencies: + find-up: 7.0.0 + + '@commitlint/types@19.0.3': + dependencies: + '@types/conventional-commits-parser': 5.0.0 + chalk: 5.3.0 + + '@conventional-changelog/git-client@1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0)': + dependencies: + '@types/semver': 7.5.8 + semver: 7.6.2 + optionalDependencies: + conventional-commits-filter: 5.0.0 + conventional-commits-parser: 6.0.0 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + optional: true + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@9.5.0)': + dependencies: + eslint: 9.5.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.10.1': {} + + '@eslint/config-array@0.16.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.5 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/eslintrc@3.1.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.5 + espree: 10.1.0 + globals: 14.0.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.5.0': {} + + '@eslint/object-schema@2.1.4': {} + + '@gar/promisify@1.1.3': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.0': {} + + '@hutson/parse-repository-url@5.0.0': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.14.4 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.4 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.7 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.4 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.14.4 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 20.14.4 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.2.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.24.7 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.7 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.14.4 + '@types/yargs': 17.0.32 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + optional: true + + '@microsoft/api-extractor-model@7.29.2(@types/node@20.14.4)': + dependencies: + '@microsoft/tsdoc': 0.15.0 + '@microsoft/tsdoc-config': 0.17.0 + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.4) + transitivePeerDependencies: + - '@types/node' + + '@microsoft/api-extractor@7.47.0(@types/node@20.14.4)': + dependencies: + '@microsoft/api-extractor-model': 7.29.2(@types/node@20.14.4) + '@microsoft/tsdoc': 0.15.0 + '@microsoft/tsdoc-config': 0.17.0 + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.4) + '@rushstack/rig-package': 0.5.2 + '@rushstack/terminal': 0.13.0(@types/node@20.14.4) + '@rushstack/ts-command-line': 4.22.0(@types/node@20.14.4) + lodash: 4.17.21 + minimatch: 3.0.8 + resolve: 1.22.8 + semver: 7.5.4 + source-map: 0.6.1 + typescript: 5.4.2 + transitivePeerDependencies: + - '@types/node' + + '@microsoft/tsdoc-config@0.17.0': + dependencies: + '@microsoft/tsdoc': 0.15.0 + ajv: 8.12.0 + jju: 1.4.0 + resolve: 1.22.8 + + '@microsoft/tsdoc@0.15.0': {} + + '@mxssfd/core@5.0.1-beta.1': + dependencies: + '@mxssfd/types': 5.0.1-beta.1 + + '@mxssfd/typedoc-theme@1.1.5(typedoc@0.26.2(typescript@5.4.5))': + dependencies: + typedoc: 0.26.2(typescript@5.4.5) + + '@mxssfd/types@5.0.1-beta.1': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@npmcli/fs@2.1.2': + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.6.2 + + '@npmcli/fs@3.1.1': + dependencies: + semver: 7.6.2 + + '@npmcli/git@4.1.0': + dependencies: + '@npmcli/promise-spawn': 6.0.2 + lru-cache: 7.18.3 + npm-pick-manifest: 8.0.2 + proc-log: 3.0.0 + promise-inflight: 1.0.1 + promise-retry: 2.0.1 + semver: 7.6.2 + which: 3.0.1 + transitivePeerDependencies: + - bluebird + + '@npmcli/installed-package-contents@2.1.0': + dependencies: + npm-bundled: 3.0.1 + npm-normalize-package-bin: 3.0.1 + + '@npmcli/move-file@2.0.1': + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + + '@npmcli/node-gyp@3.0.0': {} + + '@npmcli/promise-spawn@6.0.2': + dependencies: + which: 3.0.1 + + '@npmcli/run-script@6.0.2': + dependencies: + '@npmcli/node-gyp': 3.0.0 + '@npmcli/promise-spawn': 6.0.2 + node-gyp: 9.4.1 + read-package-json-fast: 3.0.2 + which: 3.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.1.1': {} + + '@pnpm/config.env-replace@1.1.0': {} + + '@pnpm/network.ca-file@1.0.2': + dependencies: + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@2.2.2': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@rollup/plugin-json@6.1.0(rollup@4.18.0)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + optionalDependencies: + rollup: 4.18.0 + + '@rollup/pluginutils@4.2.1': + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + + '@rollup/pluginutils@5.1.0(rollup@4.18.0)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 4.18.0 + + '@rollup/rollup-android-arm-eabi@4.18.0': + optional: true + + '@rollup/rollup-android-arm64@4.18.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.18.0': + optional: true + + '@rollup/rollup-darwin-x64@4.18.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.18.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.18.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.18.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.18.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.18.0': + optional: true + + '@rushstack/node-core-library@5.4.1(@types/node@20.14.4)': + dependencies: + ajv: 8.13.0 + ajv-draft-04: 1.0.0(ajv@8.13.0) + ajv-formats: 3.0.1(ajv@8.13.0) + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.8 + semver: 7.5.4 + optionalDependencies: + '@types/node': 20.14.4 + + '@rushstack/rig-package@0.5.2': + dependencies: + resolve: 1.22.8 + strip-json-comments: 3.1.1 + + '@rushstack/terminal@0.13.0(@types/node@20.14.4)': + dependencies: + '@rushstack/node-core-library': 5.4.1(@types/node@20.14.4) + supports-color: 8.1.1 + optionalDependencies: + '@types/node': 20.14.4 + + '@rushstack/ts-command-line@4.22.0(@types/node@20.14.4)': + dependencies: + '@rushstack/terminal': 0.13.0(@types/node@20.14.4) + '@types/argparse': 1.0.38 + argparse: 1.0.10 + string-argv: 0.3.2 + transitivePeerDependencies: + - '@types/node' + + '@sec-ant/readable-stream@0.4.1': {} + + '@shikijs/core@1.9.1': {} + + '@sigstore/bundle@1.1.0': + dependencies: + '@sigstore/protobuf-specs': 0.2.1 + + '@sigstore/protobuf-specs@0.2.1': {} + + '@sigstore/sign@1.0.0': + dependencies: + '@sigstore/bundle': 1.1.0 + '@sigstore/protobuf-specs': 0.2.1 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/tuf@1.0.3': + dependencies: + '@sigstore/protobuf-specs': 0.2.1 + tuf-js: 1.1.7 + transitivePeerDependencies: + - supports-color + + '@sinclair/typebox@0.27.8': {} + + '@sindresorhus/is@5.6.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + + '@tool-pack/types@0.3.0': {} + + '@tootallnate/once@2.0.0': {} + + '@tsconfig/node10@1.0.11': + optional: true + + '@tsconfig/node12@1.0.11': + optional: true + + '@tsconfig/node14@1.0.3': + optional: true + + '@tsconfig/node16@1.0.4': + optional: true + + '@tufjs/canonical-json@1.0.0': {} + + '@tufjs/models@1.0.4': + dependencies: + '@tufjs/canonical-json': 1.0.0 + minimatch: 9.0.4 + + '@types/argparse@1.0.38': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.24.7 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.24.7 + + '@types/conventional-commits-parser@5.0.0': + dependencies: + '@types/node': 20.14.4 + + '@types/estree@1.0.5': {} + + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 20.14.4 + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 20.14.4 + + '@types/http-cache-semantics@4.0.4': {} + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@29.5.12': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + '@types/jsdom@20.0.1': + dependencies: + '@types/node': 20.14.4 + '@types/tough-cookie': 4.0.5 + parse5: 7.1.2 + + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 20.14.4 + + '@types/minimist@1.2.5': {} + + '@types/node@20.14.4': + dependencies: + undici-types: 5.26.5 + + '@types/normalize-package-data@2.4.4': {} + + '@types/semver-utils@1.1.3': {} + + '@types/semver@7.5.8': {} + + '@types/stack-utils@2.0.3': {} + + '@types/tough-cookie@4.0.5': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.32': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@typescript-eslint/eslint-plugin@7.13.1(@typescript-eslint/parser@7.13.1(eslint@9.5.0)(typescript@5.4.5))(eslint@9.5.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/regexpp': 4.10.1 + '@typescript-eslint/parser': 7.13.1(eslint@9.5.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.13.1 + '@typescript-eslint/type-utils': 7.13.1(eslint@9.5.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.13.1(eslint@9.5.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.13.1 + eslint: 9.5.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.13.1(eslint@9.5.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/scope-manager': 7.13.1 + '@typescript-eslint/types': 7.13.1 + '@typescript-eslint/typescript-estree': 7.13.1(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.13.1 + debug: 4.3.5 + eslint: 9.5.0 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.13.1': + dependencies: + '@typescript-eslint/types': 7.13.1 + '@typescript-eslint/visitor-keys': 7.13.1 + + '@typescript-eslint/type-utils@7.13.1(eslint@9.5.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/typescript-estree': 7.13.1(typescript@5.4.5) + '@typescript-eslint/utils': 7.13.1(eslint@9.5.0)(typescript@5.4.5) + debug: 4.3.5 + eslint: 9.5.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.13.1': {} + + '@typescript-eslint/typescript-estree@7.13.1(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 7.13.1 + '@typescript-eslint/visitor-keys': 7.13.1 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.4 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.13.1(eslint@9.5.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.5.0) + '@typescript-eslint/scope-manager': 7.13.1 + '@typescript-eslint/types': 7.13.1 + '@typescript-eslint/typescript-estree': 7.13.1(typescript@5.4.5) + eslint: 9.5.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.13.1': + dependencies: + '@typescript-eslint/types': 7.13.1 + eslint-visitor-keys: 3.4.3 + + JSONStream@1.3.5: + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + + abab@2.0.6: {} + + abbrev@1.1.1: {} + + acorn-globals@7.0.1: + dependencies: + acorn: 8.12.0 + acorn-walk: 8.3.3 + + acorn-jsx@5.3.2(acorn@8.12.0): + dependencies: + acorn: 8.12.0 + + acorn-walk@8.3.3: + dependencies: + acorn: 8.12.0 + + acorn@8.12.0: {} + + add-stream@1.0.0: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + agentkeepalive@4.5.0: + dependencies: + humanize-ms: 1.2.1 + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv-draft-04@1.0.0(ajv@8.13.0): + optionalDependencies: + ajv: 8.13.0 + + ajv-formats@3.0.1(ajv@8.13.0): + optionalDependencies: + ajv: 8.13.0 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.12.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + ajv@8.13.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + ajv@8.16.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-escapes@6.2.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + aproba@2.0.0: {} + + are-we-there-yet@3.0.1: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + arg@4.1.3: + optional: true + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-ify@1.0.0: {} + + array-union@1.0.2: + dependencies: + array-uniq: 1.0.3 + + array-union@2.1.0: {} + + array-uniq@1.0.3: {} + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + async@3.2.5: {} + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + babel-jest@29.7.0(@babel/core@7.24.7): + dependencies: + '@babel/core': 7.24.7 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.24.7) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.24.7 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 + + babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.7): + dependencies: + '@babel/core': 7.24.7 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.7) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.7) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.7) + + babel-preset-jest@29.6.3(@babel/core@7.24.7): + dependencies: + '@babel/core': 7.24.7 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.7) + + balanced-match@1.0.2: {} + + boxen@7.1.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 7.0.1 + chalk: 5.3.0 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.23.1: + dependencies: + caniuse-lite: 1.0.30001636 + electron-to-chromium: 1.4.803 + node-releases: 2.0.14 + update-browserslist-db: 1.0.16(browserslist@4.23.1) + + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + cacache@16.1.3: + dependencies: + '@npmcli/fs': 2.1.2 + '@npmcli/move-file': 2.0.1 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 8.1.0 + infer-owner: 1.0.4 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 9.0.1 + tar: 6.2.1 + unique-filename: 2.0.1 + transitivePeerDependencies: + - bluebird + + cacache@17.1.4: + dependencies: + '@npmcli/fs': 3.1.1 + fs-minipass: 3.0.3 + glob: 10.4.1 + lru-cache: 7.18.3 + minipass: 7.1.2 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.6 + tar: 6.2.1 + unique-filename: 3.0.0 + + cacheable-lookup@7.0.0: {} + + cacheable-request@10.2.14: + dependencies: + '@types/http-cache-semantics': 4.0.4 + get-stream: 6.0.1 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.0.1 + responselike: 3.0.0 + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + camelcase@7.0.1: {} + + caniuse-lite@1.0.30001636: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + char-regex@1.0.2: {} + + chownr@2.0.0: {} + + ci-info@3.9.0: {} + + cjs-module-lexer@1.3.1: {} + + clean-stack@2.2.0: {} + + cli-boxes@3.0.0: {} + + cli-cursor@4.0.0: + dependencies: + restore-cursor: 4.0.0 + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.1.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + co@4.6.0: {} + + collect-v8-coverage@1.0.2: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-support@1.1.3: {} + + colorette@2.0.20: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@10.0.1: {} + + commander@11.1.0: {} + + commander@12.1.0: {} + + commander@2.20.3: {} + + commondir@1.0.1: {} + + compare-func@2.0.0: + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + + concat-map@0.0.1: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + configstore@6.0.0: + dependencies: + dot-prop: 6.0.1 + graceful-fs: 4.2.11 + unique-string: 3.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 5.1.0 + + console-control-strings@1.1.0: {} + + conventional-changelog-angular@7.0.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-angular@8.0.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-atom@5.0.0: {} + + conventional-changelog-cli@5.0.0(conventional-commits-filter@5.0.0): + dependencies: + add-stream: 1.0.0 + conventional-changelog: 6.0.0(conventional-commits-filter@5.0.0) + meow: 13.2.0 + tempfile: 5.0.0 + transitivePeerDependencies: + - conventional-commits-filter + + conventional-changelog-codemirror@5.0.0: {} + + conventional-changelog-conventionalcommits@7.0.2: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-conventionalcommits@8.0.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-core@8.0.0(conventional-commits-filter@5.0.0): + dependencies: + '@hutson/parse-repository-url': 5.0.0 + add-stream: 1.0.0 + conventional-changelog-writer: 8.0.0 + conventional-commits-parser: 6.0.0 + git-raw-commits: 5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0) + git-semver-tags: 8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0) + hosted-git-info: 7.0.2 + normalize-package-data: 6.0.1 + read-package-up: 11.0.0 + read-pkg: 9.0.1 + transitivePeerDependencies: + - conventional-commits-filter + + conventional-changelog-ember@5.0.0: {} + + conventional-changelog-eslint@6.0.0: {} + + conventional-changelog-express@5.0.0: {} + + conventional-changelog-jquery@6.0.0: {} + + conventional-changelog-jshint@5.0.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-preset-loader@5.0.0: {} + + conventional-changelog-writer@8.0.0: + dependencies: + '@types/semver': 7.5.8 + conventional-commits-filter: 5.0.0 + handlebars: 4.7.8 + meow: 13.2.0 + semver: 7.6.2 + + conventional-changelog@6.0.0(conventional-commits-filter@5.0.0): + dependencies: + conventional-changelog-angular: 8.0.0 + conventional-changelog-atom: 5.0.0 + conventional-changelog-codemirror: 5.0.0 + conventional-changelog-conventionalcommits: 8.0.0 + conventional-changelog-core: 8.0.0(conventional-commits-filter@5.0.0) + conventional-changelog-ember: 5.0.0 + conventional-changelog-eslint: 6.0.0 + conventional-changelog-express: 5.0.0 + conventional-changelog-jquery: 6.0.0 + conventional-changelog-jshint: 5.0.0 + conventional-changelog-preset-loader: 5.0.0 + transitivePeerDependencies: + - conventional-commits-filter + + conventional-commits-filter@5.0.0: {} + + conventional-commits-parser@5.0.0: + dependencies: + JSONStream: 1.3.5 + is-text-path: 2.0.0 + meow: 12.1.1 + split2: 4.2.0 + + conventional-commits-parser@6.0.0: + dependencies: + meow: 13.2.0 + + convert-source-map@2.0.0: {} + + core-js@3.37.1: {} + + cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.4)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5): + dependencies: + '@types/node': 20.14.4 + cosmiconfig: 9.0.0(typescript@5.4.5) + jiti: 1.21.6 + typescript: 5.4.5 + + cosmiconfig@9.0.0(typescript@5.4.5): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.4.5 + + create-jest@29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: + optional: true + + cross-spawn@6.0.5: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-random-string@4.0.0: + dependencies: + type-fest: 1.4.0 + + cssom@0.3.8: {} + + cssom@0.5.0: {} + + cssstyle@2.3.0: + dependencies: + cssom: 0.3.8 + + dargs@8.1.0: {} + + data-urls@3.0.2: + dependencies: + abab: 2.0.6 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + decimal.js@10.4.3: {} + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + dedent@1.5.3: {} + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + defer-to-connect@2.0.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + delegates@1.0.0: {} + + detect-newline@3.1.0: {} + + diff-sequences@29.6.3: {} + + diff@4.0.2: + optional: true + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + domexception@4.0.0: + dependencies: + webidl-conversions: 7.0.0 + + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + + dot-prop@6.0.1: + dependencies: + is-obj: 2.0.0 + + eastasianwidth@0.2.0: {} + + electron-to-chromium@1.4.803: {} + + email-addresses@5.0.0: {} + + emittery@0.13.1: {} + + emoji-regex@10.3.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + err-code@2.0.3: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 is-string: 1.0.7 - is-typed-array: 1.1.10 + is-typed-array: 1.1.13 is-weakref: 1.0.2 - object-inspect: 1.12.3 + object-inspect: 1.13.1 object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.0 - safe-regex-test: 1.0.0 - string.prototype.trim: 1.2.7 - string.prototype.trimend: 1.0.6 - string.prototype.trimstart: 1.0.6 - typed-array-length: 1.0.4 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 unbox-primitive: 1.0.2 - which-typed-array: 1.1.9 - dev: true + which-typed-array: 1.1.15 - /es-set-tostringtag/2.0.1: - resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} - engines: {node: '>= 0.4'} + es-define-property@1.0.0: dependencies: - get-intrinsic: 1.2.0 - has: 1.0.3 - has-tostringtag: 1.0.0 - dev: true + get-intrinsic: 1.2.4 - /es-to-primitive/1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} - engines: {node: '>= 0.4'} + es-errors@1.3.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-to-primitive@1.2.1: dependencies: is-callable: 1.2.7 is-date-object: 1.0.5 is-symbol: 1.0.4 - dev: true - /esbuild/0.17.17: - resolution: {integrity: sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true + esbuild@0.21.5: optionalDependencies: - '@esbuild/android-arm': 0.17.17 - '@esbuild/android-arm64': 0.17.17 - '@esbuild/android-x64': 0.17.17 - '@esbuild/darwin-arm64': 0.17.17 - '@esbuild/darwin-x64': 0.17.17 - '@esbuild/freebsd-arm64': 0.17.17 - '@esbuild/freebsd-x64': 0.17.17 - '@esbuild/linux-arm': 0.17.17 - '@esbuild/linux-arm64': 0.17.17 - '@esbuild/linux-ia32': 0.17.17 - '@esbuild/linux-loong64': 0.17.17 - '@esbuild/linux-mips64el': 0.17.17 - '@esbuild/linux-ppc64': 0.17.17 - '@esbuild/linux-riscv64': 0.17.17 - '@esbuild/linux-s390x': 0.17.17 - '@esbuild/linux-x64': 0.17.17 - '@esbuild/netbsd-x64': 0.17.17 - '@esbuild/openbsd-x64': 0.17.17 - '@esbuild/sunos-x64': 0.17.17 - '@esbuild/win32-arm64': 0.17.17 - '@esbuild/win32-ia32': 0.17.17 - '@esbuild/win32-x64': 0.17.17 - dev: true - - /escalade/3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - dev: true - - /escape-goat/4.0.0: - resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} - engines: {node: '>=12'} - dev: true - - /escape-string-regexp/1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true - - /escape-string-regexp/2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true - - /escape-string-regexp/4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true - - /escodegen/2.0.0: - resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} - engines: {node: '>=6.0'} - hasBin: true + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.1.2: {} + + escape-goat@4.0.0: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + escape-string-regexp@4.0.0: {} + + escodegen@2.1.0: dependencies: esprima: 4.0.1 estraverse: 5.3.0 esutils: 2.0.3 - optionator: 0.8.3 optionalDependencies: source-map: 0.6.1 - dev: true - /eslint-config-prettier/8.8.0_eslint@8.38.0: - resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' + eslint-config-prettier@9.1.0(eslint@9.5.0): dependencies: - eslint: 8.38.0 - dev: true + eslint: 9.5.0 - /eslint-plugin-prettier/4.2.1_mrzcadguhkbme6yx3ehduvsjxu: - resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} - engines: {node: '>=12.0.0'} - peerDependencies: - eslint: '>=7.28.0' - eslint-config-prettier: '*' - prettier: '>=2.0.0' - peerDependenciesMeta: - eslint-config-prettier: - optional: true + eslint-plugin-perfectionist@2.11.0(eslint@9.5.0)(typescript@5.4.5): dependencies: - eslint: 8.38.0 - eslint-config-prettier: 8.8.0_eslint@8.38.0 - prettier: 2.8.7 - prettier-linter-helpers: 1.0.0 - dev: true + '@typescript-eslint/utils': 7.13.1(eslint@9.5.0)(typescript@5.4.5) + eslint: 9.5.0 + minimatch: 9.0.4 + natural-compare-lite: 1.4.0 + transitivePeerDependencies: + - supports-color + - typescript - /eslint-scope/5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} + eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@9.5.0))(eslint@9.5.0)(prettier@3.3.2): dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: true + eslint: 9.5.0 + prettier: 3.3.2 + prettier-linter-helpers: 1.0.0 + synckit: 0.8.8 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@9.5.0) - /eslint-scope/7.2.0: - resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-scope@8.0.1: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 - dev: true - /eslint-visitor-keys/3.4.0: - resolution: {integrity: sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + eslint-visitor-keys@3.4.3: {} - /eslint/8.38.0: - resolution: {integrity: sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true + eslint-visitor-keys@4.0.0: {} + + eslint@9.5.0: dependencies: - '@eslint-community/eslint-utils': 4.4.0_eslint@8.38.0 - '@eslint-community/regexpp': 4.5.0 - '@eslint/eslintrc': 2.0.2 - '@eslint/js': 8.38.0 - '@humanwhocodes/config-array': 0.11.8 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.5.0) + '@eslint-community/regexpp': 4.10.1 + '@eslint/config-array': 0.16.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.5.0 '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.0 '@nodelib/fs.walk': 1.2.8 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 + debug: 4.3.5 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.0 - eslint-visitor-keys: 3.4.0 - espree: 9.5.1 + eslint-scope: 8.0.1 + eslint-visitor-keys: 4.0.0 + espree: 10.1.0 esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 + file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.20.0 - grapheme-splitter: 1.0.4 - ignore: 5.2.4 - import-fresh: 3.3.0 + ignore: 5.3.1 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-sdsl: 4.4.0 - 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.1 + optionator: 0.9.4 strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 text-table: 0.2.0 transitivePeerDependencies: - supports-color - dev: true - /esno/0.16.3: - resolution: {integrity: sha512-6slSBEV1lMKcX13DBifvnDFpNno5WXhw4j/ff7RI0y51BZiDqEe5dNhhjhIQ3iCOQuzsm2MbVzmwqbN78BBhPg==} - hasBin: true + esno@4.7.0: dependencies: - tsx: 3.12.6 - dev: true + tsx: 4.15.6 - /espree/9.5.1: - resolution: {integrity: sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + espree@10.1.0: dependencies: - acorn: 8.8.2 - acorn-jsx: 5.3.2_acorn@8.8.2 - eslint-visitor-keys: 3.4.0 - dev: true + acorn: 8.12.0 + acorn-jsx: 5.3.2(acorn@8.12.0) + eslint-visitor-keys: 4.0.0 - /esprima/4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true + esprima@4.0.1: {} - /esquery/1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} + esquery@1.5.0: dependencies: estraverse: 5.3.0 - dev: true - /esrecurse/4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 - dev: true - /estraverse/4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true + estraverse@5.3.0: {} - /estraverse/5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true + estree-walker@2.0.2: {} - /estree-walker/2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - dev: true + esutils@2.0.3: {} - /esutils/2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true + eventemitter3@5.0.1: {} - /execa/5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} + execa@5.1.1: dependencies: cross-spawn: 7.0.3 get-stream: 6.0.1 @@ -3323,262 +6405,185 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 strip-final-newline: 2.0.0 - dev: true - /execa/7.1.1: - resolution: {integrity: sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==} - engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + execa@8.0.1: dependencies: cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 4.3.1 + get-stream: 8.0.1 + human-signals: 5.0.0 is-stream: 3.0.0 merge-stream: 2.0.0 - npm-run-path: 5.1.0 + npm-run-path: 5.3.0 onetime: 6.0.0 - signal-exit: 3.0.7 + signal-exit: 4.1.0 strip-final-newline: 3.0.0 - dev: true - /exit/0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - dev: true + execa@9.2.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.3 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 7.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 5.3.0 + pretty-ms: 9.0.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.0.2 - /expect/29.5.0: - resolution: {integrity: sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + exit@0.1.2: {} + + expect@29.7.0: dependencies: - '@jest/expect-utils': 29.5.0 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-util: 29.5.0 - dev: true + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 - /fast-deep-equal/3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true + exponential-backoff@3.1.1: {} - /fast-diff/1.2.0: - resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} - dev: true + fast-deep-equal@3.1.3: {} - /fast-glob/3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - engines: {node: '>=8.6.0'} + fast-diff@1.3.0: {} + + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.5 - dev: true + micromatch: 4.0.7 - /fast-json-stable-stringify/2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true + fast-json-stable-stringify@2.1.0: {} - /fast-levenshtein/2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true + fast-levenshtein@2.0.6: {} - /fast-memoize/2.5.2: - resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} - dev: true + fast-memoize@2.5.2: {} - /fastq/1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + fastq@1.17.1: dependencies: reusify: 1.0.4 - dev: true - /fb-watchman/2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + fb-watchman@2.0.2: dependencies: bser: 2.1.1 - dev: true - /file-entry-cache/6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + figures@6.1.0: dependencies: - flat-cache: 3.0.4 - dev: true + is-unicode-supported: 2.0.0 - /filename-reserved-regex/2.0.0: - resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} - engines: {node: '>=4'} - dev: true + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 - /filenamify/4.3.0: - resolution: {integrity: sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==} - engines: {node: '>=8'} + filename-reserved-regex@2.0.0: {} + + filenamify@4.3.0: dependencies: filename-reserved-regex: 2.0.0 strip-outer: 1.0.1 trim-repeated: 1.0.0 - dev: true - /fill-range/7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - dev: true - /find-cache-dir/3.3.2: - resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} - engines: {node: '>=8'} + find-cache-dir@3.3.2: dependencies: commondir: 1.0.1 make-dir: 3.1.0 pkg-dir: 4.2.0 - dev: true - /find-up/2.1.0: - resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} - engines: {node: '>=4'} - dependencies: - locate-path: 2.0.0 - dev: true + find-up-simple@1.0.0: {} - /find-up/4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + find-up@4.1.0: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 - dev: true - /find-up/5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + find-up@5.0.0: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 - dev: true - /flat-cache/3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} + find-up@7.0.0: dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 - dev: true + locate-path: 7.2.0 + path-exists: 5.0.0 + unicorn-magic: 0.1.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 - /flatted/3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - dev: true + flatted@3.3.1: {} - /for-each/0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + for-each@0.3.3: dependencies: is-callable: 1.2.7 - dev: true - /form-data-encoder/2.1.4: - resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} - engines: {node: '>= 14.17'} - dev: true + foreground-child@3.2.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 - /form-data/4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} + form-data-encoder@2.1.4: {} + + form-data@4.0.0: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - dev: true - /fp-and-or/0.1.3: - resolution: {integrity: sha512-wJaE62fLaB3jCYvY2ZHjZvmKK2iiLiiehX38rz5QZxtdN8fVPJDeZUiVvJrHStdTc+23LHlyZuSEKgFc0pxi2g==} - engines: {node: '>=10'} - dev: true + fp-and-or@0.1.4: {} - /fs-extra/10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} + fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true + universalify: 2.0.1 - /fs-extra/11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} - engines: {node: '>=14.14'} + fs-extra@11.2.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true - - /fs-extra/7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 - dev: true + universalify: 2.0.1 - /fs-extra/8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 - dev: true - /fs-minipass/2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} + fs-minipass@2.1.0: dependencies: minipass: 3.3.6 - dev: true - /fs-minipass/3.0.1: - resolution: {integrity: sha512-MhaJDcFRTuLidHrIttu0RDGyyXs/IYHVmlcxfLAEFIWjc1vdLAkdwT7Ace2u7DbitWC0toKMl5eJZRYNVreIMw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + fs-minipass@3.0.3: dependencies: - minipass: 4.2.8 - dev: true + minipass: 7.1.2 - /fs.realpath/1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true + fs.realpath@1.0.0: {} - /fsevents/2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true + fsevents@2.3.3: optional: true - /function-bind/1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: true + function-bind@1.1.2: {} - /function.prototype.name/1.1.5: - resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} - engines: {node: '>= 0.4'} + function.prototype.name@1.1.6: dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 functions-have-names: 1.2.3 - dev: true - /functions-have-names/1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true + functions-have-names@1.2.3: {} - /gauge/4.0.4: - resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + gauge@4.0.4: dependencies: aproba: 2.0.0 color-support: 1.1.3 @@ -3588,129 +6593,93 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wide-align: 1.1.5 - dev: true - /gensync/1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true + gensync@1.0.0-beta.2: {} - /get-caller-file/2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true + get-caller-file@2.0.5: {} + + get-east-asian-width@1.2.0: {} - /get-intrinsic/1.2.0: - resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} + get-intrinsic@1.2.4: dependencies: - function-bind: 1.1.1 - has: 1.0.3 + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 has-symbols: 1.0.3 - dev: true + hasown: 2.0.2 - /get-package-type/0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true + get-package-type@0.1.0: {} - /get-pkg-repo/4.2.1: - resolution: {integrity: sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==} - engines: {node: '>=6.9.0'} - hasBin: true - dependencies: - '@hutson/parse-repository-url': 3.0.2 - hosted-git-info: 4.1.0 - through2: 2.0.5 - yargs: 16.2.0 - dev: true + get-stdin@8.0.0: {} - /get-stdin/8.0.0: - resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} - engines: {node: '>=10'} - dev: true + get-stream@6.0.1: {} - /get-stream/6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - dev: true + get-stream@8.0.1: {} - /get-symbol-description/1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} - engines: {node: '>= 0.4'} + get-stream@9.0.1: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - dev: true + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 - /get-tsconfig/4.5.0: - resolution: {integrity: sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==} - dev: true + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 - /gh-pages/5.0.0: - resolution: {integrity: sha512-Nqp1SjkPIB94Xw/3yYNTUL+G2dxlhjvv1zeN/4kMC1jfViTEqhtVz/Ba1zSXHuvXCN9ADNS1dN4r5/J/nZWEQQ==} - engines: {node: '>=10'} - hasBin: true + get-tsconfig@4.7.5: dependencies: - async: 3.2.4 - commander: 2.20.3 + resolve-pkg-maps: 1.0.0 + + gh-pages@6.1.1: + dependencies: + async: 3.2.5 + commander: 11.1.0 email-addresses: 5.0.0 filenamify: 4.3.0 find-cache-dir: 3.3.2 - fs-extra: 8.1.0 + fs-extra: 11.2.0 globby: 6.1.0 - dev: true - - /git-raw-commits/2.0.11: - resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} - engines: {node: '>=10'} - hasBin: true - dependencies: - dargs: 7.0.0 - lodash: 4.17.21 - meow: 8.1.2 - split2: 3.2.2 - through2: 4.0.2 - dev: true - /git-remote-origin-url/2.0.0: - resolution: {integrity: sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==} - engines: {node: '>=4'} + git-raw-commits@4.0.0: dependencies: - gitconfiglocal: 1.0.0 - pify: 2.3.0 - dev: true + dargs: 8.1.0 + meow: 12.1.1 + split2: 4.2.0 - /git-semver-tags/4.1.1: - resolution: {integrity: sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==} - engines: {node: '>=10'} - hasBin: true + git-raw-commits@5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0): dependencies: - meow: 8.1.2 - semver: 6.3.0 - dev: true + '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0) + meow: 13.2.0 + transitivePeerDependencies: + - conventional-commits-filter + - conventional-commits-parser - /gitconfiglocal/1.0.0: - resolution: {integrity: sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==} + git-semver-tags@8.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0): dependencies: - ini: 1.3.8 - dev: true + '@conventional-changelog/git-client': 1.0.1(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.0.0) + meow: 13.2.0 + transitivePeerDependencies: + - conventional-commits-filter + - conventional-commits-parser - /glob-parent/5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 - dev: true - /glob-parent/6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + glob-parent@6.0.2: dependencies: is-glob: 4.0.3 - dev: true - /glob/7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + glob@10.4.1: + dependencies: + foreground-child: 3.2.1 + jackspeak: 3.4.0 + minimatch: 9.0.4 + minipass: 7.1.2 + path-scurry: 1.11.1 + + glob@7.2.3: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -3718,1469 +6687,932 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true - /glob/8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} + glob@8.1.0: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 minimatch: 5.1.6 once: 1.4.0 - dev: true - - /glob/9.3.5: - resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - fs.realpath: 1.0.0 - minimatch: 8.0.4 - minipass: 4.2.8 - path-scurry: 1.7.0 - dev: true - /global-dirs/0.1.1: - resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} - engines: {node: '>=4'} + global-directory@4.0.1: dependencies: - ini: 1.3.8 - dev: true + ini: 4.1.1 - /global-dirs/3.0.1: - resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} - engines: {node: '>=10'} + global-dirs@3.0.1: dependencies: ini: 2.0.0 - dev: true - /globals/11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true + globals@11.12.0: {} - /globals/13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - dev: true + globals@14.0.0: {} - /globalthis/1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} - engines: {node: '>= 0.4'} + globalthis@1.0.4: dependencies: - define-properties: 1.2.0 - dev: true + define-properties: 1.2.1 + gopd: 1.0.1 - /globby/11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + globby@11.1.0: dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.2.12 - ignore: 5.2.4 + fast-glob: 3.3.2 + ignore: 5.3.1 merge2: 1.4.1 slash: 3.0.0 - dev: true - /globby/6.1.0: - resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} - engines: {node: '>=0.10.0'} + globby@6.1.0: dependencies: array-union: 1.0.2 glob: 7.2.3 object-assign: 4.1.1 pify: 2.3.0 pinkie-promise: 2.0.1 - dev: true - /gopd/1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + gopd@1.0.1: dependencies: - get-intrinsic: 1.2.0 - dev: true + get-intrinsic: 1.2.4 - /got/12.6.0: - resolution: {integrity: sha512-WTcaQ963xV97MN3x0/CbAriXFZcXCfgxVp91I+Ze6pawQOa7SgzwSx2zIJJsX+kTajMnVs0xcFD1TxZKFqhdnQ==} - engines: {node: '>=14.16'} + got@12.6.1: dependencies: - '@sindresorhus/is': 5.3.0 + '@sindresorhus/is': 5.6.0 '@szmarczak/http-timer': 5.0.1 cacheable-lookup: 7.0.0 - cacheable-request: 10.2.9 + cacheable-request: 10.2.14 decompress-response: 6.0.0 form-data-encoder: 2.1.4 get-stream: 6.0.1 - http2-wrapper: 2.2.0 + http2-wrapper: 2.2.1 lowercase-keys: 3.0.0 p-cancelable: 3.0.0 responselike: 3.0.0 - dev: true - /graceful-fs/4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: true + graceful-fs@4.2.10: {} - /graceful-fs/4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true + graceful-fs@4.2.11: {} - /grapheme-splitter/1.0.4: - resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} - dev: true + graphemer@1.4.0: {} - /handlebars/4.7.7: - resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} - engines: {node: '>=0.4.7'} - hasBin: true + handlebars@4.7.8: dependencies: minimist: 1.2.8 neo-async: 2.6.2 source-map: 0.6.1 wordwrap: 1.0.0 optionalDependencies: - uglify-js: 3.17.4 - dev: true - - /hard-rejection/2.1.0: - resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} - engines: {node: '>=6'} - dev: true + uglify-js: 3.18.0 - /has-bigints/1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - dev: true + has-bigints@1.0.2: {} - /has-flag/3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true + has-flag@3.0.0: {} - /has-flag/4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true + has-flag@4.0.0: {} - /has-property-descriptors/1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + has-property-descriptors@1.0.2: dependencies: - get-intrinsic: 1.2.0 - dev: true + es-define-property: 1.0.0 - /has-proto/1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - dev: true + has-proto@1.0.3: {} - /has-symbols/1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - dev: true + has-symbols@1.0.3: {} - /has-tostringtag/1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} - engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: dependencies: has-symbols: 1.0.3 - dev: true - /has-unicode/2.0.1: - resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - dev: true + has-unicode@2.0.1: {} - /has-yarn/3.0.0: - resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true + has-yarn@3.0.0: {} - /has/1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} + hasown@2.0.2: dependencies: - function-bind: 1.1.1 - dev: true + function-bind: 1.1.2 - /hosted-git-info/2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - dev: true + hosted-git-info@2.8.9: {} - /hosted-git-info/4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} + hosted-git-info@5.2.1: dependencies: - lru-cache: 6.0.0 - dev: true + lru-cache: 7.18.3 - /hosted-git-info/5.2.1: - resolution: {integrity: sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hosted-git-info@6.1.1: dependencies: lru-cache: 7.18.3 - dev: true - /hosted-git-info/6.1.1: - resolution: {integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hosted-git-info@7.0.2: dependencies: - lru-cache: 7.18.3 - dev: true + lru-cache: 10.2.2 - /html-encoding-sniffer/3.0.0: - resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} - engines: {node: '>=12'} + html-encoding-sniffer@3.0.0: dependencies: whatwg-encoding: 2.0.0 - dev: true - /html-escaper/2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true + html-escaper@2.0.2: {} - /http-cache-semantics/4.1.1: - resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} - dev: true + http-cache-semantics@4.1.1: {} - /http-proxy-agent/5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} + http-proxy-agent@5.0.0: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.5 transitivePeerDependencies: - supports-color - dev: true - /http2-wrapper/2.2.0: - resolution: {integrity: sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==} - engines: {node: '>=10.19.0'} + http2-wrapper@2.2.1: dependencies: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - dev: true - /https-proxy-agent/5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.5 transitivePeerDependencies: - supports-color - dev: true - /human-signals/2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true + human-signals@2.1.0: {} - /human-signals/4.3.1: - resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} - engines: {node: '>=14.18.0'} - dev: true + human-signals@5.0.0: {} - /humanize-ms/1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + human-signals@7.0.0: {} + + humanize-ms@1.2.1: dependencies: ms: 2.1.3 - dev: true - /husky/8.0.3: - resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} - engines: {node: '>=14'} - hasBin: true - dev: true + husky@9.0.11: {} - /iconv-lite/0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 - dev: true - /ignore-walk/6.0.2: - resolution: {integrity: sha512-ezmQ1Dg2b3jVZh2Dh+ar6Eu2MqNSTkyb32HU2MAQQQX9tKM3q/UQ/9lf03lQ5hW+fOeoMnwxwkleZ0xcNp0/qg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ignore-walk@6.0.5: dependencies: - minimatch: 7.4.6 - dev: true + minimatch: 9.0.4 - /ignore/5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} - engines: {node: '>= 4'} - dev: true + ignore@5.3.1: {} - /import-fresh/3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: true - /import-lazy/4.0.0: - resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} - engines: {node: '>=8'} - dev: true + import-lazy@4.0.0: {} - /import-local/3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true + import-local@3.1.0: dependencies: pkg-dir: 4.2.0 resolve-cwd: 3.0.0 - dev: true - /imurmurhash/0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true + import-meta-resolve@4.1.0: {} - /indent-string/4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - dev: true + imurmurhash@0.1.4: {} - /infer-owner/1.0.4: - resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} - dev: true + indent-string@4.0.0: {} - /inflight/1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + index-to-position@0.1.2: {} + + infer-owner@1.0.4: {} + + inflight@1.0.6: dependencies: once: 1.4.0 wrappy: 1.0.2 - dev: true - /inherits/2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true + inherits@2.0.4: {} - /ini/1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - dev: true + ini@1.3.8: {} - /ini/2.0.0: - resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} - engines: {node: '>=10'} - dev: true + ini@2.0.0: {} - /ini/4.1.0: - resolution: {integrity: sha512-HLR38RSF2iulAzc3I/sma4CoYxQP844rPYCNfzGDOHqa/YqVlwuuZgBx6M50/X8dKgzk0cm1qRg3+47mK2N+cQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: true + ini@4.1.1: {} - /internal-slot/1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} - engines: {node: '>= 0.4'} + ini@4.1.3: {} + + internal-slot@1.0.7: dependencies: - get-intrinsic: 1.2.0 - has: 1.0.3 - side-channel: 1.0.4 - dev: true + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 - /ip/2.0.0: - resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} - dev: true + ip-address@9.0.5: + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 - /is-array-buffer/3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + is-array-buffer@3.0.4: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - is-typed-array: 1.1.10 - dev: true + call-bind: 1.0.7 + get-intrinsic: 1.2.4 - /is-arrayish/0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true + is-arrayish@0.2.1: {} - /is-bigint/1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + is-bigint@1.0.4: dependencies: has-bigints: 1.0.2 - dev: true - /is-boolean-object/1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} + is-boolean-object@1.1.2: dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true + call-bind: 1.0.7 + has-tostringtag: 1.0.2 - /is-callable/1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true + is-callable@1.2.7: {} - /is-ci/3.0.1: - resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} - hasBin: true + is-ci@3.0.1: dependencies: - ci-info: 3.8.0 - dev: true + ci-info: 3.9.0 - /is-core-module/2.12.0: - resolution: {integrity: sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==} + is-core-module@2.13.1: dependencies: - has: 1.0.3 - dev: true + hasown: 2.0.2 - /is-date-object/1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} + is-data-view@1.0.1: dependencies: - has-tostringtag: 1.0.0 - dev: true + is-typed-array: 1.1.13 - /is-extglob/2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 - /is-fullwidth-code-point/3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true + is-extglob@2.1.1: {} - /is-fullwidth-code-point/4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - dev: true + is-fullwidth-code-point@3.0.0: {} - /is-generator-fn/2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - dev: true + is-fullwidth-code-point@4.0.0: {} - /is-glob/4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.2.0 + + is-generator-fn@2.1.0: {} + + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - dev: true - /is-installed-globally/0.4.0: - resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} - engines: {node: '>=10'} + is-installed-globally@0.4.0: dependencies: global-dirs: 3.0.1 is-path-inside: 3.0.3 - dev: true - /is-lambda/1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - dev: true + is-lambda@1.0.1: {} - /is-negative-zero/2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} - engines: {node: '>= 0.4'} - dev: true + is-negative-zero@2.0.3: {} - /is-npm/6.0.0: - resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true + is-npm@6.0.0: {} - /is-number-object/1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} - engines: {node: '>= 0.4'} + is-number-object@1.0.7: dependencies: - has-tostringtag: 1.0.0 - dev: true + has-tostringtag: 1.0.2 - /is-number/7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true + is-number@7.0.0: {} - /is-obj/2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} - dev: true + is-obj@2.0.0: {} - /is-path-inside/3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - dev: true + is-path-inside@3.0.3: {} - /is-plain-obj/1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - dev: true + is-plain-obj@4.1.0: {} - /is-potential-custom-element-name/1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - dev: true + is-potential-custom-element-name@1.0.1: {} - /is-regex/1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} + is-regex@1.1.4: dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true + call-bind: 1.0.7 + has-tostringtag: 1.0.2 - /is-shared-array-buffer/1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + is-shared-array-buffer@1.0.3: dependencies: - call-bind: 1.0.2 - dev: true + call-bind: 1.0.7 - /is-stream/2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true + is-stream@2.0.1: {} - /is-stream/3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true + is-stream@3.0.0: {} - /is-string/1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} + is-stream@4.0.1: {} + + is-string@1.0.7: dependencies: - has-tostringtag: 1.0.0 - dev: true + has-tostringtag: 1.0.2 - /is-symbol/1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} + is-symbol@1.0.4: dependencies: has-symbols: 1.0.3 - dev: true - /is-text-path/1.0.1: - resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==} - engines: {node: '>=0.10.0'} + is-text-path@2.0.0: dependencies: - text-extensions: 1.9.0 - dev: true + text-extensions: 2.4.0 - /is-typed-array/1.1.10: - resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} - engines: {node: '>= 0.4'} + is-typed-array@1.1.13: dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 - dev: true + which-typed-array: 1.1.15 - /is-typedarray/1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: true + is-typedarray@1.0.0: {} - /is-weakref/1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + is-unicode-supported@2.0.0: {} + + is-weakref@1.0.2: dependencies: - call-bind: 1.0.2 - dev: true + call-bind: 1.0.7 - /is-yarn-global/0.4.1: - resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} - engines: {node: '>=12'} - dev: true + is-yarn-global@0.4.1: {} - /isarray/1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: true + isarray@2.0.5: {} - /isexe/2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true + isexe@2.0.0: {} - /istanbul-lib-coverage/3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} - engines: {node: '>=8'} - dev: true + istanbul-lib-coverage@3.2.2: {} - /istanbul-lib-instrument/5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} + istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.21.4 - '@babel/parser': 7.21.4 + '@babel/core': 7.24.7 + '@babel/parser': 7.24.7 '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 6.3.0 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: true - /istanbul-lib-report/3.0.0: - resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} - engines: {node: '>=8'} + istanbul-lib-instrument@6.0.2: dependencies: - istanbul-lib-coverage: 3.2.0 - make-dir: 3.1.0 + '@babel/core': 7.24.7 + '@babel/parser': 7.24.7 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.6.2 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 supports-color: 7.2.0 - dev: true - /istanbul-lib-source-maps/4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} + istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.4 - istanbul-lib-coverage: 3.2.0 + debug: 4.3.5 + istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color - dev: true - /istanbul-reports/3.1.5: - resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} - engines: {node: '>=8'} + istanbul-reports@3.1.7: dependencies: html-escaper: 2.0.2 - istanbul-lib-report: 3.0.0 - dev: true + istanbul-lib-report: 3.0.1 - /jest-changed-files/29.5.0: - resolution: {integrity: sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jackspeak@3.4.0: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jest-changed-files@29.7.0: dependencies: execa: 5.1.1 + jest-util: 29.7.0 p-limit: 3.1.0 - dev: true - /jest-circus/29.5.0: - resolution: {integrity: sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-circus@29.7.0: dependencies: - '@jest/environment': 29.5.0 - '@jest/expect': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.15.11 + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.4 chalk: 4.1.2 co: 4.6.0 - dedent: 0.7.0 + dedent: 1.5.3 is-generator-fn: 2.1.0 - jest-each: 29.5.0 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-runtime: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 p-limit: 3.1.0 - pretty-format: 29.5.0 - pure-rand: 6.0.1 + pretty-format: 29.7.0 + pure-rand: 6.1.0 slash: 3.0.0 stack-utils: 2.0.6 transitivePeerDependencies: + - babel-plugin-macros - supports-color - dev: true - /jest-cli/29.5.0_@types+node@18.15.11: - resolution: {integrity: sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest-cli@29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)): dependencies: - '@jest/core': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 chalk: 4.1.2 + create-jest: 29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)) exit: 0.1.2 - graceful-fs: 4.2.11 import-local: 3.1.0 - jest-config: 29.5.0_@types+node@18.15.11 - jest-util: 29.5.0 - jest-validate: 29.5.0 - prompts: 2.4.2 - yargs: 17.7.1 + jest-config: 29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 transitivePeerDependencies: - '@types/node' + - babel-plugin-macros - supports-color - ts-node - dev: true - /jest-config/29.5.0_@types+node@18.15.11: - resolution: {integrity: sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true + jest-config@29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)): dependencies: - '@babel/core': 7.21.4 - '@jest/test-sequencer': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.15.11 - babel-jest: 29.5.0_@babel+core@7.21.4 + '@babel/core': 7.24.7 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.24.7) chalk: 4.1.2 - ci-info: 3.8.0 + ci-info: 3.9.0 deepmerge: 4.3.1 glob: 7.2.3 graceful-fs: 4.2.11 - jest-circus: 29.5.0 - jest-environment-node: 29.5.0 - jest-get-type: 29.4.3 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-runner: 29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - micromatch: 4.0.5 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.7 parse-json: 5.2.0 - pretty-format: 29.5.0 + pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.14.4 + ts-node: 10.9.2(@types/node@20.14.4)(typescript@5.4.5) transitivePeerDependencies: + - babel-plugin-macros - supports-color - dev: true - /jest-diff/29.5.0: - resolution: {integrity: sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-diff@29.7.0: dependencies: chalk: 4.1.2 - diff-sequences: 29.4.3 - jest-get-type: 29.4.3 - pretty-format: 29.5.0 - dev: true + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 - /jest-docblock/29.4.3: - resolution: {integrity: sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-docblock@29.7.0: dependencies: detect-newline: 3.1.0 - dev: true - /jest-each/29.5.0: - resolution: {integrity: sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-each@29.7.0: dependencies: - '@jest/types': 29.5.0 + '@jest/types': 29.6.3 chalk: 4.1.2 - jest-get-type: 29.4.3 - jest-util: 29.5.0 - pretty-format: 29.5.0 - dev: true + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 - /jest-environment-jsdom/29.5.0: - resolution: {integrity: sha512-/KG8yEK4aN8ak56yFVdqFDzKNHgF4BAymCx2LbPNPsUshUlfAl0eX402Xm1pt+eoG9SLZEUVifqXtX8SK74KCw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true + jest-environment-jsdom@29.7.0: dependencies: - '@jest/environment': 29.5.0 - '@jest/fake-timers': 29.5.0 - '@jest/types': 29.5.0 + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 18.15.11 - jest-mock: 29.5.0 - jest-util: 29.5.0 + '@types/node': 20.14.4 + jest-mock: 29.7.0 + jest-util: 29.7.0 jsdom: 20.0.3 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - dev: true - /jest-environment-node/29.5.0: - resolution: {integrity: sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-environment-node@29.7.0: dependencies: - '@jest/environment': 29.5.0 - '@jest/fake-timers': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.15.11 - jest-mock: 29.5.0 - jest-util: 29.5.0 - dev: true + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.4 + jest-mock: 29.7.0 + jest-util: 29.7.0 - /jest-get-type/29.4.3: - resolution: {integrity: sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true + jest-get-type@29.6.3: {} - /jest-haste-map/29.5.0: - resolution: {integrity: sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-haste-map@29.7.0: dependencies: - '@jest/types': 29.5.0 - '@types/graceful-fs': 4.1.6 - '@types/node': 18.15.11 + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 20.14.4 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 - jest-regex-util: 29.4.3 - jest-util: 29.5.0 - jest-worker: 29.5.0 - micromatch: 4.0.5 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.7 walker: 1.0.8 optionalDependencies: - fsevents: 2.3.2 - dev: true + fsevents: 2.3.3 - /jest-leak-detector/29.5.0: - resolution: {integrity: sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-leak-detector@29.7.0: dependencies: - jest-get-type: 29.4.3 - pretty-format: 29.5.0 - dev: true + jest-get-type: 29.6.3 + pretty-format: 29.7.0 - /jest-matcher-utils/29.5.0: - resolution: {integrity: sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-matcher-utils@29.7.0: dependencies: chalk: 4.1.2 - jest-diff: 29.5.0 - jest-get-type: 29.4.3 - pretty-format: 29.5.0 - dev: true + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 - /jest-message-util/29.5.0: - resolution: {integrity: sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-message-util@29.7.0: dependencies: - '@babel/code-frame': 7.21.4 - '@jest/types': 29.5.0 - '@types/stack-utils': 2.0.1 + '@babel/code-frame': 7.24.7 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 chalk: 4.1.2 graceful-fs: 4.2.11 - micromatch: 4.0.5 - pretty-format: 29.5.0 + micromatch: 4.0.7 + pretty-format: 29.7.0 slash: 3.0.0 stack-utils: 2.0.6 - dev: true - /jest-mock/29.5.0: - resolution: {integrity: sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-mock@29.7.0: dependencies: - '@jest/types': 29.5.0 - '@types/node': 18.15.11 - jest-util: 29.5.0 - dev: true + '@jest/types': 29.6.3 + '@types/node': 20.14.4 + jest-util: 29.7.0 - /jest-pnp-resolver/1.2.3_jest-resolve@29.5.0: - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - dependencies: - jest-resolve: 29.5.0 - dev: true + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 - /jest-regex-util/29.4.3: - resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true + jest-regex-util@29.6.3: {} - /jest-resolve-dependencies/29.5.0: - resolution: {integrity: sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve-dependencies@29.7.0: dependencies: - jest-regex-util: 29.4.3 - jest-snapshot: 29.5.0 + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 transitivePeerDependencies: - supports-color - dev: true - /jest-resolve/29.5.0: - resolution: {integrity: sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve@29.7.0: dependencies: chalk: 4.1.2 graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - jest-pnp-resolver: 1.2.3_jest-resolve@29.5.0 - jest-util: 29.5.0 - jest-validate: 29.5.0 - resolve: 1.22.2 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.8 resolve.exports: 2.0.2 slash: 3.0.0 - dev: true - /jest-runner/29.5.0: - resolution: {integrity: sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runner@29.7.0: dependencies: - '@jest/console': 29.5.0 - '@jest/environment': 29.5.0 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.15.11 + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.4 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 - jest-docblock: 29.4.3 - jest-environment-node: 29.5.0 - jest-haste-map: 29.5.0 - jest-leak-detector: 29.5.0 - jest-message-util: 29.5.0 - jest-resolve: 29.5.0 - jest-runtime: 29.5.0 - jest-util: 29.5.0 - jest-watcher: 29.5.0 - jest-worker: 29.5.0 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 p-limit: 3.1.0 source-map-support: 0.5.13 transitivePeerDependencies: - supports-color - dev: true - /jest-runtime/29.5.0: - resolution: {integrity: sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runtime@29.7.0: dependencies: - '@jest/environment': 29.5.0 - '@jest/fake-timers': 29.5.0 - '@jest/globals': 29.5.0 - '@jest/source-map': 29.4.3 - '@jest/test-result': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.15.11 + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.4 chalk: 4.1.2 - cjs-module-lexer: 1.2.2 - collect-v8-coverage: 1.0.1 + cjs-module-lexer: 1.3.1 + collect-v8-coverage: 1.0.2 glob: 7.2.3 graceful-fs: 4.2.11 - jest-haste-map: 29.5.0 - jest-message-util: 29.5.0 - jest-mock: 29.5.0 - jest-regex-util: 29.4.3 - jest-resolve: 29.5.0 - jest-snapshot: 29.5.0 - jest-util: 29.5.0 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 slash: 3.0.0 strip-bom: 4.0.0 transitivePeerDependencies: - supports-color - dev: true - /jest-snapshot/29.5.0: - resolution: {integrity: sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.21.4 - '@babel/generator': 7.21.4 - '@babel/plugin-syntax-jsx': 7.21.4_@babel+core@7.21.4 - '@babel/plugin-syntax-typescript': 7.21.4_@babel+core@7.21.4 - '@babel/traverse': 7.21.4 - '@babel/types': 7.21.4 - '@jest/expect-utils': 29.5.0 - '@jest/transform': 29.5.0 - '@jest/types': 29.5.0 - '@types/babel__traverse': 7.18.3 - '@types/prettier': 2.7.2 - babel-preset-current-node-syntax: 1.0.1_@babel+core@7.21.4 + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.7) + '@babel/types': 7.24.7 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.7) chalk: 4.1.2 - expect: 29.5.0 + expect: 29.7.0 graceful-fs: 4.2.11 - jest-diff: 29.5.0 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.5.0 - jest-message-util: 29.5.0 - jest-util: 29.5.0 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 natural-compare: 1.4.0 - pretty-format: 29.5.0 - semver: 7.5.0 + pretty-format: 29.7.0 + semver: 7.6.2 transitivePeerDependencies: - supports-color - dev: true - /jest-util/29.5.0: - resolution: {integrity: sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-util@29.7.0: dependencies: - '@jest/types': 29.5.0 - '@types/node': 18.15.11 + '@jest/types': 29.6.3 + '@types/node': 20.14.4 chalk: 4.1.2 - ci-info: 3.8.0 + ci-info: 3.9.0 graceful-fs: 4.2.11 picomatch: 2.3.1 - dev: true - /jest-validate/29.5.0: - resolution: {integrity: sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-validate@29.7.0: dependencies: - '@jest/types': 29.5.0 + '@jest/types': 29.6.3 camelcase: 6.3.0 chalk: 4.1.2 - jest-get-type: 29.4.3 + jest-get-type: 29.6.3 leven: 3.1.0 - pretty-format: 29.5.0 - dev: true + pretty-format: 29.7.0 - /jest-watcher/29.5.0: - resolution: {integrity: sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-watcher@29.7.0: dependencies: - '@jest/test-result': 29.5.0 - '@jest/types': 29.5.0 - '@types/node': 18.15.11 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.14.4 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 - jest-util: 29.5.0 + jest-util: 29.7.0 string-length: 4.0.2 - dev: true - /jest-worker/26.6.2: - resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} - engines: {node: '>= 10.13.0'} + jest-worker@26.6.2: dependencies: - '@types/node': 18.15.11 + '@types/node': 20.14.4 merge-stream: 2.0.0 supports-color: 7.2.0 - dev: true - /jest-worker/29.5.0: - resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@29.7.0: dependencies: - '@types/node': 18.15.11 - jest-util: 29.5.0 + '@types/node': 20.14.4 + jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - dev: true - /jest/29.5.0_@types+node@18.15.11: - resolution: {integrity: sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jest@29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)): dependencies: - '@jest/core': 29.5.0 - '@jest/types': 29.5.0 + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)) + '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.5.0_@types+node@18.15.11 + jest-cli: 29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)) transitivePeerDependencies: - '@types/node' + - babel-plugin-macros - supports-color - ts-node - dev: true - /jju/1.4.0: - resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} - dev: true + jiti@1.21.6: {} - /js-sdsl/4.4.0: - resolution: {integrity: sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==} - dev: true + jju@1.4.0: {} - /js-tokens/4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true + js-tokens@4.0.0: {} - /js-yaml/3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true + js-yaml@3.14.1: dependencies: argparse: 1.0.10 esprima: 4.0.1 - dev: true - /js-yaml/4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + js-yaml@4.1.0: dependencies: - argparse: 2.0.1 - dev: true - - /jsdom/20.0.3: - resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} - engines: {node: '>=14'} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true + argparse: 2.0.1 + + jsbn@1.1.0: {} + + jsdom@20.0.3: dependencies: abab: 2.0.6 - acorn: 8.8.2 + acorn: 8.12.0 acorn-globals: 7.0.1 cssom: 0.5.0 cssstyle: 2.3.0 data-urls: 3.0.2 decimal.js: 10.4.3 domexception: 4.0.0 - escodegen: 2.0.0 + escodegen: 2.1.0 form-data: 4.0.0 html-encoding-sniffer: 3.0.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.4 + nwsapi: 2.2.10 parse5: 7.1.2 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 4.1.2 + tough-cookie: 4.1.4 w3c-xmlserializer: 4.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 whatwg-url: 11.0.0 - ws: 8.13.0 + ws: 8.17.1 xml-name-validator: 4.0.0 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - dev: true - /jsesc/2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true + jsesc@2.5.2: {} - /json-buffer/3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - dev: true + json-buffer@3.0.1: {} - /json-parse-better-errors/1.0.2: - resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} - dev: true + json-parse-better-errors@1.0.2: {} - /json-parse-even-better-errors/2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true + json-parse-even-better-errors@2.3.1: {} - /json-parse-even-better-errors/3.0.0: - resolution: {integrity: sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: true + json-parse-even-better-errors@3.0.2: {} - /json-parse-helpfulerror/1.0.3: - resolution: {integrity: sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==} + json-parse-helpfulerror@1.0.3: dependencies: jju: 1.4.0 - dev: true - - /json-schema-traverse/0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true - - /json-schema-traverse/1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: true - /json-stable-stringify-without-jsonify/1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true + json-schema-traverse@0.4.1: {} - /json-stringify-safe/5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: true + json-schema-traverse@1.0.0: {} - /json5/2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true + json-stable-stringify-without-jsonify@1.0.1: {} - /jsonc-parser/3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true + json5@2.2.3: {} - /jsonfile/4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 - dev: true - /jsonfile/6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonfile@6.1.0: dependencies: - universalify: 2.0.0 + universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 - dev: true - /jsonlines/0.1.1: - resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==} - dev: true + jsonlines@0.1.1: {} - /jsonparse/1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} - dev: true + jsonparse@1.3.1: {} - /keyv/4.5.2: - resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 - dev: true - /kind-of/6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - dev: true - - /kleur/3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true + kleur@3.0.3: {} - /kleur/4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} - dev: true + kleur@4.1.5: {} - /latest-version/7.0.0: - resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} - engines: {node: '>=14.16'} + latest-version@7.0.0: dependencies: - package-json: 8.1.0 - dev: true + package-json: 8.1.1 - /leven/3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true - - /levn/0.3.0: - resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - type-check: 0.3.2 - dev: true + leven@3.1.0: {} - /levn/0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - dev: true - /lilconfig/2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} - dev: true + lilconfig@3.1.2: {} - /lines-and-columns/1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true + lines-and-columns@1.2.4: {} - /lint-staged/13.2.1_enquirer@2.3.6: - resolution: {integrity: sha512-8gfzinVXoPfga5Dz/ZOn8I2GOhf81Wvs+KwbEXQn/oWZAvCVS2PivrXfVbFJc93zD16uC0neS47RXHIjXKYZQw==} - engines: {node: ^14.13.1 || >=16.0.0} - hasBin: true + linkify-it@5.0.0: dependencies: - chalk: 5.2.0 - cli-truncate: 3.1.0 - commander: 10.0.1 - debug: 4.3.4 - execa: 7.1.1 - lilconfig: 2.1.0 - listr2: 5.0.8_enquirer@2.3.6 - micromatch: 4.0.5 - normalize-path: 3.0.0 - object-inspect: 1.12.3 + uc.micro: 2.1.0 + + lint-staged@15.2.7: + dependencies: + chalk: 5.3.0 + commander: 12.1.0 + debug: 4.3.5 + execa: 8.0.1 + lilconfig: 3.1.2 + listr2: 8.2.1 + micromatch: 4.0.7 pidtree: 0.6.0 - string-argv: 0.3.1 - yaml: 2.2.1 + string-argv: 0.3.2 + yaml: 2.4.5 transitivePeerDependencies: - - enquirer - supports-color - dev: true - /listr2/5.0.8_enquirer@2.3.6: - resolution: {integrity: sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA==} - engines: {node: ^14.13.1 || >=16.0.0} - peerDependencies: - enquirer: '>= 2.3.0 < 3' - peerDependenciesMeta: - enquirer: - optional: true + listr2@8.2.1: dependencies: - cli-truncate: 2.1.0 + cli-truncate: 4.0.0 colorette: 2.0.20 - enquirer: 2.3.6 - log-update: 4.0.0 - p-map: 4.0.0 - rfdc: 1.3.0 - rxjs: 7.8.0 - through: 2.3.8 - wrap-ansi: 7.0.0 - dev: true + eventemitter3: 5.0.1 + log-update: 6.0.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.0 - /load-json-file/4.0.0: - resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} - engines: {node: '>=4'} + load-json-file@4.0.0: dependencies: graceful-fs: 4.2.11 parse-json: 4.0.0 pify: 3.0.0 strip-bom: 3.0.0 - dev: true - - /locate-path/2.0.0: - resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} - engines: {node: '>=4'} - dependencies: - p-locate: 2.0.0 - path-exists: 3.0.0 - dev: true - /locate-path/5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 - dev: true - /locate-path/6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 - dev: true - - /lodash.camelcase/4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - dev: true - /lodash.get/4.4.2: - resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - dev: true - - /lodash.isequal/4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - dev: true - - /lodash.isfunction/3.0.9: - resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==} - dev: true + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 - /lodash.ismatch/4.4.0: - resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} - dev: true + lodash.camelcase@4.3.0: {} - /lodash.isplainobject/4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - dev: true + lodash.isplainobject@4.0.6: {} - /lodash.kebabcase/4.1.1: - resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} - dev: true + lodash.kebabcase@4.1.1: {} - /lodash.memoize/4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - dev: true + lodash.memoize@4.1.2: {} - /lodash.merge/4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true + lodash.merge@4.6.2: {} - /lodash.mergewith/4.6.2: - resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} - dev: true + lodash.mergewith@4.6.2: {} - /lodash.snakecase/4.1.1: - resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} - dev: true + lodash.snakecase@4.1.1: {} - /lodash.startcase/4.4.0: - resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} - dev: true + lodash.startcase@4.4.0: {} - /lodash.uniq/4.5.0: - resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} - dev: true + lodash.uniq@4.5.0: {} - /lodash.upperfirst/4.3.1: - resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} - dev: true + lodash.upperfirst@4.3.1: {} - /lodash/4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true + lodash@4.17.21: {} - /log-update/4.0.0: - resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} - engines: {node: '>=10'} + log-update@6.0.0: dependencies: - ansi-escapes: 4.3.2 - cli-cursor: 3.1.0 - slice-ansi: 4.0.0 - wrap-ansi: 6.2.0 - dev: true + ansi-escapes: 6.2.1 + cli-cursor: 4.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 - /lowercase-keys/3.0.0: - resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true + lowercase-keys@3.0.0: {} - /lru-cache/5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@10.2.2: {} + + lru-cache@5.1.1: dependencies: yallist: 3.1.1 - dev: true - /lru-cache/6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + lru-cache@6.0.0: dependencies: yallist: 4.0.0 - dev: true - /lru-cache/7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - dev: true + lru-cache@7.18.3: {} - /lru-cache/9.1.0: - resolution: {integrity: sha512-qFXQEwchrZcMVen2uIDceR8Tii6kCJak5rzDStfEM0qA3YLMswaxIEZO0DhIbJ3aqaJiDjt+3crlplOb0tDtKQ==} - engines: {node: 14 || >=16.14} - dev: true + lunr@2.3.9: {} - /lunr/2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - dev: true + make-dir@3.1.0: + dependencies: + semver: 6.3.1 - /make-dir/3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} + make-dir@4.0.0: dependencies: - semver: 6.3.0 - dev: true + semver: 7.6.2 - /make-error/1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true + make-error@1.3.6: {} - /make-fetch-happen/10.2.1: - resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + make-fetch-happen@10.2.1: dependencies: - agentkeepalive: 4.3.0 + agentkeepalive: 4.5.0 cacache: 16.1.3 http-cache-semantics: 4.1.1 http-proxy-agent: 5.0.0 @@ -5199,480 +7631,285 @@ packages: transitivePeerDependencies: - bluebird - supports-color - dev: true - /make-fetch-happen/11.1.0: - resolution: {integrity: sha512-7ChuOzCb1LzdQZrTy0ky6RsCoMYeM+Fh4cY0+4zsJVhNcH5Q3OJojLY1mGkD0xAhWB29lskECVb6ZopofwjldA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + make-fetch-happen@11.1.1: dependencies: - agentkeepalive: 4.3.0 - cacache: 17.0.5 + agentkeepalive: 4.5.0 + cacache: 17.1.4 http-cache-semantics: 4.1.1 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 is-lambda: 1.0.1 lru-cache: 7.18.3 - minipass: 4.2.8 - minipass-fetch: 3.0.2 + minipass: 5.0.0 + minipass-fetch: 3.0.5 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 negotiator: 0.6.3 promise-retry: 2.0.1 socks-proxy-agent: 7.0.0 - ssri: 10.0.3 + ssri: 10.0.6 transitivePeerDependencies: - - bluebird - supports-color - dev: true - /makeerror/1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + makeerror@1.0.12: dependencies: tmpl: 1.0.5 - dev: true - /map-obj/1.0.1: - resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} - engines: {node: '>=0.10.0'} - dev: true + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 - /map-obj/4.3.0: - resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} - engines: {node: '>=8'} - dev: true + mdurl@2.0.0: {} - /marked/4.3.0: - resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} - engines: {node: '>= 12'} - hasBin: true - dev: true + memorystream@0.3.1: {} - /memorystream/0.3.1: - resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} - engines: {node: '>= 0.10.0'} - dev: true + meow@12.1.1: {} - /meow/8.1.2: - resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} - engines: {node: '>=10'} - dependencies: - '@types/minimist': 1.2.2 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.1 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 3.0.3 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.18.1 - yargs-parser: 20.2.9 - dev: true - - /merge-stream/2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true + meow@13.2.0: {} - /merge2/1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true + merge-stream@2.0.0: {} - /micromatch/4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} + merge2@1.4.1: {} + + micromatch@4.0.7: dependencies: - braces: 3.0.2 + braces: 3.0.3 picomatch: 2.3.1 - dev: true - /mime-db/1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: true + mime-db@1.52.0: {} - /mime-types/2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + mime-types@2.1.35: dependencies: mime-db: 1.52.0 - dev: true - - /mimic-fn/2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - dev: true - /mimic-fn/4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - dev: true + mimic-fn@2.1.0: {} - /mimic-response/3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - dev: true + mimic-fn@4.0.0: {} - /mimic-response/4.0.0: - resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true + mimic-response@3.1.0: {} - /min-indent/1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} - dev: true + mimic-response@4.0.0: {} - /minimatch/3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.0.8: dependencies: brace-expansion: 1.1.11 - dev: true - - /minimatch/5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - dependencies: - brace-expansion: 2.0.1 - dev: true - /minimatch/7.4.6: - resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} - engines: {node: '>=10'} + minimatch@3.1.2: dependencies: - brace-expansion: 2.0.1 - dev: true + brace-expansion: 1.1.11 - /minimatch/8.0.4: - resolution: {integrity: sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==} - engines: {node: '>=16 || 14 >=14.17'} + minimatch@5.1.6: dependencies: brace-expansion: 2.0.1 - dev: true - /minimatch/9.0.0: - resolution: {integrity: sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w==} - engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.4: dependencies: brace-expansion: 2.0.1 - dev: true - /minimist-options/4.1.0: - resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} - engines: {node: '>= 6'} - dependencies: - arrify: 1.0.1 - is-plain-obj: 1.1.0 - kind-of: 6.0.3 - dev: true - - /minimist/1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true + minimist@1.2.8: {} - /minipass-collect/1.0.2: - resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} - engines: {node: '>= 8'} + minipass-collect@1.0.2: dependencies: minipass: 3.3.6 - dev: true - /minipass-fetch/2.1.2: - resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + minipass-fetch@2.1.2: dependencies: minipass: 3.3.6 minipass-sized: 1.0.3 minizlib: 2.1.2 optionalDependencies: encoding: 0.1.13 - dev: true - /minipass-fetch/3.0.2: - resolution: {integrity: sha512-/ZpF1CQaWYqjbhfFgKNt3azxztEpc/JUPuMkqOgrnMQqcU8CbE409AUdJYTIWryl3PP5CBaTJZT71N49MXP/YA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + minipass-fetch@3.0.5: dependencies: - minipass: 4.2.8 + minipass: 7.1.2 minipass-sized: 1.0.3 minizlib: 2.1.2 optionalDependencies: encoding: 0.1.13 - dev: true - /minipass-flush/1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} - engines: {node: '>= 8'} + minipass-flush@1.0.5: dependencies: minipass: 3.3.6 - dev: true - /minipass-json-stream/1.0.1: - resolution: {integrity: sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==} + minipass-json-stream@1.0.1: dependencies: jsonparse: 1.3.1 minipass: 3.3.6 - dev: true - /minipass-pipeline/1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} + minipass-pipeline@1.2.4: dependencies: minipass: 3.3.6 - dev: true - /minipass-sized/1.0.3: - resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} - engines: {node: '>=8'} + minipass-sized@1.0.3: dependencies: minipass: 3.3.6 - dev: true - /minipass/3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} + minipass@3.3.6: dependencies: yallist: 4.0.0 - dev: true - /minipass/4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} - dev: true + minipass@5.0.0: {} - /minipass/5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - dev: true + minipass@7.1.2: {} - /minizlib/2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} + minizlib@2.1.2: dependencies: minipass: 3.3.6 yallist: 4.0.0 - dev: true - - /mkdirp/1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: true - /modify-values/1.0.1: - resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} - engines: {node: '>=0.10.0'} - dev: true + mkdirp@1.0.4: {} - /ms/2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true + ms@2.1.2: {} - /ms/2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: true + ms@2.1.3: {} - /natural-compare-lite/1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true + natural-compare-lite@1.4.0: {} - /natural-compare/1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true + natural-compare@1.4.0: {} - /negotiator/0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - dev: true + negotiator@0.6.3: {} - /neo-async/2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - dev: true + neo-async@2.6.2: {} - /nice-try/1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: true + nice-try@1.0.5: {} - /node-gyp/9.3.1: - resolution: {integrity: sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==} - engines: {node: ^12.13 || ^14.13 || >=16} - hasBin: true + node-gyp@9.4.1: dependencies: env-paths: 2.2.1 + exponential-backoff: 3.1.1 glob: 7.2.3 graceful-fs: 4.2.11 make-fetch-happen: 10.2.1 nopt: 6.0.0 npmlog: 6.0.2 rimraf: 3.0.2 - semver: 7.5.0 - tar: 6.1.13 + semver: 7.6.2 + tar: 6.2.1 which: 2.0.2 transitivePeerDependencies: - bluebird - supports-color - dev: true - /node-int64/0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: true + node-int64@0.4.0: {} - /node-releases/2.0.10: - resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} - dev: true + node-releases@2.0.14: {} - /nopt/6.0.0: - resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - hasBin: true + nopt@6.0.0: dependencies: abbrev: 1.1.1 - dev: true - /normalize-package-data/2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 - resolve: 1.22.2 - semver: 5.7.1 + resolve: 1.22.8 + semver: 5.7.2 validate-npm-package-license: 3.0.4 - dev: true - /normalize-package-data/3.0.3: - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} - engines: {node: '>=10'} + normalize-package-data@5.0.0: dependencies: - hosted-git-info: 4.1.0 - is-core-module: 2.12.0 - semver: 7.5.0 + hosted-git-info: 6.1.1 + is-core-module: 2.13.1 + semver: 7.6.2 validate-npm-package-license: 3.0.4 - dev: true - /normalize-package-data/5.0.0: - resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + normalize-package-data@6.0.1: dependencies: - hosted-git-info: 6.1.1 - is-core-module: 2.12.0 - semver: 7.5.0 + hosted-git-info: 7.0.2 + is-core-module: 2.13.1 + semver: 7.6.2 validate-npm-package-license: 3.0.4 - dev: true - /normalize-path/3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true + normalize-path@3.0.0: {} - /normalize-url/8.0.0: - resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} - engines: {node: '>=14.16'} - dev: true + normalize-url@8.0.1: {} - /npm-bundled/3.0.0: - resolution: {integrity: sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-bundled@3.0.1: dependencies: - npm-normalize-package-bin: 3.0.0 - dev: true + npm-normalize-package-bin: 3.0.1 - /npm-check-updates/16.10.8: - resolution: {integrity: sha512-e+p3rUCvaU0iKOvi+/Xiyx+mLe9/aRTu9Zrc7+TR6H2q+uFgmXEwqbXYN9Ngqsta8gdTjpn751UD5MEOogO5cA==} - engines: {node: '>=14.14'} - hasBin: true + npm-check-updates@16.14.20: dependencies: - chalk: 5.2.0 - cli-table3: 0.6.3 + '@types/semver-utils': 1.1.3 + chalk: 5.3.0 + cli-table3: 0.6.5 commander: 10.0.1 fast-memoize: 2.5.2 find-up: 5.0.0 - fp-and-or: 0.1.3 + fp-and-or: 0.1.4 get-stdin: 8.0.0 globby: 11.1.0 hosted-git-info: 5.2.1 - ini: 4.1.0 + ini: 4.1.3 js-yaml: 4.1.0 json-parse-helpfulerror: 1.0.3 jsonlines: 0.1.1 lodash: 4.17.21 - minimatch: 8.0.4 + make-fetch-happen: 11.1.1 + minimatch: 9.0.4 p-map: 4.0.0 - pacote: 15.1.1 + pacote: 15.2.0 parse-github-url: 1.0.2 progress: 2.0.3 prompts-ncu: 3.0.0 - rc-config-loader: 4.1.2 + rc-config-loader: 4.1.3 remote-git-tags: 3.0.0 - rimraf: 4.4.1 - semver: 7.5.0 + rimraf: 5.0.7 + semver: 7.6.2 semver-utils: 1.1.4 source-map-support: 0.5.21 - spawn-please: 2.0.1 - strip-json-comments: 5.0.0 + spawn-please: 2.0.2 + strip-ansi: 7.1.0 + strip-json-comments: 5.0.1 untildify: 4.0.0 update-notifier: 6.0.2 transitivePeerDependencies: - bluebird - supports-color - dev: true - /npm-install-checks/6.1.1: - resolution: {integrity: sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-install-checks@6.3.0: dependencies: - semver: 7.5.0 - dev: true + semver: 7.6.2 - /npm-normalize-package-bin/3.0.0: - resolution: {integrity: sha512-g+DPQSkusnk7HYXr75NtzkIP4+N81i3RPsGFidF3DzHd9MT9wWngmqoeg/fnHFz5MNdtG4w03s+QnhewSLTT2Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: true + npm-normalize-package-bin@3.0.1: {} - /npm-package-arg/10.1.0: - resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-package-arg@10.1.0: dependencies: hosted-git-info: 6.1.1 proc-log: 3.0.0 - semver: 7.5.0 - validate-npm-package-name: 5.0.0 - dev: true + semver: 7.6.2 + validate-npm-package-name: 5.0.1 - /npm-packlist/7.0.4: - resolution: {integrity: sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-packlist@7.0.4: dependencies: - ignore-walk: 6.0.2 - dev: true + ignore-walk: 6.0.5 - /npm-pick-manifest/8.0.1: - resolution: {integrity: sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-pick-manifest@8.0.2: dependencies: - npm-install-checks: 6.1.1 - npm-normalize-package-bin: 3.0.0 + npm-install-checks: 6.3.0 + npm-normalize-package-bin: 3.0.1 npm-package-arg: 10.1.0 - semver: 7.5.0 - dev: true + semver: 7.6.2 - /npm-registry-fetch/14.0.4: - resolution: {integrity: sha512-pMS2DRkwg+M44ct65zrN/Cr9IHK1+n6weuefAo6Er4lc+/8YBCU0Czq04H3ZiSigluh7pb2rMM5JpgcytctB+Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + npm-registry-fetch@14.0.5: dependencies: - make-fetch-happen: 11.1.0 - minipass: 4.2.8 - minipass-fetch: 3.0.2 + make-fetch-happen: 11.1.1 + minipass: 5.0.0 + minipass-fetch: 3.0.5 minipass-json-stream: 1.0.1 minizlib: 2.1.2 npm-package-arg: 10.1.0 proc-log: 3.0.0 transitivePeerDependencies: - - bluebird - supports-color - dev: true - /npm-run-all/4.1.5: - resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} - engines: {node: '>= 4'} - hasBin: true + npm-run-all@4.1.5: dependencies: ansi-styles: 3.2.1 chalk: 2.4.2 @@ -5682,1630 +7919,954 @@ packages: pidtree: 0.3.1 read-pkg: 3.0.0 shell-quote: 1.8.1 - string.prototype.padend: 3.1.4 - dev: true + string.prototype.padend: 3.1.6 - /npm-run-path/4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 - dev: true - /npm-run-path/5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + npm-run-path@5.3.0: dependencies: path-key: 4.0.0 - dev: true - /npmlog/6.0.2: - resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + npmlog@6.0.2: dependencies: are-we-there-yet: 3.0.1 console-control-strings: 1.1.0 gauge: 4.0.4 set-blocking: 2.0.0 - dev: true - /nwsapi/2.2.4: - resolution: {integrity: sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g==} - dev: true + nwsapi@2.2.10: {} - /object-assign/4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: true + object-assign@4.1.1: {} - /object-inspect/1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} - dev: true + object-inspect@1.13.1: {} - /object-keys/1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true + object-keys@1.1.1: {} - /object.assign/4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} - engines: {node: '>= 0.4'} + object.assign@4.1.5: dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 + call-bind: 1.0.7 + define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 - dev: true - /once/1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + once@1.4.0: dependencies: wrappy: 1.0.2 - dev: true - /onetime/5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + onetime@5.1.2: dependencies: mimic-fn: 2.1.0 - dev: true - /onetime/6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} + onetime@6.0.0: dependencies: mimic-fn: 4.0.0 - dev: true - /optionator/0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.3.0 - prelude-ls: 1.1.2 - type-check: 0.3.2 - word-wrap: 1.2.3 - dev: true - - /optionator/0.9.1: - resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} - engines: {node: '>= 0.8.0'} + optionator@0.9.4: dependencies: deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 prelude-ls: 1.2.1 type-check: 0.4.0 - word-wrap: 1.2.3 - dev: true - - /p-cancelable/3.0.0: - resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} - engines: {node: '>=12.20'} - dev: true + word-wrap: 1.2.5 - /p-limit/1.3.0: - resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} - engines: {node: '>=4'} - dependencies: - p-try: 1.0.0 - dev: true + p-cancelable@3.0.0: {} - /p-limit/2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + p-limit@2.3.0: dependencies: p-try: 2.2.0 - dev: true - /p-limit/3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - dev: true - /p-locate/2.0.0: - resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} - engines: {node: '>=4'} + p-limit@4.0.0: dependencies: - p-limit: 1.3.0 - dev: true + yocto-queue: 1.0.0 - /p-locate/4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + p-locate@4.1.0: dependencies: p-limit: 2.3.0 - dev: true - /p-locate/5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + p-locate@5.0.0: dependencies: p-limit: 3.1.0 - dev: true - /p-map/4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} + p-locate@6.0.0: dependencies: - aggregate-error: 3.1.0 - dev: true + p-limit: 4.0.0 - /p-try/1.0.0: - resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} - engines: {node: '>=4'} - dev: true + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 - /p-try/2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true + p-try@2.2.0: {} - /package-json/8.1.0: - resolution: {integrity: sha512-hySwcV8RAWeAfPsXb9/HGSPn8lwDnv6fabH+obUZKX169QknRkRhPxd1yMubpKDskLFATkl3jHpNtVtDPFA0Wg==} - engines: {node: '>=14.16'} + package-json@8.1.1: dependencies: - got: 12.6.0 + got: 12.6.1 registry-auth-token: 5.0.2 registry-url: 6.0.1 - semver: 7.5.0 - dev: true + semver: 7.6.2 - /pacote/15.1.1: - resolution: {integrity: sha512-eeqEe77QrA6auZxNHIp+1TzHQ0HBKf5V6c8zcaYZ134EJe1lCi+fjXATkNiEEfbG+e50nu02GLvUtmZcGOYabQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true + pacote@15.2.0: dependencies: - '@npmcli/git': 4.0.4 - '@npmcli/installed-package-contents': 2.0.2 + '@npmcli/git': 4.1.0 + '@npmcli/installed-package-contents': 2.1.0 '@npmcli/promise-spawn': 6.0.2 - '@npmcli/run-script': 6.0.0 - cacache: 17.0.5 - fs-minipass: 3.0.1 - minipass: 4.2.8 + '@npmcli/run-script': 6.0.2 + cacache: 17.1.4 + fs-minipass: 3.0.3 + minipass: 5.0.0 npm-package-arg: 10.1.0 npm-packlist: 7.0.4 - npm-pick-manifest: 8.0.1 - npm-registry-fetch: 14.0.4 + npm-pick-manifest: 8.0.2 + npm-registry-fetch: 14.0.5 proc-log: 3.0.0 promise-retry: 2.0.1 - read-package-json: 6.0.1 + read-package-json: 6.0.4 read-package-json-fast: 3.0.2 - sigstore: 1.3.0 - ssri: 10.0.3 - tar: 6.1.13 + sigstore: 1.9.0 + ssri: 10.0.6 + tar: 6.2.1 transitivePeerDependencies: - bluebird - supports-color - dev: true - - /parent-module/1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + + parent-module@1.0.1: dependencies: callsites: 3.1.0 - dev: true - /parse-github-url/1.0.2: - resolution: {integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==} - engines: {node: '>=0.10.0'} - hasBin: true - dev: true + parse-github-url@1.0.2: {} - /parse-json/4.0.0: - resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} - engines: {node: '>=4'} + parse-json@4.0.0: dependencies: error-ex: 1.3.2 json-parse-better-errors: 1.0.2 - dev: true - /parse-json/5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.24.7 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - dev: true - /parse5/7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + parse-json@8.1.0: + dependencies: + '@babel/code-frame': 7.24.7 + index-to-position: 0.1.2 + type-fest: 4.20.1 + + parse-ms@4.0.0: {} + + parse5@7.1.2: dependencies: entities: 4.5.0 - dev: true - /path-exists/3.0.0: - resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} - engines: {node: '>=4'} - dev: true + path-exists@4.0.0: {} - /path-exists/4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true + path-exists@5.0.0: {} - /path-is-absolute/1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true + path-is-absolute@1.0.1: {} - /path-key/2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - dev: true + path-key@2.0.1: {} - /path-key/3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true + path-key@3.1.1: {} - /path-key/4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - dev: true + path-key@4.0.0: {} - /path-parse/1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true + path-parse@1.0.7: {} - /path-scurry/1.7.0: - resolution: {integrity: sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==} - engines: {node: '>=16 || 14 >=14.17'} + path-scurry@1.11.1: dependencies: - lru-cache: 9.1.0 - minipass: 5.0.0 - dev: true + lru-cache: 10.2.2 + minipass: 7.1.2 - /path-type/3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} + path-type@3.0.0: dependencies: pify: 3.0.0 - dev: true - /path-type/4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true + path-type@4.0.0: {} - /picocolors/1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true + picocolors@1.0.1: {} - /picomatch/2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true + picomatch@2.3.1: {} - /pidtree/0.3.1: - resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} - engines: {node: '>=0.10'} - hasBin: true - dev: true + pidtree@0.3.1: {} - /pidtree/0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - dev: true + pidtree@0.6.0: {} - /pify/2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - dev: true + pify@2.3.0: {} - /pify/3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - dev: true + pify@3.0.0: {} - /pinkie-promise/2.0.1: - resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} - engines: {node: '>=0.10.0'} + pinkie-promise@2.0.1: dependencies: pinkie: 2.0.4 - dev: true - /pinkie/2.0.4: - resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} - engines: {node: '>=0.10.0'} - dev: true + pinkie@2.0.4: {} - /pirates/4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} - engines: {node: '>= 6'} - dev: true + pirates@4.0.6: {} - /pkg-dir/4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 - dev: true - /prelude-ls/1.1.2: - resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} - engines: {node: '>= 0.8.0'} - dev: true + possible-typed-array-names@1.0.0: {} - /prelude-ls/1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true + prelude-ls@1.2.1: {} - /prettier-linter-helpers/1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} + prettier-linter-helpers@1.0.0: dependencies: - fast-diff: 1.2.0 - dev: true + fast-diff: 1.3.0 - /prettier/2.8.7: - resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true + prettier@3.3.2: {} - /pretty-format/29.5.0: - resolution: {integrity: sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@29.7.0: dependencies: - '@jest/schemas': 29.4.3 + '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 - react-is: 18.2.0 - dev: true + react-is: 18.3.1 - /proc-log/3.0.0: - resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dev: true + pretty-ms@9.0.0: + dependencies: + parse-ms: 4.0.0 - /process-nextick-args/2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true + proc-log@3.0.0: {} - /progress/2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - dev: true + progress@2.0.3: {} - /promise-inflight/1.0.1: - resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} - peerDependencies: - bluebird: '*' - peerDependenciesMeta: - bluebird: - optional: true - dev: true + promise-inflight@1.0.1: {} - /promise-retry/2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} + promise-retry@2.0.1: dependencies: err-code: 2.0.3 retry: 0.12.0 - dev: true - /prompts-ncu/3.0.0: - resolution: {integrity: sha512-qyz9UxZ5MlPKWVhWrCmSZ1ahm2GVYdjLb8og2sg0IPth1KRuhcggHGuijz0e41dkx35p1t1q3GRISGH7QGALFA==} - engines: {node: '>= 14'} + prompts-ncu@3.0.0: dependencies: kleur: 4.1.5 sisteransi: 1.0.5 - dev: true - /prompts/2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} + prompts@2.4.2: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 - dev: true - /proto-list/1.2.4: - resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - dev: true + proto-list@1.2.4: {} - /psl/1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: true + psl@1.9.0: {} - /punycode/2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} - engines: {node: '>=6'} - dev: true + punycode.js@2.3.1: {} - /pupa/3.1.0: - resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==} - engines: {node: '>=12.20'} + punycode@2.3.1: {} + + pupa@3.1.0: dependencies: escape-goat: 4.0.0 - dev: true - /pure-rand/6.0.1: - resolution: {integrity: sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==} - dev: true + pure-rand@6.1.0: {} - /q/1.5.1: - resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} - engines: {node: '>=0.6.0', teleport: '>=0.2.0'} - dev: true + querystringify@2.2.0: {} - /querystringify/2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} - dev: true - - /queue-microtask/1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - - /quick-lru/4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} - engines: {node: '>=8'} - dev: true + queue-microtask@1.2.3: {} - /quick-lru/5.1.1: - resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} - engines: {node: '>=10'} - dev: true + quick-lru@5.1.1: {} - /randombytes/2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 - dev: true - /rc-config-loader/4.1.2: - resolution: {integrity: sha512-qKTnVWFl9OQYKATPzdfaZIbTxcHziQl92zYSxYC6umhOqyAsoj8H8Gq/+aFjAso68sBdjTz3A7omqeAkkF1MWg==} + rc-config-loader@4.1.3: dependencies: - debug: 4.3.4 + debug: 4.3.5 js-yaml: 4.1.0 json5: 2.2.3 require-from-string: 2.0.2 transitivePeerDependencies: - supports-color - dev: true - /rc/1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true + rc@1.2.8: dependencies: deep-extend: 0.6.0 ini: 1.3.8 minimist: 1.2.8 strip-json-comments: 2.0.1 - dev: true - /react-is/18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true + react-is@18.3.1: {} - /read-package-json-fast/3.0.2: - resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + read-package-json-fast@3.0.2: dependencies: - json-parse-even-better-errors: 3.0.0 - npm-normalize-package-bin: 3.0.0 - dev: true + json-parse-even-better-errors: 3.0.2 + npm-normalize-package-bin: 3.0.1 - /read-package-json/6.0.1: - resolution: {integrity: sha512-AaHqXxfAVa+fNL07x8iAghfKOds/XXsu7zoouIVsbm7PEbQ3nMWXlvjcbrNLjElnUHWQtAo4QEa0RXuvD4XlpA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + read-package-json@6.0.4: dependencies: - glob: 9.3.5 - json-parse-even-better-errors: 3.0.0 + glob: 10.4.1 + json-parse-even-better-errors: 3.0.2 normalize-package-data: 5.0.0 - npm-normalize-package-bin: 3.0.0 - dev: true - - /read-pkg-up/3.0.0: - resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==} - engines: {node: '>=4'} - dependencies: - find-up: 2.1.0 - read-pkg: 3.0.0 - dev: true + npm-normalize-package-bin: 3.0.1 - /read-pkg-up/7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} - engines: {node: '>=8'} + read-package-up@11.0.0: dependencies: - find-up: 4.1.0 - read-pkg: 5.2.0 - type-fest: 0.8.1 - dev: true + find-up-simple: 1.0.0 + read-pkg: 9.0.1 + type-fest: 4.20.1 - /read-pkg/3.0.0: - resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} - engines: {node: '>=4'} + read-pkg@3.0.0: dependencies: load-json-file: 4.0.0 normalize-package-data: 2.5.0 path-type: 3.0.0 - dev: true - - /read-pkg/5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} - engines: {node: '>=8'} - dependencies: - '@types/normalize-package-data': 2.4.1 - normalize-package-data: 2.5.0 - parse-json: 5.2.0 - type-fest: 0.6.0 - dev: true - /readable-stream/2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + read-pkg@9.0.1: dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - dev: true + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 6.0.1 + parse-json: 8.1.0 + type-fest: 4.20.1 + unicorn-magic: 0.1.0 - /readable-stream/3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} + readable-stream@3.6.2: dependencies: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - dev: true - - /redent/3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} - dependencies: - indent-string: 4.0.0 - strip-indent: 3.0.0 - dev: true - /regexp.prototype.flags/1.5.0: - resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} - engines: {node: '>= 0.4'} + regexp.prototype.flags@1.5.2: dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - functions-have-names: 1.2.3 - dev: true + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 - /registry-auth-token/5.0.2: - resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} - engines: {node: '>=14'} + registry-auth-token@5.0.2: dependencies: - '@pnpm/npm-conf': 2.1.1 - dev: true + '@pnpm/npm-conf': 2.2.2 - /registry-url/6.0.1: - resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} - engines: {node: '>=12'} + registry-url@6.0.1: dependencies: rc: 1.2.8 - dev: true - /remote-git-tags/3.0.0: - resolution: {integrity: sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==} - engines: {node: '>=8'} - dev: true + remote-git-tags@3.0.0: {} - /require-directory/2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true + require-directory@2.1.1: {} - /require-from-string/2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - dev: true + require-from-string@2.0.2: {} - /requires-port/1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - dev: true + requires-port@1.0.0: {} - /resolve-alpn/1.2.1: - resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} - dev: true + resolve-alpn@1.2.1: {} - /resolve-cwd/3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 - dev: true - - /resolve-from/4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true - /resolve-from/5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true + resolve-from@4.0.0: {} - /resolve-global/1.0.0: - resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==} - engines: {node: '>=8'} - dependencies: - global-dirs: 0.1.1 - dev: true + resolve-from@5.0.0: {} - /resolve.exports/2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - dev: true + resolve-pkg-maps@1.0.0: {} - /resolve/1.19.0: - resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} - dependencies: - is-core-module: 2.12.0 - path-parse: 1.0.7 - dev: true + resolve.exports@2.0.2: {} - /resolve/1.22.2: - resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} - hasBin: true + resolve@1.22.8: dependencies: - is-core-module: 2.12.0 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true - /responselike/3.0.0: - resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} - engines: {node: '>=14.16'} + responselike@3.0.0: dependencies: lowercase-keys: 3.0.0 - dev: true - /restore-cursor/3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} + restore-cursor@4.0.0: dependencies: onetime: 5.1.2 signal-exit: 3.0.7 - dev: true - /retry/0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - dev: true + retry@0.12.0: {} - /reusify/1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true + reusify@1.0.4: {} - /rfdc/1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - dev: true + rfdc@1.4.1: {} - /rimraf/3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true + rimraf@3.0.2: dependencies: glob: 7.2.3 - dev: true - /rimraf/4.4.1: - resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} - engines: {node: '>=14'} - hasBin: true + rimraf@5.0.7: dependencies: - glob: 9.3.5 - dev: true + glob: 10.4.1 - /rollup-plugin-terser/7.0.2_rollup@3.20.6: - resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} - deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser - peerDependencies: - rollup: ^2.0.0 + rollup-plugin-terser@7.0.2(rollup@4.18.0): dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.24.7 jest-worker: 26.6.2 - rollup: 3.20.6 + rollup: 4.18.0 serialize-javascript: 4.0.0 - terser: 5.17.1 - dev: true + terser: 5.31.1 - /rollup-plugin-typescript2/0.34.1_7z4wb4mnpapsgobacn7mivmt6i: - resolution: {integrity: sha512-P4cHLtGikESmqi1CA+tdMDUv8WbQV48mzPYt77TSTOPJpERyZ9TXdDgjSDix8Fkqce6soYz3+fa4lrC93IEkcw==} - peerDependencies: - rollup: '>=1.26.3' - typescript: '>=2.4.0' + rollup-plugin-typescript2@0.36.0(rollup@4.18.0)(typescript@5.4.5): dependencies: '@rollup/pluginutils': 4.2.1 find-cache-dir: 3.3.2 fs-extra: 10.1.0 - rollup: 3.20.6 - semver: 7.5.0 - tslib: 2.5.0 - typescript: 5.0.4 - dev: true - - /rollup/3.20.6: - resolution: {integrity: sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} - hasBin: true - optionalDependencies: - fsevents: 2.3.2 - dev: true + rollup: 4.18.0 + semver: 7.6.2 + tslib: 2.6.3 + typescript: 5.4.5 - /run-parallel/1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rollup@4.18.0: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.18.0 + '@rollup/rollup-android-arm64': 4.18.0 + '@rollup/rollup-darwin-arm64': 4.18.0 + '@rollup/rollup-darwin-x64': 4.18.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.0 + '@rollup/rollup-linux-arm-musleabihf': 4.18.0 + '@rollup/rollup-linux-arm64-gnu': 4.18.0 + '@rollup/rollup-linux-arm64-musl': 4.18.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0 + '@rollup/rollup-linux-riscv64-gnu': 4.18.0 + '@rollup/rollup-linux-s390x-gnu': 4.18.0 + '@rollup/rollup-linux-x64-gnu': 4.18.0 + '@rollup/rollup-linux-x64-musl': 4.18.0 + '@rollup/rollup-win32-arm64-msvc': 4.18.0 + '@rollup/rollup-win32-ia32-msvc': 4.18.0 + '@rollup/rollup-win32-x64-msvc': 4.18.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - dev: true - /rxjs/7.8.0: - resolution: {integrity: sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==} + safe-array-concat@1.1.2: dependencies: - tslib: 2.5.0 - dev: true - - /safe-buffer/5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 - /safe-buffer/5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true + safe-buffer@5.2.1: {} - /safe-regex-test/1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + safe-regex-test@1.0.3: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 + call-bind: 1.0.7 + es-errors: 1.3.0 is-regex: 1.1.4 - dev: true - /safer-buffer/2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true + safer-buffer@2.1.2: {} - /saxes/6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} + saxes@6.0.0: dependencies: xmlchars: 2.2.0 - dev: true - /semver-diff/4.0.0: - resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} - engines: {node: '>=12'} + semver-diff@4.0.0: dependencies: - semver: 7.5.0 - dev: true + semver: 7.6.2 - /semver-utils/1.1.4: - resolution: {integrity: sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==} - dev: true + semver-utils@1.1.4: {} - /semver/5.7.1: - resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} - hasBin: true - dev: true + semver@5.7.2: {} - /semver/6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - dev: true + semver@6.3.1: {} - /semver/7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} - engines: {node: '>=10'} - hasBin: true + semver@7.5.4: dependencies: lru-cache: 6.0.0 - dev: true - /semver/7.5.0: - resolution: {integrity: sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true + semver@7.6.2: {} - /serialize-javascript/4.0.0: - resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + serialize-javascript@4.0.0: dependencies: randombytes: 2.1.0 - dev: true - /set-blocking/2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - dev: true + set-blocking@2.0.0: {} - /shebang-command/1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 - dev: true - /shebang-command/2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - dev: true - /shebang-regex/1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - dev: true + shebang-regex@1.0.0: {} - /shebang-regex/3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true + shebang-regex@3.0.0: {} - /shell-quote/1.8.1: - resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} - dev: true + shell-quote@1.8.1: {} - /shiki/0.14.1: - resolution: {integrity: sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw==} + shiki@1.9.1: dependencies: - ansi-sequence-parser: 1.1.0 - jsonc-parser: 3.2.0 - vscode-oniguruma: 1.7.0 - vscode-textmate: 8.0.0 - dev: true + '@shikijs/core': 1.9.1 - /side-channel/1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + side-channel@1.0.6: dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - object-inspect: 1.12.3 - dev: true + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 - /signal-exit/3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true + signal-exit@3.0.7: {} - /sigstore/1.3.0: - resolution: {integrity: sha512-dhdv+jOAi1RgLHw13lxumk3rlgZtumUz9QrCNPTx9MazUnUV3BfAb74oYAMPQQ7uaeogB5vTosbz3POzKbEHUQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true + signal-exit@4.1.0: {} + + sigstore@1.9.0: dependencies: - '@sigstore/protobuf-specs': 0.1.0 - make-fetch-happen: 11.1.0 - tuf-js: 1.1.4 + '@sigstore/bundle': 1.1.0 + '@sigstore/protobuf-specs': 0.2.1 + '@sigstore/sign': 1.0.0 + '@sigstore/tuf': 1.0.3 + make-fetch-happen: 11.1.1 transitivePeerDependencies: - - bluebird - supports-color - dev: true - /sisteransi/1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true - - /slash/3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true + sisteransi@1.0.5: {} - /slice-ansi/3.0.0: - resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: true + slash@3.0.0: {} - /slice-ansi/4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} - engines: {node: '>=10'} + slice-ansi@5.0.0: dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: true + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 - /slice-ansi/5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} + slice-ansi@7.1.0: dependencies: ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - dev: true + is-fullwidth-code-point: 5.0.0 - /smart-buffer/4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - dev: true + smart-buffer@4.2.0: {} - /socks-proxy-agent/7.0.0: - resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} - engines: {node: '>= 10'} + socks-proxy-agent@7.0.0: dependencies: agent-base: 6.0.2 - debug: 4.3.4 - socks: 2.7.1 + debug: 4.3.5 + socks: 2.8.3 transitivePeerDependencies: - supports-color - dev: true - /socks/2.7.1: - resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} - engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + socks@2.8.3: dependencies: - ip: 2.0.0 + ip-address: 9.0.5 smart-buffer: 4.2.0 - dev: true - /source-map-support/0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - dev: true - /source-map-support/0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - dev: true - /source-map/0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true + source-map@0.6.1: {} - /spawn-please/2.0.1: - resolution: {integrity: sha512-W+cFbZR2q2mMTfjz5ZGvhBAiX+e/zczFCNlbS9mxiSdYswBXwUuBUT+a0urH+xZZa8f/bs0mXHyZsZHR9hKogA==} - engines: {node: '>=14'} + spawn-please@2.0.2: dependencies: cross-spawn: 7.0.3 - dev: true - /spdx-correct/3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + spdx-correct@3.2.0: dependencies: spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.13 - dev: true + spdx-license-ids: 3.0.18 - /spdx-exceptions/2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - dev: true + spdx-exceptions@2.5.0: {} - /spdx-expression-parse/3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + spdx-expression-parse@3.0.1: dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.13 - dev: true + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.18 - /spdx-license-ids/3.0.13: - resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} - dev: true + spdx-license-ids@3.0.18: {} - /split/1.0.1: - resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} - dependencies: - through: 2.3.8 - dev: true + split2@4.2.0: {} - /split2/3.2.2: - resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} - dependencies: - readable-stream: 3.6.2 - dev: true + sprintf-js@1.0.3: {} - /sprintf-js/1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true + sprintf-js@1.1.3: {} - /ssri/10.0.3: - resolution: {integrity: sha512-lJtX/BFPI/VEtxZmLfeh7pzisIs6micwZ3eruD3+ds9aPsXKlYpwDS2Q7omD6WC42WO9+bnUSzlMmfv8uK8meg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ssri@10.0.6: dependencies: - minipass: 4.2.8 - dev: true + minipass: 7.1.2 - /ssri/9.0.1: - resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + ssri@9.0.1: dependencies: minipass: 3.3.6 - dev: true - /stack-utils/2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 - dev: true - /string-argv/0.3.1: - resolution: {integrity: sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==} - engines: {node: '>=0.6.19'} - dev: true + string-argv@0.3.2: {} - /string-length/4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} + string-length@4.0.2: dependencies: char-regex: 1.0.2 strip-ansi: 6.0.1 - dev: true - /string-width/4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - dev: true - /string-width/5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} + string-width@5.1.2: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.0.1 - dev: true + strip-ansi: 7.1.0 - /string.prototype.padend/3.1.4: - resolution: {integrity: sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw==} - engines: {node: '>= 0.4'} + string-width@7.1.0: dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 - /string.prototype.trim/1.2.7: - resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} - engines: {node: '>= 0.4'} + string.prototype.padend@3.1.6: dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 - /string.prototype.trimend/1.0.6: - resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + string.prototype.trim@1.2.9: dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 - /string.prototype.trimstart/1.0.6: - resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + string.prototype.trimend@1.0.8: dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 - /string_decoder/1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string.prototype.trimstart@1.0.8: dependencies: - safe-buffer: 5.1.2 - dev: true + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 - /string_decoder/1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 - dev: true - /strip-ansi/6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - dev: true - /strip-ansi/7.0.1: - resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} - engines: {node: '>=12'} + strip-ansi@7.1.0: dependencies: ansi-regex: 6.0.1 - dev: true - /strip-bom/3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true + strip-bom@3.0.0: {} - /strip-bom/4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true + strip-bom@4.0.0: {} - /strip-final-newline/2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true + strip-final-newline@2.0.0: {} - /strip-final-newline/3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - dev: true + strip-final-newline@3.0.0: {} - /strip-indent/3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} - dependencies: - min-indent: 1.0.1 - dev: true + strip-final-newline@4.0.0: {} - /strip-json-comments/2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - dev: true + strip-json-comments@2.0.1: {} - /strip-json-comments/3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true + strip-json-comments@3.1.1: {} - /strip-json-comments/5.0.0: - resolution: {integrity: sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==} - engines: {node: '>=14.16'} - dev: true + strip-json-comments@5.0.1: {} - /strip-outer/1.0.1: - resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} - engines: {node: '>=0.10.0'} + strip-outer@1.0.1: dependencies: escape-string-regexp: 1.0.5 - dev: true - /supports-color/5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 - dev: true - /supports-color/7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - dev: true - /supports-color/8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + supports-color@8.1.1: dependencies: has-flag: 4.0.0 - dev: true - /supports-preserve-symlinks-flag/1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true + supports-preserve-symlinks-flag@1.0.0: {} - /symbol-tree/3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - dev: true + symbol-tree@3.2.4: {} - /tar/6.1.13: - resolution: {integrity: sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==} - engines: {node: '>=10'} + synckit@0.8.8: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.6.3 + + tar@6.2.1: dependencies: chownr: 2.0.0 fs-minipass: 2.1.0 - minipass: 4.2.8 + minipass: 5.0.0 minizlib: 2.1.2 mkdirp: 1.0.4 yallist: 4.0.0 - dev: true - /temp-dir/2.0.0: - resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} - engines: {node: '>=8'} - dev: true + temp-dir@3.0.0: {} - /tempfile/3.0.0: - resolution: {integrity: sha512-uNFCg478XovRi85iD42egu+eSFUmmka750Jy7L5tfHI5hQKKtbPnxaSaXAbBqCDYrw3wx4tXjKwci4/QmsZJxw==} - engines: {node: '>=8'} + tempfile@5.0.0: dependencies: - temp-dir: 2.0.0 - uuid: 3.4.0 - dev: true + temp-dir: 3.0.0 - /terser/5.17.1: - resolution: {integrity: sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw==} - engines: {node: '>=10'} - hasBin: true + terser@5.31.1: dependencies: - '@jridgewell/source-map': 0.3.3 - acorn: 8.8.2 + '@jridgewell/source-map': 0.3.6 + acorn: 8.12.0 commander: 2.20.3 source-map-support: 0.5.21 - dev: true - /test-exclude/6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 minimatch: 3.1.2 - dev: true - - /text-extensions/1.9.0: - resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} - engines: {node: '>=0.10'} - dev: true - /text-table/0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true - - /through/2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true + text-extensions@2.4.0: {} - /through2/2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - dependencies: - readable-stream: 2.3.8 - xtend: 4.0.2 - dev: true + text-table@0.2.0: {} - /through2/4.0.2: - resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} - dependencies: - readable-stream: 3.6.2 - dev: true + through@2.3.8: {} - /tmpl/1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: true + tmpl@1.0.5: {} - /to-fast-properties/2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true + to-fast-properties@2.0.0: {} - /to-regex-range/5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - dev: true - /tough-cookie/4.1.2: - resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==} - engines: {node: '>=6'} + tough-cookie@4.1.4: dependencies: psl: 1.9.0 - punycode: 2.3.0 + punycode: 2.3.1 universalify: 0.2.0 url-parse: 1.5.10 - dev: true - /tr46/3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} + tr46@3.0.0: dependencies: - punycode: 2.3.0 - dev: true - - /trim-newlines/3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} - engines: {node: '>=8'} - dev: true + punycode: 2.3.1 - /trim-repeated/1.0.0: - resolution: {integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==} - engines: {node: '>=0.10.0'} + trim-repeated@1.0.0: dependencies: escape-string-regexp: 1.0.5 - dev: true - /ts-jest/29.1.0_ein22xsozyc5ohjtbndctplfiq: - resolution: {integrity: sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/types': ^29.0.0 - babel-jest: ^29.0.0 - esbuild: '*' - jest: ^29.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true + ts-api-utils@1.3.0(typescript@5.4.5): + dependencies: + typescript: 5.4.5 + + ts-jest@29.1.5(@babel/core@7.24.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.7))(jest@29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)))(typescript@5.4.5): dependencies: - '@babel/core': 7.21.4 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.5.0_@types+node@18.15.11 - jest-util: 29.5.0 + jest: 29.7.0(@types/node@20.14.4)(ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5)) + jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.5.0 - typescript: 5.0.4 + semver: 7.6.2 + typescript: 5.4.5 yargs-parser: 21.1.1 - dev: true + optionalDependencies: + '@babel/core': 7.24.7 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.24.7) - /ts-node/10.9.1_bhanhq442dy43ncydsavgi4jfi: - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} - hasBin: true - 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 + ts-node@10.9.2(@types/node@20.14.4)(typescript@5.4.5): dependencies: '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 + '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.3 - '@types/node': 18.15.11 - acorn: 8.8.2 - acorn-walk: 8.2.0 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.14.4 + acorn: 8.12.0 + acorn-walk: 8.3.3 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.0.4 + typescript: 5.4.5 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - dev: true - - /tslib/1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true - - /tslib/2.5.0: - resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} - dev: true + optional: true - /tsutils/3.21.0_typescript@5.0.4: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 5.0.4 - dev: true + tslib@2.6.3: {} - /tsx/3.12.6: - resolution: {integrity: sha512-q93WgS3lBdHlPgS0h1i+87Pt6n9K/qULIMNYZo07nSeu2z5QE2CellcAZfofVXBo2tQg9av2ZcRMQ2S2i5oadQ==} - hasBin: true + tsx@4.15.6: dependencies: - '@esbuild-kit/cjs-loader': 2.4.2 - '@esbuild-kit/core-utils': 3.1.0 - '@esbuild-kit/esm-loader': 2.5.5 + esbuild: 0.21.5 + get-tsconfig: 4.7.5 optionalDependencies: - fsevents: 2.3.2 - dev: true + fsevents: 2.3.3 - /tuf-js/1.1.4: - resolution: {integrity: sha512-Lw2JRM3HTYhEtQJM2Th3aNCPbnXirtWMl065BawwmM2pX6XStH/ZO9e8T2hh0zk/HUa+1i6j+Lv6eDitKTau6A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + tuf-js@1.1.7: dependencies: - '@tufjs/models': 1.0.3 - make-fetch-happen: 11.1.0 + '@tufjs/models': 1.0.4 + debug: 4.3.5 + make-fetch-happen: 11.1.1 transitivePeerDependencies: - - bluebird - supports-color - dev: true - - /type-check/0.3.2: - resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - dev: true - /type-check/0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - dev: true - /type-detect/4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - dev: true + type-detect@4.0.8: {} - /type-fest/0.18.1: - resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} - engines: {node: '>=10'} - dev: true + type-fest@0.21.3: {} - /type-fest/0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true + type-fest@1.4.0: {} - /type-fest/0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: true + type-fest@2.19.0: {} - /type-fest/0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} - dev: true + type-fest@4.20.1: {} - /type-fest/0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - dev: true + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 - /type-fest/1.4.0: - resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} - engines: {node: '>=10'} - dev: true + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 - /type-fest/2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - dev: true + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 - /typed-array-length/1.0.4: - resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + typed-array-length@1.0.6: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 for-each: 0.3.3 - is-typed-array: 1.1.10 - dev: true + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 - /typedarray-to-buffer/3.1.5: - resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + typedarray-to-buffer@3.1.5: dependencies: is-typedarray: 1.0.0 - dev: true - /typedoc/0.24.4_typescript@5.0.4: - resolution: {integrity: sha512-vQuliyGhJEGeKzzCFHbkS3m0gHoIL6cfr0fHf6eX658iGELtq2J9mWe0b+X5McEYgFoMuHFt5Py3Zug6Sxjn/Q==} - engines: {node: '>= 14.14'} - hasBin: true - peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x + typedoc@0.26.2(typescript@5.4.5): dependencies: lunr: 2.3.9 - marked: 4.3.0 - minimatch: 9.0.0 - shiki: 0.14.1 - typescript: 5.0.4 - dev: true - - /typescript/4.8.4: - resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true + markdown-it: 14.1.0 + minimatch: 9.0.4 + shiki: 1.9.1 + typescript: 5.4.5 + yaml: 2.4.5 + + typescript-eslint@7.13.1(eslint@9.5.0)(typescript@5.4.5): + dependencies: + '@typescript-eslint/eslint-plugin': 7.13.1(@typescript-eslint/parser@7.13.1(eslint@9.5.0)(typescript@5.4.5))(eslint@9.5.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.13.1(eslint@9.5.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.13.1(eslint@9.5.0)(typescript@5.4.5) + eslint: 9.5.0 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color - /typescript/5.0.4: - resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} - engines: {node: '>=12.20'} - hasBin: true - dev: true + typescript@5.4.2: {} - /uglify-js/3.17.4: - resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} - engines: {node: '>=0.8.0'} - hasBin: true - requiresBuild: true - dev: true + typescript@5.4.5: {} + + uc.micro@2.1.0: {} + + uglify-js@3.18.0: optional: true - /unbox-primitive/1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + unbox-primitive@1.0.2: dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - dev: true - /unique-filename/2.0.1: - resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + undici-types@5.26.5: {} + + unicorn-magic@0.1.0: {} + + unique-filename@2.0.1: dependencies: unique-slug: 3.0.0 - dev: true - /unique-filename/3.0.0: - resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + unique-filename@3.0.0: dependencies: unique-slug: 4.0.0 - dev: true - /unique-slug/3.0.0: - resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + unique-slug@3.0.0: dependencies: imurmurhash: 0.1.4 - dev: true - /unique-slug/4.0.0: - resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + unique-slug@4.0.0: dependencies: imurmurhash: 0.1.4 - dev: true - /unique-string/3.0.0: - resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} - engines: {node: '>=12'} + unique-string@3.0.0: dependencies: crypto-random-string: 4.0.0 - dev: true - /universalify/0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - dev: true + universalify@0.1.2: {} - /universalify/0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - dev: true + universalify@0.2.0: {} - /universalify/2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} - dev: true + universalify@2.0.1: {} - /untildify/4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - dev: true + untildify@4.0.0: {} - /update-browserslist-db/1.0.11_browserslist@4.21.5: - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' + update-browserslist-db@1.0.16(browserslist@4.23.1): dependencies: - browserslist: 4.21.5 - escalade: 3.1.1 - picocolors: 1.0.0 - dev: true + browserslist: 4.23.1 + escalade: 3.1.2 + picocolors: 1.0.1 - /update-notifier/6.0.2: - resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} - engines: {node: '>=14.16'} + update-notifier@6.0.2: dependencies: - boxen: 7.0.2 - chalk: 5.2.0 + boxen: 7.1.1 + chalk: 5.3.0 configstore: 6.0.0 has-yarn: 3.0.0 import-lazy: 4.0.0 @@ -7315,331 +8876,163 @@ packages: is-yarn-global: 0.4.1 latest-version: 7.0.0 pupa: 3.1.0 - semver: 7.5.0 + semver: 7.6.2 semver-diff: 4.0.0 xdg-basedir: 5.1.0 - dev: true - /uri-js/4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + uri-js@4.4.1: dependencies: - punycode: 2.3.0 - dev: true + punycode: 2.3.1 - /url-parse/1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + url-parse@1.5.10: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 - dev: true - /util-deprecate/1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true - - /uuid/3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - dev: true + util-deprecate@1.0.2: {} - /v8-compile-cache-lib/3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true + v8-compile-cache-lib@3.0.1: + optional: true - /v8-to-istanbul/9.1.0: - resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} - engines: {node: '>=10.12.0'} + v8-to-istanbul@9.2.0: dependencies: - '@jridgewell/trace-mapping': 0.3.18 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 - dev: true + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 - /validate-npm-package-license/3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - dev: true - /validate-npm-package-name/5.0.0: - resolution: {integrity: sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - dependencies: - builtins: 5.0.1 - dev: true - - /validator/13.9.0: - resolution: {integrity: sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==} - engines: {node: '>= 0.10'} - dev: true - - /vscode-oniguruma/1.7.0: - resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} - dev: true + validate-npm-package-name@5.0.1: {} - /vscode-textmate/8.0.0: - resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} - dev: true - - /w3c-xmlserializer/4.0.0: - resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} - engines: {node: '>=14'} + w3c-xmlserializer@4.0.0: dependencies: xml-name-validator: 4.0.0 - dev: true - /walker/1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + walker@1.0.8: dependencies: makeerror: 1.0.12 - dev: true - /webidl-conversions/7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} - dev: true + webidl-conversions@7.0.0: {} - /whatwg-encoding/2.0.0: - resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} - engines: {node: '>=12'} + whatwg-encoding@2.0.0: dependencies: iconv-lite: 0.6.3 - dev: true - /whatwg-mimetype/3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} - dev: true + whatwg-mimetype@3.0.0: {} - /whatwg-url/11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} + whatwg-url@11.0.0: dependencies: tr46: 3.0.0 webidl-conversions: 7.0.0 - dev: true - /which-boxed-primitive/1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 is-boolean-object: 1.1.2 is-number-object: 1.0.7 is-string: 1.0.7 is-symbol: 1.0.4 - dev: true - /which-typed-array/1.1.9: - resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} - engines: {node: '>= 0.4'} + which-typed-array@1.1.15: dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 - has-tostringtag: 1.0.0 - is-typed-array: 1.1.10 - dev: true + has-tostringtag: 1.0.2 - /which/1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true + which@1.3.1: dependencies: isexe: 2.0.0 - dev: true - /which/2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true + which@2.0.2: dependencies: isexe: 2.0.0 - dev: true - /which/3.0.0: - resolution: {integrity: sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - hasBin: true + which@3.0.1: dependencies: isexe: 2.0.0 - dev: true - /wide-align/1.1.5: - resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + wide-align@1.1.5: dependencies: string-width: 4.2.3 - dev: true - /widest-line/4.0.1: - resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} - engines: {node: '>=12'} + widest-line@4.0.1: dependencies: string-width: 5.1.2 - dev: true - /word-wrap/1.2.3: - resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} - engines: {node: '>=0.10.0'} - dev: true + word-wrap@1.2.5: {} - /wordwrap/1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - dev: true + wordwrap@1.0.0: {} - /wrap-ansi/6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - dev: true - /wrap-ansi/7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + wrap-ansi@8.1.0: dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 - /wrap-ansi/8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} + wrap-ansi@9.0.0: dependencies: ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.0.1 - dev: true + string-width: 7.1.0 + strip-ansi: 7.1.0 - /wrappy/1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true + wrappy@1.0.2: {} - /write-file-atomic/3.0.3: - resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + write-file-atomic@3.0.3: dependencies: imurmurhash: 0.1.4 is-typedarray: 1.0.0 signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 - dev: true - /write-file-atomic/4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + write-file-atomic@4.0.2: dependencies: imurmurhash: 0.1.4 signal-exit: 3.0.7 - dev: true - - /ws/8.13.0: - resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: true - - /xdg-basedir/5.1.0: - resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} - engines: {node: '>=12'} - dev: true - - /xml-name-validator/4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} - dev: true - /xmlchars/2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} - dev: true + ws@8.17.1: {} - /xtend/4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - dev: true + xdg-basedir@5.1.0: {} - /y18n/5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true + xml-name-validator@4.0.0: {} - /yallist/3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true + xmlchars@2.2.0: {} - /yallist/4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true + y18n@5.0.8: {} - /yaml/2.2.1: - resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} - engines: {node: '>= 14'} - dev: true + yallist@3.1.1: {} - /yargs-parser/20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - dev: true + yallist@4.0.0: {} - /yargs-parser/21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true + yaml@2.4.5: {} - /yargs/16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - dev: true + yargs-parser@21.1.1: {} - /yargs/17.7.1: - resolution: {integrity: sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==} - engines: {node: '>=12'} + yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - dev: true - /yn/3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - dev: true + yn@3.1.1: + optional: true - /yocto-queue/0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true + yocto-queue@0.1.0: {} - /z-schema/5.0.5: - resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} - engines: {node: '>=8.0.0'} - hasBin: true - dependencies: - lodash.get: 4.4.2 - lodash.isequal: 4.5.0 - validator: 13.9.0 - optionalDependencies: - commander: 9.5.0 - dev: true + yocto-queue@1.0.0: {} + + yoctocolors@2.0.2: {} diff --git a/scripts/build.ts b/scripts/build.ts index 17be0801..3dd2006a 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -1,10 +1,10 @@ -import * as Path from 'path'; -import chalk from 'chalk'; +import { fuzzyMatchTarget, getTargets, isMonoRepo, rootDir } from './utils'; +import { ExtractorConfig, Extractor } from '@microsoft/api-extractor'; +import minimist from 'minimist'; import { execa } from 'execa'; -import { getTargets, fuzzyMatchTarget, rootDir, isMonoRepo } from './utils'; +import * as Path from 'path'; import Fse from 'fs-extra'; -import minimist from 'minimist'; -import { Extractor, ExtractorConfig } from '@microsoft/api-extractor'; +import chalk from 'chalk'; const rootPath = rootDir(); @@ -80,8 +80,8 @@ async function buildType(target: string, pkgDirPath: string, pkgJson: Record([ // 1.获取项目名称 { - type: 'input', - name: 'name', initial: initConfig.name, message: '输入项目名称:', + type: 'input', + name: 'name', }, // 2.获取版本号version { - type: 'input', - name: 'version', - initial: initConfig.version, - message: '输入版本号(version):', validate(value) { // 校验版本号 if (!semver.valid(value)) { @@ -59,42 +55,46 @@ async function getConfig() { } return true; }, + initial: initConfig.version, + message: '输入版本号(version):', + name: 'version', + type: 'input', }, // 3.获取description { - type: 'input', - name: 'description', initial: initConfig.description, message: '输入项目描述(description):', + name: 'description', + type: 'input', }, // 4.获取keywords { - type: 'input', - name: 'keywords', initial: initConfig.keywords, message: '输入关键词(keywords):', + name: 'keywords', + type: 'input', }, // 5.获取author { - type: 'input', - name: 'author', initial: initConfig.author, message: '输入作者(author):', + name: 'author', + type: 'input', }, // 6.获取license { - type: 'input', - name: 'license', initial: initConfig.license, message: '输入license:', + name: 'license', + type: 'input', }, // 7.repo类型 { - type: 'select', - name: 'repoType', + choices: [{ name: RepoType.mono }, { name: RepoType.multi }], initial: RepoType.multi as any, message: '选择repo类型:', - choices: [{ name: RepoType.mono }, { name: RepoType.multi }], + name: 'repoType', + type: 'select', }, ]); @@ -115,11 +115,11 @@ async function getConfig() { async function setup() { try { const { start } = await prompt<{ start: boolean }>({ - type: 'confirm', - name: 'start', message: '是否开始初始化?', + type: 'confirm', initial: false, required: true, + name: 'start', }); if (!start) return; diff --git a/scripts/new-pkg.ts b/scripts/new-pkg.ts index d2a3d08f..a9b4950d 100644 --- a/scripts/new-pkg.ts +++ b/scripts/new-pkg.ts @@ -1,70 +1,70 @@ -import * as path from 'path'; +import { createSrcAndTests, getGitUrl, useFile } from './utils'; +import * as tsUtils from '@mxssfd/core'; +import rootPkg from '../package.json'; import { prompt } from 'enquirer'; +import * as path from 'path'; import chalk from 'chalk'; import * as fs from 'fs'; -import * as tsUtils from '@mxssfd/core'; -import { createSrcAndTests, getGitUrl, useFile } from './utils'; -import rootPkg from '../package.json'; const pkgsPath = path.resolve(__dirname, '../packages'); async function getConfig() { const config = { - name: '', + description: '', + private: false, + keywords: '', pkgName: '', umdName: '', - deps: [], formats: [], - private: false, - description: '', - keywords: '', + name: '', + deps: [], }; ({ value: config.name } = await prompt<{ value: string }>({ - type: 'input', - name: 'value', - message: '目录名(dirName)', - required: true, validate(value) { if (fs.existsSync(path.resolve(pkgsPath, value))) { return '目录已存在!'; } return true; }, + message: '目录名(dirName)', + required: true, + type: 'input', + name: 'value', })); const reply = await prompt([ { - type: 'input', - name: 'pkgName', - message: '包名(pkgName)', initial: `@${rootPkg.name}/${config.name}`, + message: '包名(pkgName)', + name: 'pkgName', required: true, + type: 'input', }, { - type: 'input', - name: 'umdName', - message: '全局umd名(umdName)', initial: tsUtils.toCamel(rootPkg.name, '-') + tsUtils.toCamel(config.name, '-', true), + message: '全局umd名(umdName)', + name: 'umdName', required: true, + type: 'input', }, { - type: 'input', - name: 'description', message: '项目描述(description)', + name: 'description', required: true, + type: 'input', }, { - type: 'input', - name: 'keywords', - message: '关键词(keywords)', initial: config.name.split('-').join(','), + message: '关键词(keywords)', + name: 'keywords', required: true, + type: 'input', }, { + message: '是否私有(private)', type: 'confirm', name: 'private', - message: '是否私有(private)', initial: false, required: true, }, @@ -78,10 +78,10 @@ async function getConfig() { if (deps.length) { ({ deps: config.deps } = await prompt({ - type: 'multiselect', - name: 'deps', message: '选择依赖(deps)(按空格键选中/取消,enter键确定)', + type: 'multiselect', choices: deps, + name: 'deps', })); } @@ -89,11 +89,11 @@ async function getConfig() { if (!config.private) { ({ formats: config.formats } = await prompt({ - type: 'multiselect', - name: 'formats', message: '选择打包类型(formats)(按空格键选中/取消,enter键确定)', - choices: formatsChoices, initial: formatsChoices as any, + choices: formatsChoices, + type: 'multiselect', + name: 'formats', })); } @@ -103,9 +103,9 @@ async function getConfig() { const { confirm } = await prompt<{ confirm: boolean }>({ type: 'confirm', name: 'confirm', - message: '确认', initial: false, required: true, + message: '确认', }); if (!confirm) throw 'cancel'; @@ -169,10 +169,13 @@ function createPackageJson(pkgPath: string, config: Awaited { - prev[`@${rootPkg.name}/${cur}`] = rootPkg.version; - return prev; - }, {} as Record), + config.deps.reduce( + (prev, cur) => { + prev[`@${rootPkg.name}/${cur}`] = rootPkg.version; + return prev; + }, + {} as Record, + ), )}, "author": "dyh", "license": "MIT", @@ -192,11 +195,11 @@ function createPackageJson(pkgPath: string, config: Awaited>) { if (config.private) return; const apiExtContent = { - extends: '../../api-extractor.json', - mainEntryPointFilePath: './dist/packages//src/index.d.ts', dtsRollup: { publicTrimmedFilePath: './dist/.d.ts', }, + mainEntryPointFilePath: './dist/packages//src/index.d.ts', + extends: '../../api-extractor.json', }; fs.writeFileSync( path.resolve(pkgPath, 'api-extractor.json'), @@ -222,11 +225,11 @@ function updateTypedocJson(config: Awaited>) { async function setup() { try { const { start } = await prompt<{ start: boolean }>({ - type: 'confirm', - name: 'start', message: '是否开始添加child package?', + type: 'confirm', initial: false, required: true, + name: 'start', }); if (!start) return; diff --git a/scripts/release.ts b/scripts/release.ts index f53e4f9e..3ead5d50 100644 --- a/scripts/release.ts +++ b/scripts/release.ts @@ -1,11 +1,11 @@ -import * as path from 'path'; -import * as fs from 'fs'; +import { isMonoRepo, rootDir } from './utils'; +import type { ReleaseType } from 'semver'; import { prompt } from 'enquirer'; -import { execa } from 'execa'; import * as semver from 'semver'; +import { execa } from 'execa'; +import * as path from 'path'; import chalk from 'chalk'; -import { ReleaseType } from 'semver'; -import { isMonoRepo, rootDir } from './utils'; +import * as fs from 'fs'; const rootPkgJson = require('../package.json'); const args = require('minimist')(process.argv.slice(2)); @@ -29,33 +29,6 @@ const exec = ( const getPkgPath = (pkg: string) => path.resolve(__dirname, `../packages/${pkg}`); const actions = { - lintCheck: () => exec(npmTool, ['lint-check']), - jestCheck: () => exec(bin('jest'), ['--no-cache']), - build: () => exec(npmTool, ['build']), - updateVersions(pkgs: string[], version: string) { - function updateDeps(json: Record, depType: string, version: string) { - const dep = json[depType]; - for (const k in dep) { - if (k.startsWith('@' + rootPkgJson.name)) { - console.log(chalk.yellow(`${json['name']} -> ${depType} -> ${k}@${version}`)); - dep[k] = version; - } - } - } - function updatePackage(pkgPath: string, version: string) { - const file = fs.readFileSync(pkgPath).toString(); - const json = JSON.parse(file); - json.version = version; - updateDeps(json, 'devDependencies', version); - updateDeps(json, 'dependencies', version); - updateDeps(json, 'peerDependencies', version); - fs.writeFileSync(pkgPath, JSON.stringify(json, null, 2)); - } - for (const pkg of pkgs) { - updatePackage(path.resolve(getPkgPath(pkg), 'package.json'), version); - } - updatePackage(path.resolve(__dirname, `../package.json`), version); - }, async release(config: Config) { async function publishPkg(pkgPath: string) { const json = JSON.parse(fs.readFileSync(path.resolve(pkgPath, 'package.json'), 'utf-8')); @@ -74,7 +47,7 @@ const actions = { step(`Publishing ${json.name}...`); try { - await exec('npm', ['publish', '--access=public'], { cwd: pkgPath, stdio: 'pipe' }); + await exec('npm', ['publish', '--access=public'], { stdio: 'pipe', cwd: pkgPath }); console.log(chalk.green(`Successfully published ${json.name}@${config.targetVersion}`)); } catch (e: any) { if (e.stderr.match(/previously published/)) { @@ -91,7 +64,30 @@ const actions = { } else await publishPkg(rootDir()); }, - genChangeLog: () => exec(npmTool, ['changelog']), + updateVersions(pkgs: string[], version: string) { + function updateDeps(json: Record, depType: string, version: string) { + const dep = json[depType]; + for (const k in dep) { + if (k.startsWith('@' + rootPkgJson.name)) { + console.log(chalk.yellow(`${json['name']} -> ${depType} -> ${k}@${version}`)); + dep[k] = version; + } + } + } + function updatePackage(pkgPath: string, version: string) { + const file = fs.readFileSync(pkgPath).toString(); + const json = JSON.parse(file); + json.version = version; + updateDeps(json, 'devDependencies', version); + updateDeps(json, 'dependencies', version); + updateDeps(json, 'peerDependencies', version); + fs.writeFileSync(pkgPath, JSON.stringify(json, null, 2)); + } + for (const pkg of pkgs) { + updatePackage(path.resolve(getPkgPath(pkg), 'package.json'), version); + } + updatePackage(path.resolve(__dirname, `../package.json`), version); + }, async gitCommit(targetVersion: string) { const { stdout } = await exec('git', ['diff'], { stdio: 'pipe' }); if (stdout) { @@ -108,26 +104,30 @@ const actions = { await exec('git', ['push', 'origin', `refs/tags/v${targetVersion}`]); await exec('git', ['push']); }, + jestCheck: () => exec(bin('jest'), ['--no-cache']), + genChangeLog: () => exec(npmTool, ['changelog']), + lintCheck: () => exec(npmTool, ['lint-check']), + build: () => exec(npmTool, ['build']), }; interface Config { - pkgs: string[]; + skippedPackages: string[]; + currentVersion: string; targetVersion: string; - skipTest: boolean; skipBuild: boolean; - currentVersion: string; + skipTest: boolean; + pkgs: string[]; preId: string; - skippedPackages: string[]; tag: string; } const baseConfig: Config = { pkgs: isMonoRepo ? fs.readdirSync(path.resolve(__dirname, '../packages')) : [], - targetVersion: args._[0], - skipTest: args.skipTest, - skipBuild: args.skipBuild, - currentVersion: rootPkgJson.version, // semver.prerelease('1.2.3-alpha.3') -> [ 'alpha', 3 ] preId: args.preid || semver.prerelease(rootPkgJson.version)?.[0], + currentVersion: rootPkgJson.version, + skipBuild: args.skipBuild, + targetVersion: args._[0], + skipTest: args.skipTest, skippedPackages: [], tag: args.tag, }; @@ -144,27 +144,23 @@ async function getVersion(preId: string, currentVersion: string) { ]; const { release } = await prompt<{ release: string }>([ { - type: 'select', - name: 'release', - message: `选择发布版本(当前v${rootPkgJson.version})`, choices: versionIncrements .map<{ message: string; name: string; hint: string }>((i) => { const version = inc(i) as string; return { - message: i, - name: version, hint: 'v' + version, + name: version, + message: i, }; }) .concat([{ message: `custom`, name: 'custom', hint: '' }]), + message: `选择发布版本(当前v${rootPkgJson.version})`, + name: 'release', + type: 'select', }, ]); if (release === 'custom') { ({ version: targetVersion } = await prompt<{ version: string }>({ - type: 'input', - name: 'version', - message: `Input custom version, cur(v${rootPkgJson.version}):`, - initial: currentVersion, validate(value) { // 校验版本号 if (!semver.valid(value)) return `invalid version: ${value}`; @@ -172,15 +168,19 @@ async function getVersion(preId: string, currentVersion: string) { return true; }, + message: `Input custom version, cur(v${rootPkgJson.version}):`, + initial: currentVersion, + name: 'version', + type: 'input', })); } else { targetVersion = release; } const { yes } = await prompt<{ yes: boolean }>({ + message: `Releasing v${targetVersion}. Confirm?`, type: 'confirm', name: 'yes', - message: `Releasing v${targetVersion}. Confirm?`, }); if (!yes) { diff --git a/scripts/set-repo.ts b/scripts/set-repo.ts index e7f6aaed..adf2d57f 100644 --- a/scripts/set-repo.ts +++ b/scripts/set-repo.ts @@ -1,13 +1,13 @@ -import * as Fs from 'fs'; -import { Config, RepoType } from './init-pkg'; -import { execa } from 'execa'; import { createSrcAndTests, rootDir, useFile } from './utils'; +import { type Config, RepoType } from './init-pkg'; import { toCamel } from '@mxssfd/core'; +import { execa } from 'execa'; +import * as Fs from 'fs'; const paths = { - typedoc: rootDir('typedoc.json'), - tsconfig: rootDir('tsconfig.json'), pnpmWorkspace: rootDir('pnpm-workspace.yaml'), + tsconfig: rootDir('tsconfig.json'), + typedoc: rootDir('typedoc.json'), pkgs: rootDir('packages'), src: rootDir('src'), }; @@ -53,19 +53,19 @@ const multi = { pkgJson['exports'] = { '.': { import: { - node: `./dist/${config.name}.cjs.js`, default: `./dist/${config.name}.esm-bundler.js`, + node: `./dist/${config.name}.cjs.js`, }, require: `./dist/${config.name}.cjs.js`, }, }; pkgJson['buildOptions'] = { - name: toCamel(pkgJson['name'], '-', true), formats: ['esm-bundler', 'esm-browser', 'cjs', 'global'], + name: toCamel(pkgJson['name'], '-', true), }; pkgJson['publishConfig'] = { - access: 'public', registry: 'https://registry.npmjs.org/', + access: 'public', }; updatePkg(pkgJson); }, @@ -74,8 +74,8 @@ const multi = { apiJson['mainEntryPointFilePath'] = './dist/src/index.d.ts'; apiJson['dtsRollup'] = { - enabled: true, publicTrimmedFilePath: './dist/.d.ts', + enabled: true, }; updateApiJson(apiJson); }, diff --git a/scripts/single-fn-file.ts b/scripts/single-fn-file.ts index 40adec5c..e5ffdd36 100644 --- a/scripts/single-fn-file.ts +++ b/scripts/single-fn-file.ts @@ -1,11 +1,11 @@ -import * as Path from 'path'; -import * as FS from 'fs'; -import type { Declaration, ExportNamedDeclaration } from '@babel/types'; -import { parse } from '@babel/parser'; +import type { ExportNamedDeclaration, Declaration } from '@babel/types'; +import type { Identifier } from '@babel/types'; import generate from '@babel/generator'; +import { parse } from '@babel/parser'; import { prompt } from 'enquirer'; -import { Identifier } from '@babel/types'; +import * as Path from 'path'; import chalk from 'chalk'; +import * as FS from 'fs'; /** * 把一个大函数集合文件转成单函数文件 @@ -31,7 +31,7 @@ async function run() { function extractFunctionsFromFile(filepath: string): string[] { const fileContent = FS.readFileSync(filepath, 'utf-8'); // 解析文件内容为 AST - const ast = parse(fileContent, { sourceType: 'module', plugins: ['typescript'] }); + const ast = parse(fileContent, { plugins: ['typescript'], sourceType: 'module' }); // 提取函数定义 const nodes = ast.program.body.filter( @@ -48,6 +48,10 @@ function extractFunctionsFromFile(filepath: string): string[] { return (declaration.declarations[0]!.id as Identifier).name; case 'ExportNamedDeclaration': return getFnName(declaration.declaration!); + case 'TSDeclareFunction': // 函数重载 + return declaration.id!.name; + case 'TSTypeAliasDeclaration': // 类型别名 + return declaration.id!.name; default: console.error(declaration); throw new Error(`未识别的类型:${declaration.type}`); @@ -64,20 +68,29 @@ function extractFunctionsFromFile(filepath: string): string[] { trailingComments: [], }).code; + const isAlias = node.declaration?.type === 'TSTypeAliasDeclaration'; + // 获取函数名 const filename = getFnName(node.declaration!); - // 生成单独的函数文件 - FS.writeFileSync(Path.resolve(dirname, filename + '.ts'), functionFileContent + '\n'); + const filepath = Path.resolve(dirname, filename + '.ts'); + if (FS.existsSync(filepath)) { + // 如果文件存在,则拼接进去 + FS.appendFileSync(filepath, functionFileContent + '\n', 'utf-8'); + } else { + // 生成单独的函数文件 + FS.writeFileSync(Path.resolve(dirname, filename + '.ts'), functionFileContent + '\n', 'utf8'); + } // 写入流 index.ts导出 - indexStream.write(`export * from './${filename}';\n`); + if (!['TSDeclareFunction'].includes(node.declaration!.type)) + indexStream.write(`export${isAlias ? ' type' : ''} * from './${filename}';\n`); }); // 关闭流 indexStream.end(); // 返回函数名列表 - return nodes.map(getFnName); + return Array.from(new Set(nodes.map(getFnName))); } const ignoreList = [ @@ -107,31 +120,31 @@ async function selectFile(rootPath: string): Promise { .map((name) => { const path = Path.resolve(rootPath, name); const isFile = FS.statSync(path).isFile(); - return { name, path, isFile }; + return { isFile, name, path }; }) .sort((a, b) => Number(a.isFile) - Number(b.isFile)); const { path } = await prompt<{ path: string }>([ { - type: 'select', - name: 'path', - message: `选择文件`, - choices: paths.map<{ name: string; hint: string }>(({ name, path, isFile }) => { + choices: paths.map<{ name: string; hint: string }>(({ isFile, name, path }) => { return { + hint: isFile ? 'file' : 'dir', message: name, name: path, - hint: isFile ? 'file' : 'dir', }; }), + message: `选择文件`, + type: 'select', + name: 'path', }, ]); if (!paths.find((p) => p.path === path)!.isFile) return await selectFile(path); const { confirm } = await prompt<{ confirm: boolean }>({ + message: `确定转换该文件(${path})?`, type: 'confirm', name: 'confirm', - message: `确定转换该文件(${path})?`, }); if (!confirm) throw '取消选择文件....'; diff --git a/scripts/utils.ts b/scripts/utils.ts index 507e5cb9..f8de2e66 100644 --- a/scripts/utils.ts +++ b/scripts/utils.ts @@ -1,4 +1,4 @@ -import { resolve, basename } from 'path'; +import { basename, resolve } from 'path'; import chalk from 'chalk'; import * as Fs from 'fs'; const childProcess = require('child_process'); @@ -70,7 +70,7 @@ export function useFile< P extends boolean = false, C = P extends true ? Record : string, >(path: string, parseJson = false as P): [C, (content: C) => void] { - let _content: string | Record | null = Fs.readFileSync(path).toString(); + let _content: Record | string | null = Fs.readFileSync(path).toString(); if (parseJson) _content = JSON.parse(_content); return [ diff --git a/src/CalcChain.ts b/src/CalcChain.ts index 49d38854..c16134ba 100644 --- a/src/CalcChain.ts +++ b/src/CalcChain.ts @@ -1,4 +1,4 @@ -import { plus, minus, times, divide, strip } from './number'; +import { divide, minus, times, strip, plus } from './number'; /** * 链式计算 @@ -25,6 +25,14 @@ import { plus, minus, times, divide, strip } from './number'; export class CalcChain { private _value!: number; + public divide = this['/']; + + public minus = this['-']; + + public times = this['*']; + + public plus = this['+']; + constructor(private readonly initNumber: number) { this.setValue(initNumber); } @@ -34,6 +42,10 @@ export class CalcChain { return new CalcChain(num); } + private setValue(value: number) { + this._value = value; + } + // 加 public ['+'](...nums: number[]): CalcChain { // this.calc((a, b, pow) => (a * pow + b * pow) / pow, num, others); @@ -41,7 +53,19 @@ export class CalcChain { return this; } - public plus = this['+']; + // 100 - 20 * 2; <==> Calc.create(20)["*"](2).before(100, "-") + public by(num: number, calcLabel: '+' | '-' | '*' | '/') { + const value = this._value; + this.setValue(num); + this[calcLabel](value); + return this; + } + + // 除 + public ['/'](...nums: number[]): CalcChain { + this.setValue(divide(this._value, ...nums)); + return this; + } // 减 public ['-'](...nums: number[]): CalcChain { @@ -49,34 +73,20 @@ export class CalcChain { return this; } - public minus = this['-']; - // 乘 public ['*'](...nums: number[]): CalcChain { this.setValue(times(this._value, ...nums)); return this; } - public times = this['*']; - - // 除 - public ['/'](...nums: number[]): CalcChain { - this.setValue(divide(this._value, ...nums)); - return this; - } - - public divide = this['/']; - - // 100 - 20 * 2; <==> Calc.create(20)["*"](2).before(100, "-") - public by(num: number, calcLabel: '+' | '-' | '*' | '/') { - const value = this._value; - this.setValue(num); - this[calcLabel](value); + // 重置为初始值 + public reset(): CalcChain { + this._value = this.initNumber; return this; } - private setValue(value: number) { - this._value = value; + valueOf(): number { + return this._value; } // 获取当前值 @@ -88,14 +98,4 @@ export class CalcChain { public set value(num) { this.setValue(num); } - - // 重置为初始值 - public reset(): CalcChain { - this._value = this.initNumber; - return this; - } - - valueOf(): number { - return this._value; - } } diff --git a/src/array-buffer/arrayBufferToString.ts b/src/array-buffer/arrayBufferToString.ts new file mode 100644 index 00000000..03e96d82 --- /dev/null +++ b/src/array-buffer/arrayBufferToString.ts @@ -0,0 +1,14 @@ +/** + * 把 ArrayBuffer 编码为 string + * + * @see stringToArrayBuffer + */ +export function arrayBufferToString(ab: ArrayBuffer, uint: 16 | 8 = 16): string { + const ua = new (uint === 16 ? Uint16Array : Uint8Array)(ab); + const len = ua.length; + let result = ''; + for (let i = 0; i < len; i++) { + result += String.fromCharCode(ua[i]!); + } + return result; +} diff --git a/src/array-buffer/decodeArrayBufferToObject.ts b/src/array-buffer/decodeArrayBufferToObject.ts new file mode 100644 index 00000000..c8900821 --- /dev/null +++ b/src/array-buffer/decodeArrayBufferToObject.ts @@ -0,0 +1,19 @@ +import { arrayBufferToString } from './arrayBufferToString'; + +/** + * 将被 encodeObjectToArrayBuffer 转成 ArrayBuffer 的 object 还原回来 + * + * @see encodeObjectToArrayBuffer + */ +export function decodeArrayBufferToObject(buffer: ArrayBuffer): null | T { + // TextEncoder 在 node 环境下不支持 + // const u8a = new Uint8Array(buffer); + // const str = new TextDecoder().decode(u8a); + + const str = arrayBufferToString(buffer); + try { + return JSON.parse(str); + } catch { + return null; + } +} diff --git a/src/array-buffer/encodeObjectToArrayBuffer.ts b/src/array-buffer/encodeObjectToArrayBuffer.ts new file mode 100644 index 00000000..8ffed980 --- /dev/null +++ b/src/array-buffer/encodeObjectToArrayBuffer.ts @@ -0,0 +1,17 @@ +import { stringToArrayBuffer } from './stringToArrayBuffer'; + +/** + * 把 object 编码为 ArrayBuffer + * + * 注意:如果 对象里面有特殊对象,例如 函数、正则、ArrayBuffer 等, 那么会被 JSON.stringify 转成空,需要自行转换,如果是 ArrayBuffer 可先 使用 arrayBufferToString 转换为 string + * + * @see decodeArrayBufferToObject + * @see encodeArrayBufferToString + */ +export function encodeObjectToArrayBuffer(obj: object): ArrayBuffer { + const str = JSON.stringify(obj); + // TextEncoder 在 node 环境下不支持 + // const u8a = new TextEncoder().encode(str); + // return u8a.buffer; + return stringToArrayBuffer(str); +} diff --git a/src/array-buffer/index.ts b/src/array-buffer/index.ts new file mode 100644 index 00000000..6e031b51 --- /dev/null +++ b/src/array-buffer/index.ts @@ -0,0 +1,4 @@ +export * from './arrayBufferToString'; +export * from './stringToArrayBuffer'; +export * from './encodeObjectToArrayBuffer'; +export * from './decodeArrayBufferToObject'; diff --git a/src/array-buffer/stringToArrayBuffer.ts b/src/array-buffer/stringToArrayBuffer.ts new file mode 100644 index 00000000..7037a556 --- /dev/null +++ b/src/array-buffer/stringToArrayBuffer.ts @@ -0,0 +1,13 @@ +/** + * string 编码转换为 ArrayBuffer + * + * @see arrayBufferToString + */ +export function stringToArrayBuffer(value: string, uint: 16 | 8 = 16): ArrayBuffer { + const len = value.length; + const result = new (uint === 16 ? Uint16Array : Uint8Array)(value.length); + for (let i = 0; i < len; i++) { + result[i] = value.charCodeAt(i); + } + return result.buffer; +} diff --git a/src/array/async/forEachAsync.ts b/src/array/async/forEachAsync.ts new file mode 100644 index 00000000..e09795ac --- /dev/null +++ b/src/array/async/forEachAsync.ts @@ -0,0 +1,20 @@ +/** + * forEach异步回调版 + * + * 跟promiseQueue类似,不过此函数是callback异步,重点在callback + * + * @param arr + * @param cbAsync 异步回调 + */ +export async function forEachAsync( + arr: ArrayLike, + cbAsync: (value: T, index: number, array: ArrayLike) => Promise, +): Promise { + // 不能直接把arr.length放进循环,否则在循环里新增的话length会变长,原生的不会变长 + const len = arr.length; + // if (!isArrayLike(arr)) throw new TypeError(); + for (let i = 0; i < len; i++) { + const v = await cbAsync(arr[i] as T, i, arr); + if (v === false) break; + } +} diff --git a/src/array/async/index.ts b/src/array/async/index.ts new file mode 100644 index 00000000..79369742 --- /dev/null +++ b/src/array/async/index.ts @@ -0,0 +1,3 @@ +export * from './forEachAsync'; +export * from './mapAsync'; +export * from './reduceAsync'; diff --git a/src/array/async/mapAsync.ts b/src/array/async/mapAsync.ts new file mode 100644 index 00000000..8a560f52 --- /dev/null +++ b/src/array/async/mapAsync.ts @@ -0,0 +1,36 @@ +import { forEachAsync } from './forEachAsync'; + +/** + * map异步回调版 + * + * @example + * + * const asyncList = [ + * async () => { + * await sleep(200); + * return 1; + * }, + * async () => { + * await sleep(300); + * return 2; + * }, + * async () => { + * await sleep(10); + * return 3; + * }, + * ]; + * const res = await fn(asyncList, (v) => v()); + * console.log(res); // [1, 2, 3] + * + */ +export async function mapAsync( + arr: ArrayLike, + cbAsync: (value: T, index: number, array: ArrayLike) => Promise, +): Promise { + const result: any[] = []; + await forEachAsync(arr, async (v: T, k, a) => { + const item = await cbAsync(v, k, a); + result.push(item); + }); + return result; +} diff --git a/src/array/async.ts b/src/array/async/reduceAsync.ts similarity index 63% rename from src/array/async.ts rename to src/array/async/reduceAsync.ts index 482ad1d3..a5da5f28 100644 --- a/src/array/async.ts +++ b/src/array/async/reduceAsync.ts @@ -1,33 +1,8 @@ /** - * 跟promiseQueue类似,不过此函数是callback异步,重点在callback - * @param arr - * @param cbAsync 异步回调 - */ -export async function forEachAsync( - arr: ArrayLike, - cbAsync: (value: T, index: number, array: ArrayLike) => Promise, -): Promise { - // 不能直接把arr.length放进循环,否则在循环里新增的话length会变长,原生的不会变长 - const len = arr.length; - // if (!isArrayLike(arr)) throw new TypeError(); - for (let i = 0; i < len; i++) { - const v = await cbAsync(arr[i] as T, i, arr); - if (v === false) break; - } -} -export async function mapAsync( - arr: ArrayLike, - cbAsync: (value: T, index: number, array: ArrayLike) => Promise, -): Promise { - const result: any[] = []; - await forEachAsync(arr, async (v: T, k, a) => { - const item = await cbAsync(v, k, a); - result.push(item); - }); - return result; -} -/** + * reduce异步回调版 + * * reduce promise 跟 promiseQueue差不多,此函数多了callbackFn + * * @param arr 如果数组中的某一项返回的是false,那么会中断遍历 * @param callbackFn * @param initValue @@ -66,20 +41,16 @@ export async function reduceAsync( initValue?: unknown, ): Promise { const len = arr.length; - if (!len) { if (initValue === void 0) throw new Error('Reduce of empty array with no initial value'); return Promise.resolve(initValue); } - let previousValue: unknown = initValue ?? (await arr[0]()); - for (let i = initValue ? 0 : 1; i < len; i++) { const item = arr[i]; const curValue = await callbackFn(previousValue, item, i, arr); if (curValue === false) break; previousValue = curValue; } - return previousValue; } diff --git a/src/array/common.ts b/src/array/common.ts deleted file mode 100644 index 2002daca..00000000 --- a/src/array/common.ts +++ /dev/null @@ -1,1150 +0,0 @@ -import type { TupleM2N } from '@tool-pack/types'; -import { typeOf, isNaN, isArray, isFunction } from '../data-type'; -import { hasOwn } from '../object'; - -/** - * 创建数组 - * --- - * len与end两个都有值时,以小的为准; - * 包含start,不包含end - * - * @example - * // returns [0, 1] - * createArray({end: 2}); - * @example - * // returns [0, 1] - * createArray({start: 0, end: 2}); - * @example - * // [1, 1] - * createArray({start:0, end:2, len:2, fill:1}); - * @example - * // returns [1, 2] - * createArray(start: 0, len: 2, fill: item => item+1); - */ -export function createArray({ - start = 0, - end, - len, - fill, -}: { - start?: number; - end?: number; - len?: number; - fill?: T | ((item: number, index: number, end: number) => T); -}): T[] { - let _end: number = start; - if (len && end) { - _end = Math.min(start + len, end); - } else { - if (len !== undefined) { - _end = start + len; - } - if (end !== undefined) { - _end = end; - } - } - let callback: (item: number, index: number, end: number) => any; - switch (typeOf(fill)) { - case 'function': - callback = fill as typeof callback; - break; - case 'undefined': - case 'null': - callback = (i) => i; - break; - default: - callback = () => fill; - } - const arr: any[] = []; - for (let item = start, index = 0; item < _end; item++, index++) { - arr.push(callback(item, index, _end)); - } - return arr; -} - -// 注意:写成下面这种方式(把ArrayLike提取到范型A): -// function forEach>( -// arr: A, -// callbackFn: (value: T, index: number, array: A) => any | false, -// elseCB?: () => void, -// ): boolean -// 在使用时回调函数的value是不会有类型推导的,value类型将是 unknown - -// ie9支持 -// forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; -/** - * 遍历数组,并不完全等同 Array.prototype.forEach,该forEach支持中断,支持类似Python的for else功能 - * - * Python的for else hack写法 - * - * ```ts - * try { - * [1, 2, 3, 4, 5].forEach((item, index) => { - * \/* do something *\/ - * if (index === 2 && item === 3) { - * // break; - * throw new Error('break'); - * } - * }); - * \/* do else *\/ - * } catch (e: any) { - * if (e.message !== 'break') throw e; - * } - * ``` - * - * @example - * const arr1 = [1, 2, 3]; - * let isDone = forEach(arr1, (_v, k) => (arr1[k] = k)); - * isEqual(arr1, [0, 1, 2]); // true - * isDone; // true - * - * // ArrayLike - * isDone = forEach({ 0: 1, 1: 2, length: 2 }, (_v, k) => (arr1[k] = k + k)); - * isEqual(arr1, [0, 2, 2]); // true - * isDone; // true - * - * isDone = forEach(arr1, (_v, k) => { - * arr1[k] = k + 1; - * return k !== 1; - * }); - * isDone; // false - * isEqual(arr1, [1, 2, 2]); // true - * - * let elseCount = 0; - * isDone = forEach( - * arr2, - * (v, k) => (arr2[k] = 'a' + v), - * () => elseCount++, // 完整遍历以后会执行该方法 - * ); - * isDone; // true - * elseCount; // 1 - * - * @param arr 数组 - * @param callbackFn 该回调如果返回false则会中断遍历 - * @param elseCB 类似于Python的for else中的else, - * 只会在完整的遍历后执行,如果break则不会触发 - * @returns {boolean} isDone 是否遍历完成 - */ -export function forEach( - arr: ArrayLike, - callbackFn: (value: T, index: number, array: ArrayLike) => any | false, - elseCB?: () => void, -): boolean { - // 不能直接把arr.length放进循环,否则在循环里新增的话length会变长,原生的不会变长 - const len = arr.length || 0; - // if (!isArrayLike(arr)) throw new TypeError(); - for (let i = 0; i < len; i++) { - if (callbackFn(arr[i] as T, i, arr) === false) return false; - } - elseCB && elseCB(); - return true; -} - -/** - * forEach的反向遍历版本 - * - * @example - * - * const arr: number[] = []; - * forEachRight([1, 2, 3, 4], (i) => arr.push(i + 1)); - * isEqual(arr, [5, 4, 3, 2]); // true - * - * const result: any = {}; - * forEachRight(createArray({ len: 20 }), (v, k) => { - * result[k] = v; - * if (k === 10) return false; - * return; - * }); - * isEqual(result, - * createArray({ start: 10, end: 20 }).reduce((obj, v) => { - * obj[v] = v; - * return obj; - * }, {} as Record), - * )); // true - * - * const result2: any[] = []; - * forEachRight(createArray({ len: 20 }), (v, k) => { - * result2.push({ [k]: v }); - * if (k === 15) return false; - * return; - * }); - * - * isEqual(result2, [{ 19: 19 }, { 18: 18 }, { 17: 17 }, { 16: 16 }, { 15: 15 }]); // true - * - * let elseCount = 0; - * const isDone = forEachRight( - * arr, - * () => {}, - * () => elseCount++, // 完整遍历以后会执行该方法 - * ); - * isDone; // true - * elseCount; // 1 - */ -export function forEachRight( - arr: ArrayLike, - callbackFn: (value: T, index: number, array: ArrayLike) => any | false, - elseCB?: () => void, -): boolean { - for (let i = arr.length - 1; i > -1; i--) { - if (callbackFn(arr[i] as T, i, arr) === false) return false; - } - elseCB && elseCB(); - return true; -} - -/** - * 判断value是否是数组,如果是数组就返回value否则返回[value] - * - * @example - * castArray([1]); // [1] - * castArray(1); // [1] - */ -export function castArray(value: T): T extends Array ? T : Array { - return (isArray(value) ? value : [value]) as any; -} - -/** - * 在跟Array.prototype.findIndex基础上添加对ArrayLike支持,且可以跟findIndexRight配套使用 - * - * @example - * - * // 中途删除 - * const i = [1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1].findIndex((v, index, a) => { - * if (v === 1) a.splice(index, 1); - * return v === 4; - * }); - * i; // 3 - * - * const i2 = findIndex([1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1], (v, index, a) => { - * if (v === 1) (a as number[]).splice(index, 1); - * return v === 4; - * }); - * i2; // 3 - * - * findIndex([1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1], (v) => v === 4); // 5 - * findIndex([{ v: 1 }, { v: 2 }], (v) => v.v === 4); // -1 - * findIndex([{ v: 1 }, { v: 2 }], (v) => v.v === 2); // 1 - * - * findIndex([], undefined as any); // -1 - * - */ -export function findIndex( - arr: ArrayLike, - predicate: (value: T, index: number, obj: ArrayLike) => boolean, -): number { - const len = arr.length; - for (let i = 0; i < len; i++) { - const item = arr[i] as T; - if (predicate(item, i, arr as any)) return i; - } - return -1; -} - -/** - * findIndex反向遍历版本 - * - * @example - * const list = [1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1]; - * const result: number[] = []; - * const i = findIndexRight(list, (v) => (result.push(v), v === 4)); - * i; // 5 - * result; // [1, 1, 1, 1, 1, 4] - * findIndexRight([{ v: 1 }, { v: 2 }], (v) => v.v === 4); // -1 - * findIndexRight([{ v: 1 }, { v: 2 }], (v) => v.v === 2); // 1 - * - * findIndexRight([], undefined as any); // -1 - */ -export function findIndexRight( - arr: ArrayLike, - predicate: (value: T, index: number, obj: ArrayLike) => boolean, -): number { - for (let i = arr.length - 1; i >= 0; i--) { - const item = arr[i] as T; - if (predicate(item, i, arr as any)) return i; - } - return -1; -} -/** - * 二分查找item index - * - * @example - * - * let findTimes = 0; - * const arr = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }]; - * - * binaryFindIndex(arr, (o) => (findTimes++, 3 - o.item.id)); // id等于3的item的index是2 - * findTimes; // 查找遍历次数:3 - * - * findTimes = 0; - * binaryFindIndex(arr, (o) => (findTimes++, 2 - o.item.id)); // id等于2的item的index是1 - * findTimes; // 查找遍历次数:2 - * - * findTimes = 0; - * binaryFindIndex(arr, (o) => (findTimes++, 6 - o.item.id)); // id等于6的item的index是5 - * findTimes; // 查找遍历次数:2 - * - * findTimes = 0; - * binaryFindIndex(arr, (o) => (findTimes++, 7 - o.item.id)); // id等于7的item的index是-1 - * findTimes; // 查找遍历次数:2 - * - * @param arr 要查找的数组 - * @param handler 判断条件 item => target - item 返回值为0时为要找的值,小于0则往前找,大于0往后找 - */ -export function binaryFindIndex( - arr: T[], - handler: (options: { item: T; index: number; start: number; end: number; arr: T[] }) => number, -): number { - if (arr.length === 0) return -1; - let start = 0; - let end = arr.length; - - do { - const middleIndex = Math.floor((end - start) / 2) + start; - const value: number = handler({ - item: arr[middleIndex] as T, - index: middleIndex, - start, - end, - arr, - }); - - if (value === 0) { - return middleIndex; - } else if (value > 0) { - start = middleIndex + 1; - } else { - end = middleIndex; - } - } while (end > start); - - return -1; -} - -/** - * 二分查找item - * - * @see binaryFindIndex - * - * @example - * - * let findTimes = 0; - * const arr = [ - * { id: 1, text: '1' }, - * { id: 2, text: '2' }, - * { id: 3, text: '3' }, - * { id: 4, text: '4' }, - * { id: 5, text: '5' }, - * { id: 6, text: '6' }, - * ]; - * - * binaryFind(arr, (o) => (findTimes++, 3 - o.item.id)); // { id: 3, text: '3' } - * findTimes; // 查找遍历次数:3 - * - * findTimes = 0; - * binaryFind(arr, (o) => (findTimes++, 2 - o.item.id)); // { id: 2, text: '2' } - * findTimes; // 查找遍历次数:2 - * - * findTimes = 0; - * binaryFind(arr, (o) => (findTimes++, 6 - o.item.id)); // { id: 6, text: '6' } - * findTimes; // 查找遍历次数:2 - * - * findTimes = 0; - * binaryFind(arr, (o) => (findTimes++, 7 - o.item.id)); // null - * findTimes; // 查找遍历次数:2 - * - * @param arr 要查找的数组 - * @param handler 判断条件 item => target - item 返回值为0时为要找的值,小于0则往前找,大于0往后找 - */ -export function binaryFind( - arr: T[], - handler: (options: { item: T; index: number; start: number; end: number; arr: T[] }) => number, -): T | null { - const index = binaryFindIndex(arr, handler); - if (index === -1) return null; - return arr[index as keyof typeof arr] as T; -} - -/** - * insertToArray函数回调参数类型声明 - */ -export interface InsertToArrayToCBOptions { - item: T; - index: number; - array: T[]; - inserts: T[]; - insert: T; -} - -/** - * item插入到数组,在原数组中改变 - * - * 插入单个,静态目标 - * - * @example - * - * let arr: number[]; - * - * // 插入单个 静态位置 - * arr = [1, 2, 3, 2]; - * insertToArray(5, 1, arr); // 1 - * arr; // [1, 5, 2, 3, 2] - * // 恢复 - * arr = [1, 2, 3, 2]; - * // 插到目标位置后面 - * insertToArray(5, 1, arr, { after: true }); // 2 - * arr; // [1, 2, 5, 3, 2] - * // 恢复 - * arr = [1, 2, 3, 2]; - * // 负号位置 - * insertToArray(5, -1, arr, { after: false }); // 3 - * arr; // [1, 2, 3, 5, 2] - * - * @param insert 插入的item - * @param to 要插入的位置 - * @param array 要插入item的数组 - * @param param 可选参数 - * @param param.after 默认插到前面去 - * @returns 实际插入的位置 - */ -export function insertToArray( - insert: T, - to: number, - array: T[], - param?: { - /** - * 插入位置前后,true为后 - */ - after?: boolean; - }, -): number; -/** - * item插入到数组,在原数组中改变 - * - * 插入多个,静态目标 - * - * @example - * - * // 插入多个 静态位置 - * arr = [1, 2, 3, 2]; - * insertToArray([5, 6], 1, arr); // 1 - * arr; // [1, 5, 6, 2, 3, 2] - * // 恢复 - * arr = [1, 2, 3, 2]!; - * // 插到目标位置后面 - * insertToArray([5, 6], 1, arr, { after: true }); // 2 - * arr; // [1, 2, 5, 6, 3, 2] - * // 恢复 - * arr = [1, 2, 3, 2]; - * // 负号位置 - * insertToArray([5, 6], -1, arr, { after: false }); // 3 - * arr; // [1, 2, 3, 5, 6, 2] - * - * @param inserts 插入的items - * @param to 要插入的位置 - * @param array 要插入item的数组 - * @param param 可选参数 - * @param param.after 默认插到前面去 - * @returns 实际插入的位置 - */ -export function insertToArray( - inserts: T[], - to: number, - array: T[], - param?: { - /** - * 插入位置前后,true为后 - */ - after?: boolean; - }, -): number; -/** - * item插入到数组,在原数组中改变 - * - * 插入单个,动态目标 - * - * @example - * - * // 插入单个 动态位置 - * arr = [1, 2, 3, 2]; - * insertToArray(5, (o) => o.item === 2, arr); // 1 - * arr; // [1, 5, 2, 3, 2] - * // 恢复 - * arr = [1, 2, 3, 2]; - * // 插到目标位置后面 - * insertToArray(5, (o) => o.item === 2, arr, { after: true }); // 2 - * arr; // [1, 2, 5, 3, 2] - * // 恢复 - * arr = [1, 2, 3, 2]; - * // 反向查找 - * insertToArray(5, (o) => o.item === 2, arr, { after: false, reverse: true }); // 3 - * arr; // [1, 2, 3, 5, 2] - * - * @param insert 插入的item - * @param toCB 查找要插入的位置回调 - * @param array 要插入item的数组 - * @param param 可选参数 - * @param param.after 默认插到前面去 - * @param param.reverse 是否反向遍历 - * @returns 实际插入的位置 - */ -export function insertToArray( - insert: T, - toCB: (options: Omit, 'inserts'>) => boolean, - array: T[], - param?: { - /** - * 插入位置前后,true为后 - */ - after?: boolean; - /** - * 从前还是从后查起,true为前 - */ - reverse?: boolean; - }, -): number; - -/** - * item插入到数组,在原数组中改变 - * - * 插入多个,动态目标 - * - * @example - * - * // 插入多个个 动态位置 - * arr = [1, 2, 3, 2]; - * insertToArray([5, 5], (o) => o.item === 2, arr); // 1 - * arr; // [1, 5, 5, 2, 3, 2] - * // 恢复 - * arr = [1, 2, 3, 2]; - * // 插到目标位置后面 - * insertToArray([5, 5], (o) => o.item === 2, arr, { after: true }); // 2 - * arr; // [1, 2, 5, 5, 3, 2] - * // 恢复 - * arr = [1, 2, 3, 2]; - * // 反向查找 - * insertToArray([5, 5], (o) => o.item === 2, arr, { reverse: true }); // 3 - * arr; // [1, 2, 3, 5, 5, 2] - * - * @param inserts 插入的item - * @param toCB 查找要插入的位置回调 - * @param array 要插入item的数组 - * @param param 可选参数 - * @param param.after 默认插到前面去 - * @param param.reverse 是否反向遍历 - * @returns 实际插入的位置 - */ -export function insertToArray( - inserts: T[], - toCB: (options: Omit, 'insert'>) => boolean, - array: T[], - param?: { - /** - * 插入位置前后,true为后 - */ - after?: boolean; - /** - * 从前还是从后查起,true为前 - */ - reverse?: boolean; - }, -): number; - -/** - * item插入到数组,在原数组中改变 - * @param insert 插入的item - * @param to 要插入的位置 如果to是函数的话没有找到则不会插进数组 - * @param array 要插入item的数组 - * @param option - * @param option.after 默认插到前面去 - * @param option.reverse 是否反向遍历 - * @returns 实际插入的位置 - */ -export function insertToArray( - insert: unknown, - to: number | Function, - array: unknown[], - { after = false, reverse = false } = {}, -): number { - const inserts = castArray(insert) as unknown[]; - let index = to as number; - if (isFunction(to)) { - index = (reverse ? findIndexRight : findIndex)(array, (v, k, a) => { - const _options = { item: v, index: k, array: a }; - const options = Array.isArray(insert) - ? ({ ..._options, inserts: insert as any[] } as Omit) - : ({ ..._options, insert } as Omit); - - return to(options); - }); - if (index === -1) { - return -1; - } - } else { - if (to < 0) { - index = array.length + to; - } else if (to > array.length) { - index = array.length - (after ? 1 : 0); - } - } - after && index++; - array.splice(index, 0, ...inserts); - return index; -} - -/** - * 从数组中移除item - * - * @example - * - * const a1 = [1, 2, 3, 4, 5]; - * - * arrayRemoveItem(a1, 100); // undefined - * a1; // [1, 2, 3, 4, 5] - * arrayRemoveItem(a1, 1); // 1 - * a1; // [2, 3, 4, 5] - * - */ -export function arrayRemoveItem(array: T[], item: T): void | T { - const index = array.indexOf(item); - if (index === -1) return; - return array.splice(index, 1)[0]; -} - -/** - * 从数组中移除多个item - * - * 没和arrayRemoveItem合并是因为无法区分function[]中的第二个参数是item还是,查找回调函数 - * - * @example - * - * const a1 = [1, 2, 3, 4, 5]; - * - * arrayRemoveItemsBy(a1, (v) => v === 100); // [] - * a1; // [1, 2, 3, 4, 5] - * arrayRemoveItemsBy(a1, (v) => v === 1); // [1] - * a1; // [2, 3, 4, 5] - * - */ -export function arrayRemoveItemsBy( - array: T[], - removeBy: (v: T, k: number, a: T[]) => boolean, -): T[] { - const removedItems: T[] = []; - forEachRight(array, (v: T, k, a) => { - if (!removeBy(v, k, a as T[])) return; - const item = array.splice(k, 1)[0] as T; - removedItems.unshift(item); - }); - return removedItems; -} - -/** - * 数组去重函数 - * - * @example - * - * unique([1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1]); // [1, 2, 3, 4] - * unique([1, 2, 3, 4]); // [1, 2, 3, 4] - * unique([NaN, null, undefined, '']); // [NaN, null, undefined, ''] - * unique([undefined, undefined, '']); // [undefined, ''] - * unique([NaN, NaN]); // [NaN] - * unique([NaN, NaN], (a, b) => Number.isNaN(a) && Number.isNaN(b)); // [NaN] - * const a = { value: 1 }; - * const b = { value: 2 }; - * const c = { value: 3 }; - * const d = { value: 2 }; - * unique([a, b, c, d]); // [a, b, c, d] - * unique([]); // [] - * unique([a, b, c, d], (v1, v2) => v1.value === v2.value); // [a, b, c] - * - */ -export function unique(target: T[], isRepeatFn?: (value: T, value2: T) => boolean) { - if (!target.length) return target; - const fn = isRepeatFn || ((v1, v2) => v1 === v2 || (isNaN(v1) && isNaN(v2))); - const result = [target[0] as T]; - for (let i = 1, len = target.length; i < len; i++) { - const item = target[i] as T; - if (result.some((resItem) => fn(resItem, item))) continue; - result.push(item); - } - return result; -} - -/** - * 数组分片 - * @example - * chunk([0,1,2,3,4,5,6], 3) // => [[0,1,2],[3,4,5],[6]] - * - * chunk([0, 1, 2, 3, 4, 5, 6], 10); // [[0, 1, 2, 3, 4, 5, 6]] - * chunk([0, 1, 2, 3, 4, 5, 6], 1); // [[0], [1], [2], [3], [4], [5], [6]] - * chunk([0, 1, 2, 3, 4, 5, 6], 0); // [0, 1, 2, 3, 4, 5, 6] - * chunk([0, 1, 2, 3, 4, 5, 6], -1); // [0, 1, 2, 3, 4, 5, 6] - * chunk([0, 1, 2, 3, 4, 5, 6], 3); // [[0, 1, 2], [3, 4, 5], [6]] - * chunk([0, 1, 2, 3, 4, 5], 3); // [[0, 1, 2], [3, 4, 5]] - * chunk([0, 1, 2, 3, 4], 3); // [[0, 1, 2], [3, 4]] - * const emptyArr: any[] = []; - * chunk(emptyArr, 3); // [] - * chunk(emptyArr, 3) !== emptyArr; // true - * chunk({} as any, 3); // [] - * - */ -export function chunk(arr: ArrayLike, chunkLen: L): TupleM2N[] { - if (chunkLen < 1) return Array.prototype.slice.call(arr); - const result: any[] = []; - let i = 0; - while (i < arr.length) { - result.push(Array.prototype.slice.call(arr, i, (i += chunkLen))); - } - return result; -} - -/** - * 判断min <= num <= max - * - * @example - * - * inRange(0, [undefined as any, 100]); // true - * inRange(0, [0]); // true - * inRange(0, [1]); // false - * inRange(0, [1, 2]); // false - * - * @param value - * @param [min = Number.MIN_SAFE_INTEGER] - * @param [max = Number.MAX_SAFE_INTEGER] - */ -export function inRange( - value: number, - [min = -Infinity, max = Infinity]: [number?, number?], -): boolean { - return min <= value && value <= max; -} - -/** - * inRange的复数版 - * - * @see inRange - * - * @example - * - * inRanges(0, [undefined as any, 100]); // true - * inRanges(0, [0]); // true - * inRanges(0, [1]); // false - * inRanges(0, [1, 2]); // false - * - * inRanges(0, [1, 2], [-9, -1]); // false - * inRanges(-9, [1, 2], [-9, -1]); // true - * inRanges(-1, [1, 2], [-9, -1]); // true - * inRanges(-10, [1, 2], [-9, -1]); // false - * inRanges(-10, [1, 2], [-9, -1], [-20, -10]); // true - * inRanges(0, [1, 2], [-9, -1]); // false - */ -export function inRanges(value: number, ...ranges: [number?, number?][]): boolean { - return ranges.some((item) => inRange(value, item)); -} - -/** - * 数组分组 - * @example - * groupBy([{type: 1}, {type: 2}], "type") // returns {1: [{type: 1}], 2: [{type: 2}]} - * // 找不到对应key的分到'*'组 - * groupBy([{type: 1}, {value: 2}], "type") // returns {"*": [{value: 2}], 1: [{type: 1}]} - * - * - * groupBy([{ type: 1 }, { type: 2 }], 'type'); // { 1: [{ type: 1 }], 2: [{ type: 2 }]} - * - * groupBy( - * [ - * { type: 1, value: 111 }, - * { type: 2, value: 222 }, - * { type: 1, value: 222 }, - * { type: 2, value: 33344 }, - * { type: 1, value: 333 }, - * { type: 1, value: 444 }, - * ], - * 'type' - * ); - * // { - * // 1: [ - * // { type: 1, value: 111 }, - * // { type: 1, value: 222 }, - * // { type: 1, value: 333 }, - * // { type: 1, value: 444 }, - * // ], - * // 2: [ - * // { type: 2, value: 222 }, - * // { type: 2, value: 33344 }, - * // ], - * // }; - * - * groupBy([], ''); // {} - * groupBy([], undefined as any); // {} - * groupBy([{ type: 1 }, { type: 2 }], undefined as any); // { '*': [{ type: 1 }, { type: 2 }]} - * groupBy([{ type: 1 }, { value: 2 }], 'type'); // { '*': [{ value: 2 }], 1: [{ type: 1 }] } - * - * // 默认 '*' 组 改为 'other' 组 - * groupBy([{ type: 1 }, { value: 2 }], 'type', 'other'); // {other: [{ value: 2 }],1: [{ type: 1 }] } - * - * - * @param arr 数组 - * @param key 如果item中不存在该key,那么该item会归类到undefined - * @param defaultKey 如果item中不存在该key,那么该item会归类到defaultKey - */ -export function groupBy< - T extends { [k: string]: any }, - K extends keyof T, - R extends { [k: string]: T[] }, ->(arr: T[], key: K, defaultKey?: number | string): R; -/** - * 数组分组 - * - * @example - * - * groupBy( - * [ - * { name: 'a', score: 50 }, - * { name: 'b', score: 90 }, - * { name: 'c', score: 70 }, - * { name: 'd', score: 10 }, - * { name: 'e', score: 100 }, - * ], - * (item) => { - * const score = item.score; - * if (score >= 90) return 'A'; - * if (score >= 60) return 'B'; - * return 'C'; - * }, - * ); - * // result - * // { - * // A: [{ name: 'b', score: 90 }, { name: 'e', score: 100 }], - * // B: [{ name: 'c', score: 70 }], - * // C: [{ name: 'a', score: 50 }, { name: 'd', score: 10 }], - * // } - * - * const list = [ - * { code: 'a' }, - * { code: 'a_a' }, - * { code: 'a_b' }, - * { code: 'a_c' }, - * { code: 'b' }, - * { code: 'b_a' }, - * { code: 'b_b' }, - * ]; - * - * const r = groupBy(list, (item, obj) => { - * let result = ''; - * objForEach( - * obj, - * (_v, k): false | void => { - * if (new RegExp((k as string) + '_.+').test(item.code)) { - * result = k as string; - * return false; - * } - * }, - * () => (result = item.code), - * ); - * return result; - * }); - * - * r; // {a: [{ code: 'a' }, { code: 'a_a' }, { code: 'a_b' }, { code: 'a_c' }],b: [{ code: 'b' }, { code: 'b_a' }, { code: 'b_b' }]} - * - * @param arr 数组 - * @param by 归类回调 - * @param defaultKey 如果item中不存在该key,那么该item会归类到defaultKey - */ -export function groupBy( - arr: T[], - by: (it: T, result: any) => string | void, - defaultKey?: number | string, -): R; -export function groupBy(arr: any[], key: string | Function, defaultKey: number | string = '*') { - const cb = isFunction(key) ? key : (item: Record) => item[key]; - return arr.reduce((result, item) => { - const k = cb(item, result) ?? defaultKey; - if (!hasOwn(result, k)) { - result[k] = [item]; - } else { - result[k].push(item); - } - return result; - }, {} as Record); -} - -/** - * 查找是否items中任何一个在list中 - * - * @example - * - * someInList([0, 20, 100], [...Array(10).keys()]); // true - * - * someInList([500, 20], Array.from({ length: 10 })); // false - * - * someInList([{ id: 1 }], [{ id: 1 }, { id: 2 }, { id2: 3 }]); // false - * - * const list = [{ id: 1 }, { id: 2 }, { id: 3 }]; - * someInList([{ id: 1 }], list, (item, _i, list) => list.some((s) => s.id === item.id)),; // true - * - */ -export function someInList( - items: T[], - list: T[], - cb: (item: T, index: number, list: T[]) => boolean = (v, _, arr) => arr.includes(v), -): boolean { - return items.some((item, index) => { - return cb(item, index, list); - }); -} - -/** - * 数组求和 - * - * @example - * - * sum([0, 20, 100]); // 120 - * sum([-10, 20, 100]); // 110 - */ -export function sum(arr: number[]): number { - return arr.reduce((res, item) => item + res, 0); -} - -/** - * 数组求平均值 - * - * @example - * - * avg([20, 20, 20]); // 20 - * avg([-10, 20, 20]); // 10 - * - */ -export function avg(arr: number[]): number { - return sum(arr) / arr.length; -} - -/** - * 获取num阶杨辉三角 - * - * @example - * - * getYangHuiTriangleOne(6); // [1, 5, 10, 10, 5, 1] - * getYangHuiTriangleOne(10); // [1, 9, 36, 84, 126, 126, 84, 36, 9, 1] - * - * @param num 阶数 - */ -export function getYangHuiTriangleOne(num: number): number[] { - if (num < 1) return []; - if (num === 1) return [1]; - - const result: number[] = []; - result[0] = result[1] = 1; - - for (let i = 3; i <= num; i++) { - const prev = result.slice(); - - result[0] = result[i - 1] = 1; - - for (let j = 1; j < i - 1; j++) { - result[j] = (prev[j - 1] as number) + (prev[j] as number); - } - } - - return result; -} - -/** - * 获取num阶杨辉三角 - * - * @example - * - * // [1], - * // [1, 1], - * // [1, 2, 1], - * // [1, 3, 3, 1], - * // [1, 4, 6, 4, 1], - * // [1, 5, 10, 10, 5, 1] - * getYangHuiTriangle(6); - * - * @param num 阶数 - */ -export function getYangHuiTriangle(num: number): number[][] { - const result: number[][] = [[1]]; - - if (num === 1) return result; - - result.push([1, 1]); - - for (let i = 3; i <= num; i++) { - const cur: number[] = []; - const prev = result[result.length - 1] as number[]; - - cur[0] = cur[i - 1] = 1; - - for (let k = 1; k < i - 1; k++) { - cur[k] = (prev[k - 1] as number) + (prev[k] as number); - } - result.push(cur); - } - - return result; -} - -const enum Direct { - top = 'top', - bottom = 'bottom', - left = 'left', - right = 'right', -} - -/** - * 环绕式遍历数组 - * - * @example - * - * ```ts - * const arr = [ - * [1, 2, 3, 4, 5], - * [6, 7, 8, 9, 10], - * [11, 12, 13, 14, 15], - * [16, 17, 18, 19, 20], - * [21, 22, 23, 24, 25], - * ]; - * - * const res: number[] = []; - * - * // 顺时针遍历 - * forEachAround(arr, (v) => res.push(v)); - * console.log(res); // [1, 2, 3, 4, 5, 10, 15, 20, 25, 24, 23, 22, 21, 16, 11, 6, 7, 8, 9, 14, 19, 18, 17, 12, 13] - * - * res.length = 0; - * // 逆时针遍历 - * forEachAround(arr, (v) => res.push(v), {reverse: true}); - * console.log(res); // [1, 6, 11, 16, 21, 22, 23, 24, 25, 20, 15, 10, 5, 4, 3, 2, 7, 12, 17, 18, 19, 14, 9, 8, 13] - * - * res.length = 0; - * // 只遍历最外面一圈 - * forEachAround(arr, (v, i): false | void => { - * if (i[0] === 1 && i[1] === 1) return false; - * res.push(v); - * }); - * console.log(res); // [1, 2, 3, 4, 5, 10, 15, 20, 25, 24, 23, 22, 21, 16, 11, 6] - * - * res.length = 0; - * // 只遍历最外面一圈,并且跳过第一层 - * forEachAround(arr, (v, i): false | void => { - * if (i[0] === 0 && i[1] === 0) { - * // 移动到第二行倒数第二列 - * i[0] = 1; - * i[1] = 3; - * return; - * } - * if (i[0] === 1 && i[1] === 1) return false; - * res.push(v); - * }); - * console.log(res); // [10, 15, 20, 25, 24, 23, 22, 21, 16, 11, 6] - * - * res.length = 0; - * // 只遍历最外面一圈,并且跳过第一层(使用startIndexes和startDirect) - * forEachAround( - * arr, - * (v, i): false | void => { - * res.push(v); - * if (i[0] === 0 && i[1] === 0) return false; - * }, - * { startIndexes: [1, 4], startDirect: 'bottom' }, - * ); - * console.log(res); // [10, 15, 20, 25, 24, 23, 22, 21, 16, 11, 6, 1] - * - * ``` - * - * @param arr 需要遍历的数组 - * @param callbackFn 回调函数 - * @param {{}} options - * @param options.reverse 是否逆时针遍历;默认为false,顺时针遍历 - * @param options.startIndexes 开始时的index,默认[0, 0] - * @param options.startDirect 开始时的方向,默认向右('right'),reverse为true时向左('left') - */ -export function forEachAround>( - arr: T, - callbackFn: ( - value: T extends Array<(infer R)[]> ? R : unknown, - indexes: [col: number, row: number], - array: T, - ) => any | false, - { - reverse = false, - startIndexes, - startDirect, - }: { - reverse?: boolean; - startIndexes?: [col: number, row: number]; - startDirect?: 'top' | 'bottom' | 'left' | 'right'; - } = {}, -) { - let direct = (startDirect as Direct) ?? (reverse ? Direct.bottom : Direct.right); - let indexes: [col: number, row: number] = startIndexes ?? [0, 0]; - - const ranges: [col: [start: number, end: number], row: [start: number, end: number]] = [ - [0, arr.length - 1], - [0, (arr[0]?.length || 0) - 1], - ]; - - function getNextIndexes(direct: Direct): typeof indexes | null { - let x = 0; - let y = 0; - const matches: Record void> = { - [Direct.right]: () => x++, - [Direct.left]: () => x--, - [Direct.top]: () => y--, - [Direct.bottom]: () => y++, - }; - matches[direct](); - - const _indexes: typeof indexes = [indexes[0] + y, indexes[1] + x]; - - const [colRange, rowRange] = ranges; - if (!inRange(_indexes[0], colRange) || !inRange(_indexes[1], rowRange)) return null; - - return _indexes; - } - function getNewDirect(): Direct | null { - const matches: Record Direct> = { - [Direct.right]: () => (reverse ? Direct.top : Direct.bottom), - [Direct.left]: () => (reverse ? Direct.bottom : Direct.top), - [Direct.top]: () => (reverse ? Direct.left : Direct.right), - [Direct.bottom]: () => (reverse ? Direct.right : Direct.left), - }; - const _d = matches[direct](); - return getNextIndexes(_d) && _d; - } - function updateRanges(): void { - const [colRange, rowRange] = ranges; - const matches: Record void> = { - [Direct.right]: () => (reverse ? colRange[1]-- : colRange[0]++), - [Direct.left]: () => (reverse ? colRange[0]++ : colRange[1]--), - [Direct.top]: () => (reverse ? rowRange[1]-- : rowRange[0]++), - [Direct.bottom]: () => (reverse ? rowRange[0]++ : rowRange[1]--), - }; - matches[direct](); - } - - let whileFlag = true; - const runCB = () => { - const [col, row] = indexes; - const item = arr[col]?.[row]; - if (callbackFn(item, indexes, arr) === false) whileFlag = false; - }; - - if (inRange(indexes[0], ranges[0]) && inRange(indexes[1], ranges[1])) runCB(); - - while (whileFlag) { - const nextIndexes = getNextIndexes(direct); - if (nextIndexes) { - indexes = nextIndexes; - runCB(); - continue; - } - const _d = getNewDirect(); - if (_d === null) break; - updateRanges(); - direct = _d; - } -} diff --git a/src/array/common/arrayRemoveItem.ts b/src/array/common/arrayRemoveItem.ts new file mode 100644 index 00000000..1ba7890d --- /dev/null +++ b/src/array/common/arrayRemoveItem.ts @@ -0,0 +1,18 @@ +/** + * 从数组中移除item + * + * @example + * + * const a1 = [1, 2, 3, 4, 5]; + * + * arrayRemoveItem(a1, 100); // undefined + * a1; // [1, 2, 3, 4, 5] + * arrayRemoveItem(a1, 1); // 1 + * a1; // [2, 3, 4, 5] + * + */ +export function arrayRemoveItem(array: T[], item: T): void | T { + const index = array.indexOf(item); + if (index === -1) return; + return array.splice(index, 1)[0]; +} diff --git a/src/array/common/arrayRemoveItemsBy.ts b/src/array/common/arrayRemoveItemsBy.ts new file mode 100644 index 00000000..02f82cc2 --- /dev/null +++ b/src/array/common/arrayRemoveItemsBy.ts @@ -0,0 +1,29 @@ +import { forEachRight } from './forEachRight'; + +/** + * 从数组中移除多个item + * + * 没和arrayRemoveItem合并是因为无法区分function[]中的第二个参数是item还是,查找回调函数 + * + * @example + * + * const a1 = [1, 2, 3, 4, 5]; + * + * arrayRemoveItemsBy(a1, (v) => v === 100); // [] + * a1; // [1, 2, 3, 4, 5] + * arrayRemoveItemsBy(a1, (v) => v === 1); // [1] + * a1; // [2, 3, 4, 5] + * + */ +export function arrayRemoveItemsBy( + array: T[], + removeBy: (v: T, k: number, a: T[]) => boolean, +): T[] { + const removedItems: T[] = []; + forEachRight(array, (v: T, k, a) => { + if (!removeBy(v, k, a as T[])) return; + const item = array.splice(k, 1)[0] as T; + removedItems.unshift(item); + }); + return removedItems; +} diff --git a/src/array/common/avg.ts b/src/array/common/avg.ts new file mode 100644 index 00000000..2bc0cbfc --- /dev/null +++ b/src/array/common/avg.ts @@ -0,0 +1,14 @@ +import { sum } from './sum'; + +/** + * 数组求平均值 + * + * @example + * + * avg([20, 20, 20]); // 20 + * avg([-10, 20, 20]); // 10 + * + */ +export function avg(arr: number[]): number { + return sum(arr) / arr.length; +} diff --git a/src/array/common/binaryFind.ts b/src/array/common/binaryFind.ts new file mode 100644 index 00000000..09d00fb6 --- /dev/null +++ b/src/array/common/binaryFind.ts @@ -0,0 +1,45 @@ +import { binaryFindIndex } from './binaryFindIndex'; + +/** + * 二分查找item + * + * @see binaryFindIndex + * + * @example + * + * let findTimes = 0; + * const arr = [ + * { id: 1, text: '1' }, + * { id: 2, text: '2' }, + * { id: 3, text: '3' }, + * { id: 4, text: '4' }, + * { id: 5, text: '5' }, + * { id: 6, text: '6' }, + * ]; + * + * binaryFind(arr, (o) => (findTimes++, 3 - o.item.id)); // { id: 3, text: '3' } + * findTimes; // 查找遍历次数:3 + * + * findTimes = 0; + * binaryFind(arr, (o) => (findTimes++, 2 - o.item.id)); // { id: 2, text: '2' } + * findTimes; // 查找遍历次数:2 + * + * findTimes = 0; + * binaryFind(arr, (o) => (findTimes++, 6 - o.item.id)); // { id: 6, text: '6' } + * findTimes; // 查找遍历次数:2 + * + * findTimes = 0; + * binaryFind(arr, (o) => (findTimes++, 7 - o.item.id)); // null + * findTimes; // 查找遍历次数:2 + * + * @param arr 要查找的数组 + * @param handler 判断条件 item => target - item 返回值为0时为要找的值,小于0则往前找,大于0往后找 + */ +export function binaryFind( + arr: T[], + handler: (options: { index: number; start: number; end: number; arr: T[]; item: T }) => number, +): null | T { + const index = binaryFindIndex(arr, handler); + if (index === -1) return null; + return arr[index as keyof typeof arr] as T; +} diff --git a/src/array/common/binaryFindIndex.ts b/src/array/common/binaryFindIndex.ts new file mode 100644 index 00000000..9982198a --- /dev/null +++ b/src/array/common/binaryFindIndex.ts @@ -0,0 +1,52 @@ +/** + * 二分查找item index + * + * @example + * + * let findTimes = 0; + * const arr = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }]; + * + * binaryFindIndex(arr, (o) => (findTimes++, 3 - o.item.id)); // id等于3的item的index是2 + * findTimes; // 查找遍历次数:3 + * + * findTimes = 0; + * binaryFindIndex(arr, (o) => (findTimes++, 2 - o.item.id)); // id等于2的item的index是1 + * findTimes; // 查找遍历次数:2 + * + * findTimes = 0; + * binaryFindIndex(arr, (o) => (findTimes++, 6 - o.item.id)); // id等于6的item的index是5 + * findTimes; // 查找遍历次数:2 + * + * findTimes = 0; + * binaryFindIndex(arr, (o) => (findTimes++, 7 - o.item.id)); // id等于7的item的index是-1 + * findTimes; // 查找遍历次数:2 + * + * @param arr 要查找的数组 + * @param handler 判断条件 item => target - item 返回值为0时为要找的值,小于0则往前找,大于0往后找 + */ +export function binaryFindIndex( + arr: T[], + handler: (options: { index: number; start: number; end: number; arr: T[]; item: T }) => number, +): number { + if (arr.length === 0) return -1; + let start = 0; + let end = arr.length; + do { + const middleIndex = Math.floor((end - start) / 2) + start; + const value: number = handler({ + item: arr[middleIndex] as T, + index: middleIndex, + start, + end, + arr, + }); + if (value === 0) { + return middleIndex; + } else if (value > 0) { + start = middleIndex + 1; + } else { + end = middleIndex; + } + } while (end > start); + return -1; +} diff --git a/src/array/common/castArray.ts b/src/array/common/castArray.ts new file mode 100644 index 00000000..7e8dd69f --- /dev/null +++ b/src/array/common/castArray.ts @@ -0,0 +1,12 @@ +import { isArray } from '../../data-type'; + +/** + * 判断value是否是数组,如果是数组就返回value否则返回[value] + * + * @example + * castArray([1]); // [1] + * castArray(1); // [1] + */ +export function castArray(value: T): T extends Array ? T : Array { + return (isArray(value) ? value : [value]) as any; +} diff --git a/src/array/common/chunk.ts b/src/array/common/chunk.ts new file mode 100644 index 00000000..66a6bf6e --- /dev/null +++ b/src/array/common/chunk.ts @@ -0,0 +1,31 @@ +import type { TupleM2N } from '@tool-pack/types'; + +/** + * 数组分片 + * @example + * chunk([0,1,2,3,4,5,6], 3) // => [[0,1,2],[3,4,5],[6]] + * + * chunk([0, 1, 2, 3, 4, 5, 6], 10); // [[0, 1, 2, 3, 4, 5, 6]] + * chunk([0, 1, 2, 3, 4, 5, 6], 1); // [[0], [1], [2], [3], [4], [5], [6]] + * chunk([0, 1, 2, 3, 4, 5, 6], 0); // [0, 1, 2, 3, 4, 5, 6] + * chunk([0, 1, 2, 3, 4, 5, 6], -1); // [0, 1, 2, 3, 4, 5, 6] + * chunk([0, 1, 2, 3, 4, 5, 6], 3); // [[0, 1, 2], [3, 4, 5], [6]] + * chunk([0, 1, 2, 3, 4, 5], 3); // [[0, 1, 2], [3, 4, 5]] + * chunk([0, 1, 2, 3, 4], 3); // [[0, 1, 2], [3, 4]] + * const emptyArr: any[] = []; + * chunk(emptyArr, 3); // [] + * chunk(emptyArr, 3) !== emptyArr; // true + * chunk({} as any, 3); // [] + * + */ +export function chunk(arr: ArrayLike, chunkLen: L): TupleM2N[] { + const slice = Array.prototype.slice; + if (chunkLen < 1) return slice.call(arr); + + const result: any[] = []; + let i = 0; + const len = arr.length; + while (i < len) result.push(slice.call(arr, i, (i += chunkLen))); + + return result; +} diff --git a/src/array/common/createArray.ts b/src/array/common/createArray.ts new file mode 100644 index 00000000..d1cf8413 --- /dev/null +++ b/src/array/common/createArray.ts @@ -0,0 +1,61 @@ +import { typeOf } from '../../data-type'; + +/** + * 创建数组 + * --- + * len与end两个都有值时,以小的为准; + * 包含start,不包含end + * + * @example + * // returns [0, 1] + * createArray({end: 2}); + * @example + * // returns [0, 1] + * createArray({start: 0, end: 2}); + * @example + * // [1, 1] + * createArray({start:0, end:2, len:2, fill:1}); + * @example + * // returns [1, 2] + * createArray(start: 0, len: 2, fill: item => item+1); + */ +export function createArray({ + start = 0, + fill, + end, + len, +}: { + fill?: ((item: number, index: number, end: number) => T) | T; + start?: number; + end?: number; + len?: number; +}): T[] { + let _end: number = start; + if (len && end) { + _end = Math.min(start + len, end); + } else { + if (len !== undefined) { + _end = start + len; + } + if (end !== undefined) { + _end = end; + } + } + let callback: (item: number, index: number, end: number) => any; + switch (typeOf(fill)) { + case 'function': + callback = fill as typeof callback; + break; + case 'undefined': + case 'null': + callback = (i) => i; + break; + default: + callback = () => fill; + } + const arr: any[] = []; + for (let item = start, index = 0; item < _end; item++, index++) { + arr.push(callback(item, index, _end)); + } + return arr; +} diff --git a/src/array/common/findIndex.ts b/src/array/common/findIndex.ts new file mode 100644 index 00000000..7c780d3e --- /dev/null +++ b/src/array/common/findIndex.ts @@ -0,0 +1,36 @@ +/** + * 在跟Array.prototype.findIndex基础上添加对ArrayLike支持,且可以跟findIndexRight配套使用 + * + * @example + * + * // 中途删除 + * const i = [1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1].findIndex((v, index, a) => { + * if (v === 1) a.splice(index, 1); + * return v === 4; + * }); + * i; // 3 + * + * const i2 = findIndex([1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1], (v, index, a) => { + * if (v === 1) (a as number[]).splice(index, 1); + * return v === 4; + * }); + * i2; // 3 + * + * findIndex([1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1], (v) => v === 4); // 5 + * findIndex([{ v: 1 }, { v: 2 }], (v) => v.v === 4); // -1 + * findIndex([{ v: 1 }, { v: 2 }], (v) => v.v === 2); // 1 + * + * findIndex([], undefined as any); // -1 + * + */ +export function findIndex( + arr: ArrayLike, + predicate: (value: T, index: number, obj: ArrayLike) => boolean, +): number { + const len = arr.length; + for (let i = 0; i < len; i++) { + const item = arr[i] as T; + if (predicate(item, i, arr as any)) return i; + } + return -1; +} diff --git a/src/array/common/findIndexRight.ts b/src/array/common/findIndexRight.ts new file mode 100644 index 00000000..d9e35f26 --- /dev/null +++ b/src/array/common/findIndexRight.ts @@ -0,0 +1,24 @@ +/** + * findIndex反向遍历版本 + * + * @example + * const list = [1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1]; + * const result: number[] = []; + * const i = findIndexRight(list, (v) => (result.push(v), v === 4)); + * i; // 5 + * result; // [1, 1, 1, 1, 1, 4] + * findIndexRight([{ v: 1 }, { v: 2 }], (v) => v.v === 4); // -1 + * findIndexRight([{ v: 1 }, { v: 2 }], (v) => v.v === 2); // 1 + * + * findIndexRight([], undefined as any); // -1 + */ +export function findIndexRight( + arr: ArrayLike, + predicate: (value: T, index: number, obj: ArrayLike) => boolean, +): number { + for (let i = arr.length - 1; i >= 0; i--) { + const item = arr[i] as T; + if (predicate(item, i, arr as any)) return i; + } + return -1; +} diff --git a/src/array/common/forEach.ts b/src/array/common/forEach.ts new file mode 100644 index 00000000..9965f18d --- /dev/null +++ b/src/array/common/forEach.ts @@ -0,0 +1,77 @@ +// 注意:写成下面这种方式(把ArrayLike提取到范型A): +// function forEach>( +// arr: A, +// callbackFn: (value: T, index: number, array: A) => any | false, +// elseCB?: () => void, +// ): boolean +// 在使用时回调函数的value是不会有类型推导的,value类型将是 unknown + +// ie9支持 +// forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void; +/** + * 遍历数组,并不完全等同 Array.prototype.forEach,该forEach支持中断,支持类似Python的for else功能 + * + * Python的for else hack写法 + * + * ```ts + * try { + * [1, 2, 3, 4, 5].forEach((item, index) => { + * \/* do something *\/ + * if (index === 2 && item === 3) { + * // break; + * throw new Error('break'); + * } + * }); + * \/* do else *\/ + * } catch (e: any) { + * if (e.message !== 'break') throw e; + * } + * ``` + * + * @example + * const arr1 = [1, 2, 3]; + * let isDone = forEach(arr1, (_v, k) => (arr1[k] = k)); + * isEqual(arr1, [0, 1, 2]); // true + * isDone; // true + * + * // ArrayLike + * isDone = forEach({ 0: 1, 1: 2, length: 2 }, (_v, k) => (arr1[k] = k + k)); + * isEqual(arr1, [0, 2, 2]); // true + * isDone; // true + * + * isDone = forEach(arr1, (_v, k) => { + * arr1[k] = k + 1; + * return k !== 1; + * }); + * isDone; // false + * isEqual(arr1, [1, 2, 2]); // true + * + * let elseCount = 0; + * isDone = forEach( + * arr2, + * (v, k) => (arr2[k] = 'a' + v), + * () => elseCount++, // 完整遍历以后会执行该方法 + * ); + * isDone; // true + * elseCount; // 1 + * + * @param arr 数组 + * @param callbackFn 该回调如果返回false则会中断遍历 + * @param elseCB 类似于Python的for else中的else, + * 只会在完整的遍历后执行,如果break则不会触发 + * @returns {boolean} isDone 是否遍历完成 + */ +export function forEach( + arr: ArrayLike, + callbackFn: (value: T, index: number, array: ArrayLike) => false | any, + elseCB?: () => void, +): boolean { + // 不能直接把arr.length放进循环,否则在循环里新增的话length会变长,原生的不会变长 + const len = arr.length || 0; + // if (!isArrayLike(arr)) throw new TypeError(); + for (let i = 0; i < len; i++) { + if (callbackFn(arr[i] as T, i, arr) === false) return false; + } + elseCB && elseCB(); + return true; +} diff --git a/src/array/common/forEachAround.ts b/src/array/common/forEachAround.ts new file mode 100644 index 00000000..0f6dad57 --- /dev/null +++ b/src/array/common/forEachAround.ts @@ -0,0 +1,156 @@ +import { inRange } from './inRange'; + +// eslint-disable-next-line no-restricted-syntax +const enum Direct { + bottom = 'bottom', + right = 'right', + left = 'left', + top = 'top', +} + +/** + * 环绕式遍历数组 + * + * @example + * + * ```ts + * const arr = [ + * [1, 2, 3, 4, 5], + * [6, 7, 8, 9, 10], + * [11, 12, 13, 14, 15], + * [16, 17, 18, 19, 20], + * [21, 22, 23, 24, 25], + * ]; + * + * const res: number[] = []; + * + * // 顺时针遍历 + * forEachAround(arr, (v) => res.push(v)); + * console.log(res); // [1, 2, 3, 4, 5, 10, 15, 20, 25, 24, 23, 22, 21, 16, 11, 6, 7, 8, 9, 14, 19, 18, 17, 12, 13] + * + * res.length = 0; + * // 逆时针遍历 + * forEachAround(arr, (v) => res.push(v), {reverse: true}); + * console.log(res); // [1, 6, 11, 16, 21, 22, 23, 24, 25, 20, 15, 10, 5, 4, 3, 2, 7, 12, 17, 18, 19, 14, 9, 8, 13] + * + * res.length = 0; + * // 只遍历最外面一圈 + * forEachAround(arr, (v, i): false | void => { + * if (i[0] === 1 && i[1] === 1) return false; + * res.push(v); + * }); + * console.log(res); // [1, 2, 3, 4, 5, 10, 15, 20, 25, 24, 23, 22, 21, 16, 11, 6] + * + * res.length = 0; + * // 只遍历最外面一圈,并且跳过第一层 + * forEachAround(arr, (v, i): false | void => { + * if (i[0] === 0 && i[1] === 0) { + * // 移动到第二行倒数第二列 + * i[0] = 1; + * i[1] = 3; + * return; + * } + * if (i[0] === 1 && i[1] === 1) return false; + * res.push(v); + * }); + * console.log(res); // [10, 15, 20, 25, 24, 23, 22, 21, 16, 11, 6] + * + * res.length = 0; + * // 只遍历最外面一圈,并且跳过第一层(使用startIndexes和startDirect) + * forEachAround( + * arr, + * (v, i): false | void => { + * res.push(v); + * if (i[0] === 0 && i[1] === 0) return false; + * }, + * { startIndexes: [1, 4], startDirect: 'bottom' }, + * ); + * console.log(res); // [10, 15, 20, 25, 24, 23, 22, 21, 16, 11, 6, 1] + * + * ``` + * + * @param arr 需要遍历的数组 + * @param callbackFn 回调函数 + * @param {{}} options + * @param options.reverse 是否逆时针遍历;默认为false,顺时针遍历 + * @param options.startIndexes 开始时的index,默认[0, 0] + * @param options.startDirect 开始时的方向,默认向右('right'),reverse为true时向左('left') + */ +export function forEachAround>( + arr: T, + callbackFn: ( + value: T extends Array<(infer R)[]> ? R : unknown, + indexes: [col: number, row: number], + array: T, + ) => false | any, + { + reverse = false, + startIndexes, + startDirect, + }: { + startIndexes?: [col: number, row: number]; + startDirect?: keyof typeof Direct; + reverse?: boolean; + } = {}, +) { + let direct = (startDirect as Direct) ?? (reverse ? Direct.bottom : Direct.right); + let indexes: [col: number, row: number] = startIndexes ?? [0, 0]; + const ranges: [col: [start: number, end: number], row: [start: number, end: number]] = [ + [0, arr.length - 1], + [0, (arr[0]?.length || 0) - 1], + ]; + function getNextIndexes(direct: Direct): typeof indexes | null { + let x = 0; + let y = 0; + const matches: Record void> = { + [Direct.bottom]: () => y++, + [Direct.right]: () => x++, + [Direct.left]: () => x--, + [Direct.top]: () => y--, + }; + matches[direct](); + const _indexes: typeof indexes = [indexes[0] + y, indexes[1] + x]; + const [colRange, rowRange] = ranges; + if (!inRange(_indexes[0], colRange) || !inRange(_indexes[1], rowRange)) return null; + return _indexes; + } + function getNewDirect(): Direct | null { + const matches: Record Direct> = { + [Direct.bottom]: () => (reverse ? Direct.right : Direct.left), + [Direct.right]: () => (reverse ? Direct.top : Direct.bottom), + [Direct.left]: () => (reverse ? Direct.bottom : Direct.top), + [Direct.top]: () => (reverse ? Direct.left : Direct.right), + }; + const _d = matches[direct](); + return getNextIndexes(_d) && _d; + } + function updateRanges(): void { + const [colRange, rowRange] = ranges; + const matches: Record void> = { + [Direct.bottom]: () => (reverse ? rowRange[0]++ : rowRange[1]--), + [Direct.right]: () => (reverse ? colRange[1]-- : colRange[0]++), + [Direct.left]: () => (reverse ? colRange[0]++ : colRange[1]--), + [Direct.top]: () => (reverse ? rowRange[1]-- : rowRange[0]++), + }; + matches[direct](); + } + let whileFlag = true; + const runCB = () => { + const [col, row] = indexes; + const item = arr[col]?.[row]; + if (callbackFn(item, indexes, arr) === false) whileFlag = false; + }; + if (inRange(indexes[0], ranges[0]) && inRange(indexes[1], ranges[1])) runCB(); + while (whileFlag) { + const nextIndexes = getNextIndexes(direct); + if (nextIndexes) { + indexes = nextIndexes; + runCB(); + continue; + } + const _d = getNewDirect(); + if (_d === null) break; + updateRanges(); + direct = _d; + } +} diff --git a/src/array/common/forEachRight.ts b/src/array/common/forEachRight.ts new file mode 100644 index 00000000..05d671fe --- /dev/null +++ b/src/array/common/forEachRight.ts @@ -0,0 +1,51 @@ +/** + * forEach的反向遍历版本 + * + * @example + * + * const arr: number[] = []; + * forEachRight([1, 2, 3, 4], (i) => arr.push(i + 1)); + * isEqual(arr, [5, 4, 3, 2]); // true + * + * const result: any = {}; + * forEachRight(createArray({ len: 20 }), (v, k) => { + * result[k] = v; + * if (k === 10) return false; + * return; + * }); + * isEqual(result, + * createArray({ start: 10, end: 20 }).reduce((obj, v) => { + * obj[v] = v; + * return obj; + * }, {} as Record), + * )); // true + * + * const result2: any[] = []; + * forEachRight(createArray({ len: 20 }), (v, k) => { + * result2.push({ [k]: v }); + * if (k === 15) return false; + * return; + * }); + * + * isEqual(result2, [{ 19: 19 }, { 18: 18 }, { 17: 17 }, { 16: 16 }, { 15: 15 }]); // true + * + * let elseCount = 0; + * const isDone = forEachRight( + * arr, + * () => {}, + * () => elseCount++, // 完整遍历以后会执行该方法 + * ); + * isDone; // true + * elseCount; // 1 + */ +export function forEachRight( + arr: ArrayLike, + callbackFn: (value: T, index: number, array: ArrayLike) => false | any, + elseCB?: () => void, +): boolean { + for (let i = arr.length - 1; i > -1; i--) { + if (callbackFn(arr[i] as T, i, arr) === false) return false; + } + elseCB && elseCB(); + return true; +} diff --git a/src/array/common/getYangHuiTriangle.ts b/src/array/common/getYangHuiTriangle.ts new file mode 100644 index 00000000..b72599dd --- /dev/null +++ b/src/array/common/getYangHuiTriangle.ts @@ -0,0 +1,30 @@ +/** + * 获取num阶杨辉三角 + * + * @example + * + * // [1], + * // [1, 1], + * // [1, 2, 1], + * // [1, 3, 3, 1], + * // [1, 4, 6, 4, 1], + * // [1, 5, 10, 10, 5, 1] + * getYangHuiTriangle(6); + * + * @param num 阶数 + */ +export function getYangHuiTriangle(num: number): number[][] { + const result: number[][] = [[1]]; + if (num === 1) return result; + result.push([1, 1]); + for (let i = 3; i <= num; i++) { + const cur: number[] = []; + const prev = result[result.length - 1] as number[]; + cur[0] = cur[i - 1] = 1; + for (let k = 1; k < i - 1; k++) { + cur[k] = (prev[k - 1] as number) + (prev[k] as number); + } + result.push(cur); + } + return result; +} diff --git a/src/array/common/getYangHuiTriangleOne.ts b/src/array/common/getYangHuiTriangleOne.ts new file mode 100644 index 00000000..d17f52d1 --- /dev/null +++ b/src/array/common/getYangHuiTriangleOne.ts @@ -0,0 +1,24 @@ +/** + * 获取num阶杨辉三角 + * + * @example + * + * getYangHuiTriangleOne(6); // [1, 5, 10, 10, 5, 1] + * getYangHuiTriangleOne(10); // [1, 9, 36, 84, 126, 126, 84, 36, 9, 1] + * + * @param num 阶数 + */ +export function getYangHuiTriangleOne(num: number): number[] { + if (num < 1) return []; + if (num === 1) return [1]; + const result: number[] = []; + result[0] = result[1] = 1; + for (let i = 3; i <= num; i++) { + const prev = result.slice(); + result[0] = result[i - 1] = 1; + for (let j = 1; j < i - 1; j++) { + result[j] = (prev[j - 1] as number) + (prev[j] as number); + } + } + return result; +} diff --git a/src/array/common/groupBy.ts b/src/array/common/groupBy.ts new file mode 100644 index 00000000..280a0141 --- /dev/null +++ b/src/array/common/groupBy.ts @@ -0,0 +1,128 @@ +import { isFunction } from '../../data-type'; + +/** + * 数组分组 + * + * 注意:该重载默认查找 item 对象的 key 而不是 item + * + * @example + * groupBy([{type: 1}, {type: 2}], "type") // returns {1: [{type: 1}], 2: [{type: 2}]} + * // 找不到对应key的分到'*'组 + * groupBy([{type: 1}, {value: 2}], "type") // returns {"*": [{value: 2}], 1: [{type: 1}]} + * + * + * groupBy([{ type: 1 }, { type: 2 }], 'type'); // { 1: [{ type: 1 }], 2: [{ type: 2 }]} + * + * groupBy( + * [ + * { type: 1, value: 111 }, + * { type: 2, value: 222 }, + * { type: 1, value: 222 }, + * { type: 2, value: 33344 }, + * { type: 1, value: 333 }, + * { type: 1, value: 444 }, + * ], + * 'type' + * ); + * // { + * // 1: [ + * // { type: 1, value: 111 }, + * // { type: 1, value: 222 }, + * // { type: 1, value: 333 }, + * // { type: 1, value: 444 }, + * // ], + * // 2: [ + * // { type: 2, value: 222 }, + * // { type: 2, value: 33344 }, + * // ], + * // }; + * + * groupBy([], ''); // {} + * groupBy([], undefined as any); // {} + * groupBy([{ type: 1 }, { type: 2 }], undefined as any); // { '*': [{ type: 1 }, { type: 2 }]} + * groupBy([{ type: 1 }, { value: 2 }], 'type'); // { '*': [{ value: 2 }], 1: [{ type: 1 }] } + * + * // 默认 '*' 组 改为 'other' 组 + * groupBy([{ type: 1 }, { value: 2 }], 'type', 'other'); // {other: [{ value: 2 }],1: [{ type: 1 }] } + * + * + * @param arr 数组 + * @param key 如果 item 中不存在该 key,那么该 item 会归类到 defaultKey + * @param [defaultKey='*'] 所有未归类的 item 都会归类到 defaultKey + */ +export function groupBy< + const T extends Record, + K extends keyof T, + D extends string = '*', +>(arr: ArrayLike, key: K, defaultKey?: D): Partial>; + +/** + * 数组分组 + * + * @example + * + * groupBy( + * [ + * { name: 'a', score: 50 }, + * { name: 'b', score: 90 }, + * { name: 'c', score: 70 }, + * { name: 'd', score: 10 }, + * { name: 'e', score: 100 }, + * ], + * (item) => { + * const score = item.score; + * if (score >= 90) return 'A'; + * if (score >= 60) return 'B'; + * return 'C'; + * }, + * ); + * // result + * // { + * // A: [{ name: 'b', score: 90 }, { name: 'e', score: 100 }], + * // B: [{ name: 'c', score: 70 }], + * // C: [{ name: 'a', score: 50 }, { name: 'd', score: 10 }], + * // } + * + * groupBy([50, 90, 70, 10, 100], (score) => { + * if (score >= 90) return 'A'; + * if (score >= 60) return 'B'; + * return 'C'; + * }); // {A:[90, 100], B:[70], C:[50, 10]}; + * // 约等于 + * groupBy( + * [50, 90, 70, 10, 100], + * (score): string | void => { + * if (score >= 90) return 'A'; + * if (score >= 60) return 'B'; + * }, + * 'C', + * ),; // {A:[90, 100], B:[70], C:[50, 10]}; + * + * @param arr 数组 + * @param by 归类回调;如果返回值为空则会归类到 defaultKey + * @param [defaultKey='*'] 所有未归类的 item 都会归类到 defaultKey + */ +export function groupBy< + T, + B extends (it: T, result: Partial>) => string | void, + D extends string = '*', +>(arr: ArrayLike, by: B, defaultKey?: D): Partial, void> | D, T[]>>; + +export function groupBy( + arr: ArrayLike, + key: Function | string, + defaultKey: number | string = '*', +): Record { + const getItemKey = isFunction(key) ? key : (item: Record) => item[key]; + const result: Record = {}; + + for (let i = 0, len = arr.length; i < len; i++) { + const item = arr[i]; + const k = getItemKey(item, result) ?? defaultKey; + const v = result[k]; + if (v) v.push(item); + else result[k] = [item]; + } + + return result; +} diff --git a/src/array/common/inRange.ts b/src/array/common/inRange.ts new file mode 100644 index 00000000..9610cc7d --- /dev/null +++ b/src/array/common/inRange.ts @@ -0,0 +1,20 @@ +/** + * 判断min <= num <= max + * + * @example + * + * inRange(0, [undefined as any, 100]); // true + * inRange(0, [0]); // true + * inRange(0, [1]); // false + * inRange(0, [1, 2]); // false + * + * @param value + * @param [min = Number.MIN_SAFE_INTEGER] + * @param [max = Number.MAX_SAFE_INTEGER] + */ +export function inRange( + value: number, + [min = -Infinity, max = Infinity]: readonly [number?, number?], +): boolean { + return min <= value && value <= max; +} diff --git a/src/array/common/inRanges.ts b/src/array/common/inRanges.ts new file mode 100644 index 00000000..50cb386e --- /dev/null +++ b/src/array/common/inRanges.ts @@ -0,0 +1,24 @@ +import { inRange } from './inRange'; + +/** + * inRange的复数版 + * + * @see inRange + * + * @example + * + * inRanges(0, [undefined as any, 100]); // true + * inRanges(0, [0]); // true + * inRanges(0, [1]); // false + * inRanges(0, [1, 2]); // false + * + * inRanges(0, [1, 2], [-9, -1]); // false + * inRanges(-9, [1, 2], [-9, -1]); // true + * inRanges(-1, [1, 2], [-9, -1]); // true + * inRanges(-10, [1, 2], [-9, -1]); // false + * inRanges(-10, [1, 2], [-9, -1], [-20, -10]); // true + * inRanges(0, [1, 2], [-9, -1]); // false + */ +export function inRanges(value: number, ...ranges: [number?, number?][]): boolean { + return ranges.some((item) => inRange(value, item)); +} diff --git a/src/array/common/index.ts b/src/array/common/index.ts new file mode 100644 index 00000000..0140644a --- /dev/null +++ b/src/array/common/index.ts @@ -0,0 +1,24 @@ +export * from './createArray'; +export * from './forEach'; +export * from './forEachRight'; +export * from './castArray'; +export * from './findIndex'; +export * from './findIndexRight'; +export * from './binaryFindIndex'; +export * from './binaryFind'; +export * from './insertToArray'; +export * from './arrayRemoveItem'; +export * from './arrayRemoveItemsBy'; +export * from './unique'; +export * from './chunk'; +export * from './inRange'; +export * from './inRanges'; +export * from './groupBy'; +export * from './someInList'; +export * from './sum'; +export * from './avg'; +export * from './getYangHuiTriangleOne'; +export * from './getYangHuiTriangle'; +export * from './forEachAround'; +export type * from './types'; +export * from './joinArray'; diff --git a/src/array/common/insertToArray.ts b/src/array/common/insertToArray.ts new file mode 100644 index 00000000..9abf255f --- /dev/null +++ b/src/array/common/insertToArray.ts @@ -0,0 +1,228 @@ +import type { InsertToArrayToCBOptions } from './types'; +import { findIndexRight } from './findIndexRight'; +import { isFunction } from '../../data-type'; +import { castArray } from './castArray'; +import { findIndex } from './findIndex'; + +/** + * item插入到数组,在原数组中改变 + * + * 插入单个,静态目标 + * + * @example + * + * let arr: number[]; + * + * // 插入单个 静态位置 + * arr = [1, 2, 3, 2]; + * insertToArray(5, 1, arr); // 1 + * arr; // [1, 5, 2, 3, 2] + * // 恢复 + * arr = [1, 2, 3, 2]; + * // 插到目标位置后面 + * insertToArray(5, 1, arr, { after: true }); // 2 + * arr; // [1, 2, 5, 3, 2] + * // 恢复 + * arr = [1, 2, 3, 2]; + * // 负号位置 + * insertToArray(5, -1, arr, { after: false }); // 3 + * arr; // [1, 2, 3, 5, 2] + * + * @param insert 插入的item + * @param to 要插入的位置 + * @param array 要插入item的数组 + * @param param 可选参数 + * @param param.after 默认插到前面去 + * @returns 实际插入的位置 + */ +export function insertToArray( + insert: T, + to: number, + array: T[], + param?: { + /** + * 插入位置前后,true为后 + */ + after?: boolean; + }, +): number; +/** + * item插入到数组,在原数组中改变 + * + * 插入多个,静态目标 + * + * @example + * + * // 插入多个 静态位置 + * arr = [1, 2, 3, 2]; + * insertToArray([5, 6], 1, arr); // 1 + * arr; // [1, 5, 6, 2, 3, 2] + * // 恢复 + * arr = [1, 2, 3, 2]!; + * // 插到目标位置后面 + * insertToArray([5, 6], 1, arr, { after: true }); // 2 + * arr; // [1, 2, 5, 6, 3, 2] + * // 恢复 + * arr = [1, 2, 3, 2]; + * // 负号位置 + * insertToArray([5, 6], -1, arr, { after: false }); // 3 + * arr; // [1, 2, 3, 5, 6, 2] + * + * @param inserts 插入的items + * @param to 要插入的位置 + * @param array 要插入item的数组 + * @param param 可选参数 + * @param param.after 默认插到前面去 + * @returns 实际插入的位置 + */ +export function insertToArray( + inserts: T[], + to: number, + array: T[], + param?: { + /** + * 插入位置前后,true为后 + */ + after?: boolean; + }, +): number; +/** + * item插入到数组,在原数组中改变 + * + * 插入单个,动态目标 + * + * @example + * + * // 插入单个 动态位置 + * arr = [1, 2, 3, 2]; + * insertToArray(5, (o) => o.item === 2, arr); // 1 + * arr; // [1, 5, 2, 3, 2] + * // 恢复 + * arr = [1, 2, 3, 2]; + * // 插到目标位置后面 + * insertToArray(5, (o) => o.item === 2, arr, { after: true }); // 2 + * arr; // [1, 2, 5, 3, 2] + * // 恢复 + * arr = [1, 2, 3, 2]; + * // 反向查找 + * insertToArray(5, (o) => o.item === 2, arr, { after: false, reverse: true }); // 3 + * arr; // [1, 2, 3, 5, 2] + * + * @param insert 插入的item + * @param toCB 查找要插入的位置回调 + * @param array 要插入item的数组 + * @param param 可选参数 + * @param param.after 默认插到前面去 + * @param param.reverse 是否反向遍历 + * @returns 实际插入的位置 + */ +export function insertToArray( + insert: T, + toCB: (options: Omit, 'inserts'>) => boolean, + array: T[], + param?: { + /** + * 从前还是从后查起,true为前 + */ + reverse?: boolean; + /** + * 插入位置前后,true为后 + */ + after?: boolean; + }, +): number; +/** + * item插入到数组,在原数组中改变 + * + * 插入多个,动态目标 + * + * @example + * + * // 插入多个个 动态位置 + * arr = [1, 2, 3, 2]; + * insertToArray([5, 5], (o) => o.item === 2, arr); // 1 + * arr; // [1, 5, 5, 2, 3, 2] + * // 恢复 + * arr = [1, 2, 3, 2]; + * // 插到目标位置后面 + * insertToArray([5, 5], (o) => o.item === 2, arr, { after: true }); // 2 + * arr; // [1, 2, 5, 5, 3, 2] + * // 恢复 + * arr = [1, 2, 3, 2]; + * // 反向查找 + * insertToArray([5, 5], (o) => o.item === 2, arr, { reverse: true }); // 3 + * arr; // [1, 2, 3, 5, 5, 2] + * + * @param inserts 插入的item + * @param toCB 查找要插入的位置回调 + * @param array 要插入item的数组 + * @param param 可选参数 + * @param param.after 默认插到前面去 + * @param param.reverse 是否反向遍历 + * @returns 实际插入的位置 + */ +export function insertToArray( + inserts: T[], + toCB: (options: Omit, 'insert'>) => boolean, + array: T[], + param?: { + /** + * 从前还是从后查起,true为前 + */ + reverse?: boolean; + /** + * 插入位置前后,true为后 + */ + after?: boolean; + }, +): number; +/** + * item插入到数组,在原数组中改变 + * @param insert 插入的item + * @param to 要插入的位置 如果to是函数的话没有找到则不会插进数组 + * @param array 要插入item的数组 + * @param option + * @param option.after 默认插到前面去 + * @param option.reverse 是否反向遍历 + * @returns 实际插入的位置 + */ +export function insertToArray( + insert: unknown, + to: Function | number, + array: unknown[], + { reverse = false, after = false } = {}, +): number { + const inserts = castArray(insert) as unknown[]; + let index = to as number; + if (isFunction(to)) { + index = (reverse ? findIndexRight : findIndex)(array, (v, k, a) => { + const _options = { + index: k, + array: a, + item: v, + }; + const options = Array.isArray(insert) + ? ({ + ..._options, + inserts: insert as any[], + } as Omit) + : ({ + ..._options, + insert, + } as Omit); + return to(options); + }); + if (index === -1) { + return -1; + } + } else { + if (to < 0) { + index = array.length + to; + } else if (to > array.length) { + index = array.length - (after ? 1 : 0); + } + } + after && index++; + array.splice(index, 0, ...inserts); + return index; +} diff --git a/src/array/common/joinArray.ts b/src/array/common/joinArray.ts new file mode 100644 index 00000000..6c5bfd1b --- /dev/null +++ b/src/array/common/joinArray.ts @@ -0,0 +1,55 @@ +import { isFunction } from '../../data-type'; + +/** + * 添加元素到数组缝隙中 + * + * 类似Array.prototype.join, + * 与join合成string不同的是joinToArray是加入到数组中, + * 该方法不对原数组操作 + * + * @override ## separator为固定值 + * + * @example + * + * joinArray([1, 2, 3], 0); // [1, 0, 2, 0, 3] + * joinArray([1], 0); // [1] + * joinArray([1, 2], 0); // [1, 0, 2] + * joinArray([1, 2, 3], 'a'); // [1, 'a', 2, 'a', 3] + * + */ +export function joinArray( + arr: ArrayLike, + separator: T, + callbackFn?: (item: T, index: number) => T, +): T[]; +/** + * @override ## separator为回调函数 + * + * @example + * + * joinArray([1, 2, 3], (i) => i + 10); // [1, 11, 2, 13, 3] + * + */ +export function joinArray( + arr: ArrayLike, + getSeparator: (index: number) => T, + callbackFn?: (item: T, index: number) => T, +): T[]; +export function joinArray( + arr: ArrayLike, + separator: unknown, + callbackFn: (item: unknown, index: number) => unknown = (it) => it, +): unknown[] { + const len = arr.length; + if (!len) return []; + + const res: unknown[] = [callbackFn(arr[0], 0)]; + + const cb = isFunction<(index: number) => unknown>(separator) ? separator : () => separator; + for (let i = 1; i < len; i++) { + const index = res.length; + res.push(cb(index), callbackFn(arr[i], index + 1)); + } + + return res; +} diff --git a/src/array/common/someInList.ts b/src/array/common/someInList.ts new file mode 100644 index 00000000..e1122138 --- /dev/null +++ b/src/array/common/someInList.ts @@ -0,0 +1,24 @@ +/** + * 查找是否items中任何一个在list中 + * + * @example + * + * someInList([0, 20, 100], [...Array(10).keys()]); // true + * + * someInList([500, 20], Array.from({ length: 10 })); // false + * + * someInList([{ id: 1 }], [{ id: 1 }, { id: 2 }, { id2: 3 }]); // false + * + * const list = [{ id: 1 }, { id: 2 }, { id: 3 }]; + * someInList([{ id: 1 }], list, (item, _i, list) => list.some((s) => s.id === item.id)),; // true + * + */ +export function someInList( + items: T[], + list: T[], + cb: (item: T, index: number, list: T[]) => boolean = (v, _, arr) => arr.includes(v), +): boolean { + return items.some((item, index) => { + return cb(item, index, list); + }); +} diff --git a/src/array/common/sum.ts b/src/array/common/sum.ts new file mode 100644 index 00000000..35e5b251 --- /dev/null +++ b/src/array/common/sum.ts @@ -0,0 +1,11 @@ +/** + * 数组求和 + * + * @example + * + * sum([0, 20, 100]); // 120 + * sum([-10, 20, 100]); // 110 + */ +export function sum(arr: number[]): number { + return arr.reduce((res, item) => item + res, 0); +} diff --git a/src/array/common/types.ts b/src/array/common/types.ts new file mode 100644 index 00000000..7795398d --- /dev/null +++ b/src/array/common/types.ts @@ -0,0 +1,10 @@ +/** + * insertToArray函数回调参数类型声明 + */ +export interface InsertToArrayToCBOptions { + index: number; + inserts: T[]; + array: T[]; + insert: T; + item: T; +} diff --git a/src/array/common/unique.ts b/src/array/common/unique.ts new file mode 100644 index 00000000..eb511cf8 --- /dev/null +++ b/src/array/common/unique.ts @@ -0,0 +1,33 @@ +import { isNaN } from '../../data-type'; + +/** + * 数组去重函数 + * + * @example + * + * unique([1, 1, 2, 1, 3, 4, 1, 1, 1, 1, 1]); // [1, 2, 3, 4] + * unique([1, 2, 3, 4]); // [1, 2, 3, 4] + * unique([NaN, null, undefined, '']); // [NaN, null, undefined, ''] + * unique([undefined, undefined, '']); // [undefined, ''] + * unique([NaN, NaN]); // [NaN] + * unique([NaN, NaN], (a, b) => Number.isNaN(a) && Number.isNaN(b)); // [NaN] + * const a = { value: 1 }; + * const b = { value: 2 }; + * const c = { value: 3 }; + * const d = { value: 2 }; + * unique([a, b, c, d]); // [a, b, c, d] + * unique([]); // [] + * unique([a, b, c, d], (v1, v2) => v1.value === v2.value); // [a, b, c] + * + */ +export function unique(target: T[], isRepeatFn?: (value: T, value2: T) => boolean) { + if (!target.length) return target; + const fn = isRepeatFn || ((v1, v2) => v1 === v2 || (isNaN(v1) && isNaN(v2))); + const result = [target[0] as T]; + for (let i = 1, len = target.length; i < len; i++) { + const item = target[i] as T; + if (result.some((resItem) => fn(resItem, item))) continue; + result.push(item); + } + return result; +} diff --git a/src/base64/arrayBufferToBase64.ts b/src/base64/arrayBufferToBase64.ts new file mode 100644 index 00000000..72c05865 --- /dev/null +++ b/src/base64/arrayBufferToBase64.ts @@ -0,0 +1,18 @@ +import { arrayBufferToString } from '../array-buffer'; + +/** + * 把 ArrayBuffer 转成 base64 + * + * 可与 base64ToArrayBuffer 互相转换 + * + * @see base64ToArrayBuffer + * + * @example + * const str = JSON.stringify({ hello: 'world' }, null, 2); + * const buffer = stringToArrayBuffer(str, 8); + * arrayBufferToBase64(buffer); // 'ewogICJoZWxsbyI6ICJ3b3JsZCIKfQ==' + */ +export function arrayBufferToBase64(buffer: ArrayBuffer): string { + // return btoa(String.fromCharCode(...new Uint8Array(buffer))); + return btoa(arrayBufferToString(buffer, 8)); +} diff --git a/src/base64/base64ToArrayBuffer.ts b/src/base64/base64ToArrayBuffer.ts new file mode 100644 index 00000000..545d2885 --- /dev/null +++ b/src/base64/base64ToArrayBuffer.ts @@ -0,0 +1,18 @@ +import { parseBase64 } from './parseBase64'; + +/** + * 把 base64 转成 ArrayBuffer + * + * 可与 arrayBufferToBase64 互相转换 + * + * @see arrayBufferToBase64 + * @see parseBase64 + * + * @example + * const base64 = 'data:application/json;base64,ewogICJoZWxsbyI6ICJ3b3JsZCIKfQ=='; + * const buffer = base64ToArrayBuffer(base64); + * arrayBufferToBase64(buffer); // base64.split(',')[1] + */ +export function base64ToArrayBuffer(base64: string): ArrayBuffer { + return parseBase64(base64).uint8Array.buffer; +} diff --git a/src/base64/index.ts b/src/base64/index.ts new file mode 100644 index 00000000..e1547874 --- /dev/null +++ b/src/base64/index.ts @@ -0,0 +1,3 @@ +export * from './parseBase64'; +export * from './arrayBufferToBase64'; +export * from './base64ToArrayBuffer'; diff --git a/src/base64/parseBase64.ts b/src/base64/parseBase64.ts new file mode 100644 index 00000000..7297a536 --- /dev/null +++ b/src/base64/parseBase64.ts @@ -0,0 +1,37 @@ +import type { TupleM2N } from '@tool-pack/types'; + +/** + * 解析base64的mime和uint8Array + * + * + * @example + * + * // { hello: 'world' } + * const p = parseBase64('data:application/json;base64,ewogICJoZWxsbyI6ICJ3b3JsZCIKfQ=='); + * p.mime; // 'application/json' + * String.fromCodePoint(...p.uint8Array); // '{\n "hello": "world"\n}' + */ +export function parseBase64(base64: string): { + uint8Array: Uint8Array; + mime: string; +} { + const [mime, body] = splitBase64(base64); + let len = body.length; + const uint8Array = new Uint8Array(len); + while (len--) uint8Array[len] = body.charCodeAt(len); + return { uint8Array, mime }; +} +function splitBase64(base64: string): [mime: string, body: string] { + const split = base64.split(',') as TupleM2N; + let mime = ''; + let body = ''; + + if (split.length === 1) { + body = split[0]; + } else { + mime = (split[0].match(/:(.*?);/) ?? [])[1] as string; + body = split[1]; + } + + return [mime, atob(body)]; +} diff --git a/src/bezier/base/bezier2.ts b/src/bezier/base/bezier2.ts new file mode 100644 index 00000000..c2679dd6 --- /dev/null +++ b/src/bezier/base/bezier2.ts @@ -0,0 +1,13 @@ +import { strip } from '../../number'; + +/** + * 2阶贝塞尔曲线 + * + * @param t 百分比 [0, 1] + * @param v1 值1 + * @param cv 控制值 + * @param v2 值2 + */ +export function bezier2(t: number, v1: number, cv: number, v2: number): number { + return strip((1 - t) * (1 - t) * v1 + 2 * t * (1 - t) * cv + t * t * v2); +} diff --git a/src/bezier/base/bezier3.ts b/src/bezier/base/bezier3.ts new file mode 100644 index 00000000..e3d88f19 --- /dev/null +++ b/src/bezier/base/bezier3.ts @@ -0,0 +1,19 @@ +import { strip } from '../../number'; + +/** + * 3阶贝塞尔曲线公式 + * + * @param t 百分比 [0, 1] + * @param v1 值1 + * @param cv1 控制值1 + * @param cv2 控制值2 + * @param v2 值2 + */ +export function bezier3(t: number, v1: number, cv1: number, cv2: number, v2: number): number { + return strip( + v1 * (1 - t) * (1 - t) * (1 - t) + + 3 * cv1 * t * (1 - t) * (1 - t) + + 3 * cv2 * t * t * (1 - t) + + v2 * t * t * t, + ); +} diff --git a/src/bezier/base/index.ts b/src/bezier/base/index.ts new file mode 100644 index 00000000..085a9fc6 --- /dev/null +++ b/src/bezier/base/index.ts @@ -0,0 +1,3 @@ +export * from './bezier2'; +export * from './bezier3'; +export * from './useCubicBezier3'; diff --git a/src/bezier/base.ts b/src/bezier/base/useCubicBezier3.ts similarity index 72% rename from src/bezier/base.ts rename to src/bezier/base/useCubicBezier3.ts index 127183bf..69e19ee9 100644 --- a/src/bezier/base.ts +++ b/src/bezier/base/useCubicBezier3.ts @@ -1,43 +1,5 @@ -import { strip } from '../number'; -import { Tuple } from '@tool-pack/types'; - -/** - * 2阶贝塞尔曲线 - * - * @param t 百分比 [0, 1] - * @param v1 值1 - * @param cv 控制值 - * @param v2 值2 - */ -export function bezier2(t: number, v1: number, cv: number, v2: number): number { - return strip((1 - t) * (1 - t) * v1 + 2 * t * (1 - t) * cv + t * t * v2); -} - -/** - * 3阶贝塞尔曲线公式 - * - * @param t 百分比 [0, 1] - * @param v1 值1 - * @param cv1 控制值1 - * @param cv2 控制值2 - * @param v2 值2 - */ -export function bezier3(t: number, v1: number, cv1: number, cv2: number, v2: number): number { - return strip( - v1 * (1 - t) * (1 - t) * (1 - t) + - 3 * cv1 * t * (1 - t) * (1 - t) + - 3 * cv2 * t * t * (1 - t) + - v2 * t * t * t, - ); -} - -const predefined = { - ease: '.25,.1,.25,1', - linear: '0,0,1,1', - 'ease-in': '.42,0,1,1', - 'ease-out': '0,0,.58,1', - 'ease-in-out': '.42,0,.58,1', -}; +import type { Tuple } from '@tool-pack/types'; +import { strip } from '../../number'; /** * 使用3阶贝塞尔曲线缓动函数 @@ -53,7 +15,6 @@ export function useCubicBezier3( ): (t: number) => number { const fn = typeof tm === 'string' ? (predefined[tm].split(',').map(Number) as Tuple) : tm; - const [a, b, c, d] = fn; // 原文:https://zhuanlan.zhihu.com/p/60193908 @@ -69,9 +30,7 @@ export function useCubicBezier3( const epsilon = 1e-7; // 目标精度 const getX = (t: number) => ((px1 * t + px2) * t + px3) * t; - const getY = (t: number) => ((py1 * t + py2) * t + py3) * t; - const solve = function (x: number): number { if (x === 0 || x === 1) { // 对 0 和 1 两个特殊 t 不做计算 @@ -96,8 +55,15 @@ export function useCubicBezier3( }; const distance = Math.abs(v2 - v1); - return v1 > v2 ? (t: number): number => strip(distance - solve(t) * distance) : (t: number): number => strip(solve(t) * distance); } + +const predefined = { + 'ease-in-out': '.42,0,.58,1', + 'ease-out': '0,0,.58,1', + 'ease-in': '.42,0,1,1', + ease: '.25,.1,.25,1', + linear: '0,0,1,1', +}; diff --git a/src/bezier/point.ts b/src/bezier/point.ts deleted file mode 100644 index 64240eae..00000000 --- a/src/bezier/point.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { Point } from '../coordinate'; -import { bezier2, bezier3 } from './base'; -import { getYangHuiTriangleOne } from '../array'; -import { strip } from '../number'; - -/** - * 生成二阶贝塞尔曲线路径点 - * - * @example - * - * const bezierList = createArray({ - * start: 0, - * end: 11, - * fill: (i) => pointBezier2(i / 10, [1, 1], [10, 10], [10, 10]), - * }); - * - * // [ - * // [1, 1], - * // [2.71, 2.71], - * // [4.24, 4.24], - * // [5.59, 5.59], - * // [6.76, 6.76], - * // [7.75, 7.75], - * // [8.56, 8.56], - * // [9.19, 9.19], - * // [9.64, 9.64], - * // [9.91, 9.91], - * // [10, 10], - * // ] - * bezierList; - * - * @param t 当前百分比,范围:0-1 - * @param startPos 起点坐标 - * @param controlPoint 控制点 - * @param endPos 终点坐标 - */ -export function pointBezier2( - t: number, - startPos: Point, - controlPoint: Point, - endPos: Point, -): Point { - const [x1, y1] = startPos; - const [cx, cy] = controlPoint; - const [x2, y2] = endPos; - // const x = (1 - t) * (1 - t) * x1 + 2 * t * (1 - t) * cx + t * t * x2; - // const y = (1 - t) * (1 - t) * y1 + 2 * t * (1 - t) * cy + t * t * y2; - return [bezier2(t, x1, cx, x2), bezier2(t, y1, cy, y2)]; -} - -/** - * 三阶贝塞尔 - * - * @example - * - * const bezierList = createArray({ - * start: 0, - * end: 11, - * fill: (i) => Bezier.pointBezier3(i / 10, [1, 1], [2, 2], [8, 8], [10, 10]), - * }); - * - * // [ - * // [1, 1], - * // [1.441, 1.441], - * // [2.128, 2.128], - * // [3.007, 3.007], - * // [4.024, 4.024], - * // [5.125, 5.125], - * // [6.256, 6.256], - * // [7.363, 7.363], - * // [8.392, 8.392], - * // [9.289, 9.289], - * // [10, 10], - * // ]; - * bezierList; - * - * @param t 当前百分比 - * @param startPos 起点坐标 - * @param controlPoint1 控制点1 - * @param controlPoint2 控制点2 - * @param endPos 终点坐标 - */ -export function pointBezier3( - t: number, - startPos: Point, - controlPoint1: Point, - controlPoint2: Point, - endPos: Point, -) { - const [x1, y1] = startPos; - const [x2, y2] = endPos; - const [cx1, cy1] = controlPoint1; - const [cx2, cy2] = controlPoint2; - - return [bezier3(t, x1, cx1, cx2, x2), bezier3(t, y1, cy1, cy2, y2)]; -} - -/** - * n阶贝塞尔曲线 - * --- - * 由于要取杨辉三角以及累加,性能没有固定阶数的好 - * - * @param t 百分比 - * @param points 贝塞尔曲线控制点坐标 - */ -export function pointBezierN(t: number, ...points: Point[]): Point | null { - const len = points.length; - - if (len < 2) { - return null; - } - - const yh = getYangHuiTriangleOne(len); - - let x = 0; - let y = 0; - - points.forEach((point, i) => { - const yhItem = yh[i] as number; - x += Math.pow(1 - t, len - i - 1) * point[0] * Math.pow(t, i) * yhItem; - y += Math.pow(1 - t, len - i - 1) * point[1] * Math.pow(t, i) * yhItem; - }); - - return [strip(x), strip(y)]; -} diff --git a/src/bezier/point/index.ts b/src/bezier/point/index.ts new file mode 100644 index 00000000..1a3e1031 --- /dev/null +++ b/src/bezier/point/index.ts @@ -0,0 +1,3 @@ +export * from './pointBezier2'; +export * from './pointBezier3'; +export * from './pointBezierN'; diff --git a/src/bezier/point/pointBezier2.ts b/src/bezier/point/pointBezier2.ts new file mode 100644 index 00000000..46fdca61 --- /dev/null +++ b/src/bezier/point/pointBezier2.ts @@ -0,0 +1,47 @@ +import type { Point } from '@tool-pack/types'; +import { bezier2 } from '../base'; + +/** + * 生成二阶贝塞尔曲线路径点 + * + * @example + * + * const bezierList = createArray({ + * start: 0, + * end: 11, + * fill: (i) => pointBezier2(i / 10, [1, 1], [10, 10], [10, 10]), + * }); + * + * // [ + * // [1, 1], + * // [2.71, 2.71], + * // [4.24, 4.24], + * // [5.59, 5.59], + * // [6.76, 6.76], + * // [7.75, 7.75], + * // [8.56, 8.56], + * // [9.19, 9.19], + * // [9.64, 9.64], + * // [9.91, 9.91], + * // [10, 10], + * // ] + * bezierList; + * + * @param t 当前百分比,范围:0-1 + * @param startPos 起点坐标 + * @param controlPoint 控制点 + * @param endPos 终点坐标 + */ +export function pointBezier2( + t: number, + startPos: Point, + controlPoint: Point, + endPos: Point, +): Point { + const [x1, y1] = startPos; + const [cx, cy] = controlPoint; + const [x2, y2] = endPos; + // const x = (1 - t) * (1 - t) * x1 + 2 * t * (1 - t) * cx + t * t * x2; + // const y = (1 - t) * (1 - t) * y1 + 2 * t * (1 - t) * cy + t * t * y2; + return [bezier2(t, x1, cx, x2), bezier2(t, y1, cy, y2)]; +} diff --git a/src/bezier/point/pointBezier3.ts b/src/bezier/point/pointBezier3.ts new file mode 100644 index 00000000..8f4b9996 --- /dev/null +++ b/src/bezier/point/pointBezier3.ts @@ -0,0 +1,48 @@ +import type { Point } from '@tool-pack/types'; +import { bezier3 } from '../base'; + +/** + * 三阶贝塞尔 + * + * @example + * + * const bezierList = createArray({ + * start: 0, + * end: 11, + * fill: (i) => Bezier.pointBezier3(i / 10, [1, 1], [2, 2], [8, 8], [10, 10]), + * }); + * + * // [ + * // [1, 1], + * // [1.441, 1.441], + * // [2.128, 2.128], + * // [3.007, 3.007], + * // [4.024, 4.024], + * // [5.125, 5.125], + * // [6.256, 6.256], + * // [7.363, 7.363], + * // [8.392, 8.392], + * // [9.289, 9.289], + * // [10, 10], + * // ]; + * bezierList; + * + * @param t 当前百分比 + * @param startPos 起点坐标 + * @param controlPoint1 控制点1 + * @param controlPoint2 控制点2 + * @param endPos 终点坐标 + */ +export function pointBezier3( + t: number, + startPos: Point, + controlPoint1: Point, + controlPoint2: Point, + endPos: Point, +) { + const [x1, y1] = startPos; + const [x2, y2] = endPos; + const [cx1, cy1] = controlPoint1; + const [cx2, cy2] = controlPoint2; + return [bezier3(t, x1, cx1, cx2, x2), bezier3(t, y1, cy1, cy2, y2)]; +} diff --git a/src/bezier/point/pointBezierN.ts b/src/bezier/point/pointBezierN.ts new file mode 100644 index 00000000..cb0e5bc3 --- /dev/null +++ b/src/bezier/point/pointBezierN.ts @@ -0,0 +1,27 @@ +import { getYangHuiTriangleOne } from '../../array'; +import type { Point } from '@tool-pack/types'; +import { strip } from '../../number'; + +/** + * n阶贝塞尔曲线 + * --- + * 由于要取杨辉三角以及累加,性能没有固定阶数的好 + * + * @param t 百分比 + * @param points 贝塞尔曲线控制点坐标 + */ +export function pointBezierN(t: number, ...points: Point[]): Point | null { + const len = points.length; + if (len < 2) { + return null; + } + const yh = getYangHuiTriangleOne(len); + let x = 0; + let y = 0; + points.forEach((point, i) => { + const yhItem = yh[i] as number; + x += Math.pow(1 - t, len - i - 1) * point[0] * Math.pow(t, i) * yhItem; + y += Math.pow(1 - t, len - i - 1) * point[1] * Math.pow(t, i) * yhItem; + }); + return [strip(x), strip(y)]; +} diff --git a/src/clone.ts b/src/clone.ts deleted file mode 100644 index 7dc9f726..00000000 --- a/src/clone.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { isBroadlyObj, typeOf } from './data-type'; -import { hasOwn } from './object'; - -/** - * 对函数复制 - * - * 如果要复制函数属性的话,使用deepClone - * - * 只能复制部分函数,部分函数会丢失外部作用域 - * - * @throws 部分环境像electron可能会因为不能使用eval而复制失败 - * - * @example - * - * // 复制普通函数 - * function test(a: number, b: number) { - * return a + b; - * } - * - * cloneFunction(test)(50, 50); // 100 - * - * // 复制箭头函数 - * const test2 = (a: number, b: number) => a + b; - * cloneFunction(test2)(50, 50); // 100 - * - * // 复制匿名函数 - * cloneFunction(function (a: number, b: number) { - * return a + b; - * })(50, 50); // 100 - * - * // 复制非函数 - * cloneFunction(1 as any); // 1 - * - * // ---------- 以上复制正常运行 ---------- - * - * // 复制对象方法 - * const obj: any = { - * a: 1, - * b: 1, - * c: 1, - * fn1() { - * return ++this.a; - * }, - * fn2: () => ++obj.b, - * fn3: function () { - * return ++this.c; - * }, - * }; - * obj.clone1 = cloneFunction(obj.fn1); - * obj.fn1(); // 2 - * obj.clone1(); // 3 - * - * obj.clone2 = cloneFunction(obj.fn2); - * typeof obj.clone2; // 'function' - * obj.clone2()); // throw 'obj is not defined' - * - * obj.clone3 = cloneFunction(obj.fn3); - * obj.clone3(); // 2 - * - * obj.a; // 3 - * obj.b; // 1 - * obj.c; // 2 - * - * // -------- 以上复制除了箭头函数无法访问obj,其他都是正常的 --------- - * - * // 对外部变量对访问 - * const o = { a: 1 }; - * - * const fn = () => o.a; - * cloneFunction(fn)());// throw 'o is not defined'; - * - * cloneFunction(function () { - * return o.a; - * })(), - * ); // throw 'o is not defined' - * - * // --------- 以上复制运行全部出错 ---------- - * - * - */ -export function cloneFunction(fn: T): T { - if (typeOf(fn) !== 'function') return fn; - - let str = fn.toString(); - // fn(){} es6写法的函数要转换成function(){} - str = str.replace(/(function)? ?\w+ ?\(/, 'function('); - // let newFn: any; - // str = "newFn = " + str; - // (0, eval)(str); // 直接使用eval在rollup build的时候会报错 (0, eval)(str)在nodejs里面不会有效 - // return newFn; - - // 用new Function(str)代替eval(str) - return new Function('return ' + str)(); -} - -interface CloneStrategies { - [key: string]: (target: any) => any; -} -const cloneStrategies: CloneStrategies = (function () { - const st = { - array(target: any) { - return new target.constructor(); - }, - function(target: any) { - // 复制的函数作用域不再是原函数的作用域 - // (如复制一个闭包函数,作用域会提升到script顶层,将不能访问原闭包函数外的变量), - // 不再复制函数 - // return cloneFunction(target); - return target; - }, - date(target: any) { - return new target.constructor(target); - }, - }; - const strategies: CloneStrategies = { - ...st, - object: st.array, - regexp: st.date, - }; - - return strategies; -})(); - -/** - * 对象深拷贝办法(深度优先) - * - * @example - * - * const obj = { a: [2, 3], c: 1, d: { f: 123 } }; - * const newObj = deepClone(obj); - * // copy == obj - * isEqual(newObj,obj); // true - * // copy !== obj - * obj === newObj; // false - * // copy.a == obj.a - * isEqual(obj.a,newObj.a); // true - * // copy.a !== obj.a - * obj.a === newObj.a; // false - * - * // 0 === 0 - * deepClone(0); // 0 - * - */ -export function deepClone(target: T): T { - const cache = new Set(); - - function _clone(value: any) { - const type = typeOf(value); - const isObject = isBroadlyObj(value as any); - if (isObject) { - if (cache.has(value)) return value; - // 非引用类型不缓存 - cache.add(value); - } - // 使用策略模式 - const strategies = cloneStrategies[type]; - const result: any = strategies ? strategies(value) : value; - if (['object', 'array', 'function'].indexOf(type) === -1) return result; - const tar: any = value; - // 虽然array使用for i++比for in遍历快,但是如果在数组里面有非number类型的键的话,就无法复制,所以统一用for in遍历 - for (const k in tar) { - //prototype继承的不复制 es6继承的不会被拦截 - if (!hasOwn(tar, k)) continue; - result[k] = _clone(tar[k]); // 递归复制 - } - return result; - } - - return _clone(target); -} - -/** - * 对象深拷贝办法(广度优先) - * - * @example - * - * const obj = { a: [2, 3], c: 1, d: { f: 123 } }; - * const newObj = deepCloneBfs(obj); - * // copy == obj - * isEqual(newObj,obj); // true - * // copy !== obj - * obj === newObj; // false - * // copy.a == obj.a - * isEqual(obj.a,newObj.a); // true - * // copy.a !== obj.a - * obj.a === newObj.a; // false - * - */ -export function deepCloneBfs(target: T): T { - if (typeof target !== 'object' || !target) return target; - type QueItem = [string, any, any]; - const result: any = new (target as any).constructor(); - - function getChildren(tar: object, parent: any) { - for (const k in tar) { - if (!hasOwn(tar, k)) continue; - queue.push([k, tar[k], parent]); - } - } - - const queue: QueItem[] = []; - getChildren(target as any, result); - - while (queue.length) { - const [k, v, parent] = queue.shift() as QueItem; - - const type = typeof v; - // console.log(type); - if (type !== 'object' || v === null) { - parent[k] = v; - continue; - } - - if (parent[k] === undefined) { - parent[k] = new v.constructor(); - } - getChildren(v, parent[k]); - } - return result; -} diff --git a/src/clone/cloneFunction.ts b/src/clone/cloneFunction.ts new file mode 100644 index 00000000..7fe0ebac --- /dev/null +++ b/src/clone/cloneFunction.ts @@ -0,0 +1,92 @@ +import { typeOf } from '../data-type'; + +/** + * 对函数复制 + * + * 如果要复制函数属性的话,使用deepClone + * + * 只能复制部分函数,部分函数会丢失外部作用域 + * + * @throws 部分环境像electron可能会因为不能使用eval而复制失败 + * + * @example + * + * // 复制普通函数 + * function test(a: number, b: number) { + * return a + b; + * } + * + * cloneFunction(test)(50, 50); // 100 + * + * // 复制箭头函数 + * const test2 = (a: number, b: number) => a + b; + * cloneFunction(test2)(50, 50); // 100 + * + * // 复制匿名函数 + * cloneFunction(function (a: number, b: number) { + * return a + b; + * })(50, 50); // 100 + * + * // 复制非函数 + * cloneFunction(1 as any); // 1 + * + * // ---------- 以上复制正常运行 ---------- + * + * // 复制对象方法 + * const obj: any = { + * a: 1, + * b: 1, + * c: 1, + * fn1() { + * return ++this.a; + * }, + * fn2: () => ++obj.b, + * fn3: function () { + * return ++this.c; + * }, + * }; + * obj.clone1 = cloneFunction(obj.fn1); + * obj.fn1(); // 2 + * obj.clone1(); // 3 + * + * obj.clone2 = cloneFunction(obj.fn2); + * typeof obj.clone2; // 'function' + * obj.clone2()); // throw 'obj is not defined' + * + * obj.clone3 = cloneFunction(obj.fn3); + * obj.clone3(); // 2 + * + * obj.a; // 3 + * obj.b; // 1 + * obj.c; // 2 + * + * // -------- 以上复制除了箭头函数无法访问obj,其他都是正常的 --------- + * + * // 对外部变量对访问 + * const o = { a: 1 }; + * + * const fn = () => o.a; + * cloneFunction(fn)());// throw 'o is not defined'; + * + * cloneFunction(function () { + * return o.a; + * })(), + * ); // throw 'o is not defined' + * + * // --------- 以上复制运行全部出错 ---------- + * + * + */ +export function cloneFunction(fn: T): T { + if (typeOf(fn) !== 'function') return fn; + let str = fn.toString(); + // fn(){} es6写法的函数要转换成function(){} + str = str.replace(/(function)? ?\w+ ?\(/, 'function('); + // let newFn: any; + // str = "newFn = " + str; + // (0, eval)(str); // 直接使用eval在rollup build的时候会报错 (0, eval)(str)在nodejs里面不会有效 + // return newFn; + + // 用new Function(str)代替eval(str) + return new Function('return ' + str)(); +} diff --git a/src/clone/deepClone.ts b/src/clone/deepClone.ts new file mode 100644 index 00000000..e6e81abd --- /dev/null +++ b/src/clone/deepClone.ts @@ -0,0 +1,77 @@ +import { isBroadlyObj, typeOf } from '../data-type'; +import { hasOwn } from '../object'; + +/** + * 对象深拷贝办法(深度优先) + * + * @example + * + * const obj = { a: [2, 3], c: 1, d: { f: 123 } }; + * const newObj = deepClone(obj); + * // copy == obj + * isEqual(newObj,obj); // true + * // copy !== obj + * obj === newObj; // false + * // copy.a == obj.a + * isEqual(obj.a,newObj.a); // true + * // copy.a !== obj.a + * obj.a === newObj.a; // false + * + * // 0 === 0 + * deepClone(0); // 0 + * + */ +export function deepClone(target: T): T { + const cache = new Set(); + function _clone(value: any) { + const type = typeOf(value); + const isObject = isBroadlyObj(value as any); + if (isObject) { + if (cache.has(value)) return value; + // 非引用类型不缓存 + cache.add(value); + } + // 使用策略模式 + const strategies = cloneStrategies[type]; + const result: any = strategies ? strategies(value) : value; + if (['object', 'array', 'function'].indexOf(type) === -1) return result; + const tar: any = value; + // 虽然array使用for i++比for in遍历快,但是如果在数组里面有非number类型的键的话,就无法复制,所以统一用for in遍历 + for (const k in tar) { + //prototype继承的不复制 es6继承的不会被拦截 + if (!hasOwn(tar, k)) continue; + result[k] = _clone(tar[k]); // 递归复制 + } + + return result; + } + return _clone(target); +} + +interface CloneStrategies { + [key: string]: (target: any) => any; +} +const cloneStrategies: CloneStrategies = (function () { + const st = { + function(target: any) { + // 复制的函数作用域不再是原函数的作用域 + // (如复制一个闭包函数,作用域会提升到script顶层,将不能访问原闭包函数外的变量), + // 不再复制函数 + // return cloneFunction(target); + return target; + }, + date(target: any) { + return new target.constructor(target); + }, + array(target: any) { + return new target.constructor(); + }, + }; + const strategies: CloneStrategies = { + ...st, + object: st.array, + regexp: st.date, + }; + + return strategies; +})(); diff --git a/src/clone/deepCloneBfs.ts b/src/clone/deepCloneBfs.ts new file mode 100644 index 00000000..be2dbf5d --- /dev/null +++ b/src/clone/deepCloneBfs.ts @@ -0,0 +1,46 @@ +import { hasOwn } from '../object'; + +/** + * 对象深拷贝办法(广度优先) + * + * @example + * + * const obj = { a: [2, 3], c: 1, d: { f: 123 } }; + * const newObj = deepCloneBfs(obj); + * // copy == obj + * isEqual(newObj,obj); // true + * // copy !== obj + * obj === newObj; // false + * // copy.a == obj.a + * isEqual(obj.a,newObj.a); // true + * // copy.a !== obj.a + * obj.a === newObj.a; // false + * + */ +export function deepCloneBfs(target: T): T { + if (typeof target !== 'object' || !target) return target; + type QueItem = [string, any, any]; + const result: any = new (target as any).constructor(); + function getChildren(tar: object, parent: any) { + for (const k in tar) { + if (!hasOwn(tar, k)) continue; + queue.push([k, tar[k], parent]); + } + } + const queue: QueItem[] = []; + getChildren(target as any, result); + while (queue.length) { + const [k, v, parent] = queue.shift() as QueItem; + const type = typeof v; + // console.log(type); + if (type !== 'object' || v === null) { + parent[k] = v; + continue; + } + if (parent[k] === undefined) { + parent[k] = new v.constructor(); + } + getChildren(v, parent[k]); + } + return result; +} diff --git a/src/clone/index.ts b/src/clone/index.ts new file mode 100644 index 00000000..74da96d3 --- /dev/null +++ b/src/clone/index.ts @@ -0,0 +1,3 @@ +export * from './cloneFunction'; +export * from './deepClone'; +export * from './deepCloneBfs'; diff --git a/src/color/RGB.ts b/src/color/RGB.ts index f43b676e..13db397f 100644 --- a/src/color/RGB.ts +++ b/src/color/RGB.ts @@ -1,6 +1,6 @@ -import { Tuple } from '@tool-pack/types'; -import { randomInt } from '../random'; +import type { Tuple } from '@tool-pack/types'; import { isArray } from '../data-type'; +import { randomInt } from '../random'; import { RGBSuper } from './RGBSuper'; import { RGBA } from './RGBA'; @@ -24,11 +24,17 @@ export class RGB extends RGBSuper { } /** - * 随机颜色 + * 从HEX颜色值转换而来 */ - static random(): RGB { - const num = randomInt(0, 255, 3); - return new RGB(num[0], num[1], num[2]); + static fromHEX(hexColor: string): RGB { + const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; + const hex = hexColor.replace(rgx, (_m, r, g, b) => r + r + g + g + b + b); + const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) as string[]; + if (!isArray(rgb) || rgb.length < 4) throw new TypeError(); + const r = parseInt(rgb[1] as string, 16); + const g = parseInt(rgb[2] as string, 16); + const b = parseInt(rgb[3] as string, 16); + return new RGB(r, g, b); } /** @@ -45,32 +51,26 @@ export class RGB extends RGBSuper { } /** - * 从HEX颜色值转换而来 + * 随机颜色 */ - static fromHEX(hexColor: string): RGB { - const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - const hex = hexColor.replace(rgx, (_m, r, g, b) => r + r + g + g + b + b); - const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) as string[]; - if (!isArray(rgb) || rgb.length < 4) throw new TypeError(); - const r = parseInt(rgb[1] as string, 16); - const g = parseInt(rgb[2] as string, 16); - const b = parseInt(rgb[3] as string, 16); - return new RGB(r, g, b); + static random(): RGB { + const num = randomInt(0, 255, 3); + return new RGB(num[0], num[1], num[2]); } /** - * 转换为RGBA + * 转换为字符串 */ - toRGBA(): RGBA { + toString(): string { const { r, g, b } = this; - return new RGBA(r, g, b); + return `rgb(${r},${g},${b})`; } /** - * 转换为字符串 + * 转换为RGBA */ - toString(): string { + toRGBA(): RGBA { const { r, g, b } = this; - return `rgb(${r},${g},${b})`; + return new RGBA(r, g, b); } } diff --git a/src/color/RGBA.ts b/src/color/RGBA.ts index 3d7b369e..667d3ecd 100644 --- a/src/color/RGBA.ts +++ b/src/color/RGBA.ts @@ -1,4 +1,4 @@ -import { Tuple } from '@tool-pack/types'; +import type { Tuple } from '@tool-pack/types'; import { randomInt } from '../random'; import { RGBSuper } from './RGBSuper'; import { RGB } from './RGB'; @@ -20,26 +20,25 @@ import { RGB } from './RGB'; * */ export class RGBA extends RGBSuper { + private _a!: number; + constructor(r?: number, g?: number, b?: number, a = 1) { super(r, g, b); this.a = a; } - private _a!: number; - - /** - * 获取RGBA中的A - */ - get a(): number { - return this._a; - } - /** - * 设置RGBA中的A + * 从字符串中转换而来 */ - set a(value: number) { - const a = Math.max(0, Math.min(value, 1)); - this._a = Number(a.toFixed(2)); + static fromStr(color: string): RGBA { + if (!RGBA.validate(color)) throw new TypeError('color is not rgb'); + color = color.replace(/(rgba?\(|\))/g, ''); + const rgb = color.split(',') as Tuple; + const r = parseInt(rgb[0]); + const g = parseInt(rgb[1]); + const b = parseInt(rgb[2]); + const a = parseInt(rgb[3]); + return new RGBA(r, g, b, a); } /** @@ -51,17 +50,11 @@ export class RGBA extends RGBSuper { } /** - * 从字符串中转换而来 + * 转成字符串 */ - static fromStr(color: string): RGBA { - if (!RGBA.validate(color)) throw new TypeError('color is not rgb'); - color = color.replace(/(rgba?\(|\))/g, ''); - const rgb = color.split(',') as Tuple; - const r = parseInt(rgb[0]); - const g = parseInt(rgb[1]); - const b = parseInt(rgb[2]); - const a = parseInt(rgb[3]); - return new RGBA(r, g, b, a); + toString() { + const { r, g, b, a } = this; + return `rgba(${r},${g},${b},${a})`; } /** @@ -73,10 +66,17 @@ export class RGBA extends RGBSuper { } /** - * 转成字符串 + * 设置RGBA中的A */ - toString() { - const { r, g, b, a } = this; - return `rgba(${r},${g},${b},${a})`; + set a(value: number) { + const a = Math.max(0, Math.min(value, 1)); + this._a = Number(a.toFixed(2)); + } + + /** + * 获取RGBA中的A + */ + get a(): number { + return this._a; } } diff --git a/src/color/RGBSuper.ts b/src/color/RGBSuper.ts index d2392b6a..1a3b9104 100644 --- a/src/color/RGBSuper.ts +++ b/src/color/RGBSuper.ts @@ -1,13 +1,20 @@ -import { isRGBColor } from './color'; import { getSafeNum } from '../number'; +import { isRGBColor } from './base'; function getLimitValue(value: number) { return getSafeNum(value, 0, 255); } export abstract class RGBSuper { + /** + * 校验颜色值 + * + * @see isRGBColor + */ + static validate = isRGBColor; protected _r!: number; protected _g!: number; + protected _b!: number; protected constructor(r = 0, g = 0, b = 0) { @@ -17,10 +24,11 @@ export abstract class RGBSuper { } /** - * 获取RGB中的R + * 转换为HEX颜色值 */ - get r(): number { - return this._r; + toHEX(): string { + const { r, g, b } = this; + return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); } /** @@ -30,13 +38,6 @@ export abstract class RGBSuper { this._r = getLimitValue(value); } - /** - * 获取RGB中的G - */ - get g(): number { - return this._g; - } - /** * 设置RGB中的G */ @@ -44,13 +45,6 @@ export abstract class RGBSuper { this._g = getLimitValue(value); } - /** - * 获取RGB中的B - */ - get b(): number { - return this._b; - } - /** * 设置RGB中的B */ @@ -58,20 +52,26 @@ export abstract class RGBSuper { this._b = getLimitValue(value); } - abstract toString(): string; + /** + * 获取RGB中的R + */ + get r(): number { + return this._r; + } /** - * 校验颜色值 - * - * @see isRGBColor + * 获取RGB中的G */ - static validate = isRGBColor; + get g(): number { + return this._g; + } /** - * 转换为HEX颜色值 + * 获取RGB中的B */ - toHEX(): string { - const { r, g, b } = this; - return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); + get b(): number { + return this._b; } + + abstract toString(): string; } diff --git a/src/color/base/hslToRgb.ts b/src/color/base/hslToRgb.ts new file mode 100644 index 00000000..bec424dc --- /dev/null +++ b/src/color/base/hslToRgb.ts @@ -0,0 +1,34 @@ +/** + * HSL类型颜色值转换为RGB + * + * @example + * + * hslToRgb('hsl(220,13%,18%)'); // 'rgb(40,44,52)' + * hslToRgb('hsl(0,0%,14%)'); // 'rgb(36,36,36)' + * + */ +export function hslToRgb(hslValue: string): string { + const hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(hslValue) as string[]; + const h = Number(hsl[1]) / 360; + const s = Number(hsl[2]) / 100; + const l = Number(hsl[3]) / 100; + function hue2rgb(p: number, q: number, t: number) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + let r, g, b; + if (s === 0) { + r = g = b = l; + } else { + const q = l < 0.5 ? l * (1 + s) : l + s - l * s; + const p = 2 * l - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + return `rgb(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)})`; +} diff --git a/src/color/base/index.ts b/src/color/base/index.ts new file mode 100644 index 00000000..1e078acd --- /dev/null +++ b/src/color/base/index.ts @@ -0,0 +1,4 @@ +export * from './isRGBColor'; +export * from './isHEXColor'; +export * from './rgbToHex'; +export * from './hslToRgb'; diff --git a/src/color/base/isHEXColor.ts b/src/color/base/isHEXColor.ts new file mode 100644 index 00000000..a4037890 --- /dev/null +++ b/src/color/base/isHEXColor.ts @@ -0,0 +1,21 @@ +/** + * 判断是否是HEX格式的颜色值 + * + * @example + * + * isHEXColor('#ffffff'); // true + * isHEXColor('#fff'); // true + * isHEXColor('#ffff'); // false + * isHEXColor('#fffff'); // false + * isHEXColor('#FFFFFF'); // true + * isHEXColor('#7d1919'); // true + * isHEXColor('#7D1919'); // true + * isHEXColor('#7d19199'); // false + * isHEXColor('#7d191g'); // false + * isHEXColor('rgba(0,0,266,2)'); // false + * + */ +export function isHEXColor(color: string) { + const reg = /^#([\da-fA-F]{3}){1,2}$/; + return reg.test(color); +} diff --git a/src/color/base/isRGBColor.ts b/src/color/base/isRGBColor.ts new file mode 100644 index 00000000..ef774cd7 --- /dev/null +++ b/src/color/base/isRGBColor.ts @@ -0,0 +1,23 @@ +/** + * 判断是否是RGB(包含RGBA)格式的颜色值 + * + * @example + * + * isRGBColor('rgb(0,0,0)'); // true + * isRGBColor('rgb(0, 0, 0)'); // true + * isRGBColor('rgba(0,0,0,0)'); // true + * isRGBColor('rgba(255,255,255,0)'); // true + * isRGBColor('rgba(255, 255, 255, 0)'); // true + * isRGBColor('rgba(100,100,255,0.123123)'); // true + * + * isRGBColor('rgba(-1,0,0,1)'); // false + * isRGBColor('rgba(0,-1,0,1)'); // false + * isRGBColor('rgba(0,0,-1,1)'); // false + * isRGBColor('rgba(0,0,0,-1)'); // false + * isRGBColor('rgba(.,.,.,.)'); // false + */ +export function isRGBColor(color: string) { + const reg = + /^[rR][gG][Bb][Aa]?\((\s*(2[0-4]\d|25[0-5]|[01]?\d{1,2}),){2}\s*(2[0-4]\d|25[0-5]|[01]?\d{1,2})(,\s*(0\.\d+|1|0))?\)$/; + return reg.test(color); +} diff --git a/src/color/base/rgbToHex.ts b/src/color/base/rgbToHex.ts new file mode 100644 index 00000000..c9f07940 --- /dev/null +++ b/src/color/base/rgbToHex.ts @@ -0,0 +1,37 @@ +import { isRGBColor } from './isRGBColor'; + +/** + * RGB转换为HEX + * + * @example + * + * rgbToHex('rgb(0,0,0)'); // '#000000' + * rgbToHex('rgb(132,7,7)'); // '#840707' + * rgbToHex('rgb(101,77,77)'); // '#654d4d' + * + * @throws TypeError 当检测到不合格的颜色值时抛出error + * + */ +export function rgbToHex(color: string) { + if (!isRGBColor(color)) throw new TypeError(); + const rgb = color.split(',') as [string, string, string]; + const r = parseInt(rgb[0].split('(')[1] as string); + const g = parseInt(rgb[1]); + const b = parseInt(rgb[2].split(')')[0] as string); + return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); +} + +// 移动到RGB.fromHEX +/*export function hexToRgb(hexValue: string) { + // if (!isHEXColor(hexValue)) throw new TypeError("hexValue is not hex color"); + const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; + const hex = hexValue.replace(rgx, (m, r, g, b) => { + return r + r + g + g + b + b; + }); + const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) as string[]; + if (!isArray(rgb) || rgb.length < 4) throw new TypeError(); + const r = parseInt(rgb[1], 16); + const g = parseInt(rgb[2], 16); + const b = parseInt(rgb[3], 16); + return `rgb(${r},${g},${b})`; +}*/ diff --git a/src/color/color.ts b/src/color/color.ts deleted file mode 100644 index 7ab6aa2f..00000000 --- a/src/color/color.ts +++ /dev/null @@ -1,119 +0,0 @@ -/** - * 判断是否是RGB(包含RGBA)格式的颜色值 - * - * @example - * - * isRGBColor('rgb(0,0,0)'); // true - * isRGBColor('rgb(0, 0, 0)'); // true - * isRGBColor('rgba(0,0,0,0)'); // true - * isRGBColor('rgba(255,255,255,0)'); // true - * isRGBColor('rgba(255, 255, 255, 0)'); // true - * isRGBColor('rgba(100,100,255,0.123123)'); // true - * - * isRGBColor('rgba(-1,0,0,1)'); // false - * isRGBColor('rgba(0,-1,0,1)'); // false - * isRGBColor('rgba(0,0,-1,1)'); // false - * isRGBColor('rgba(0,0,0,-1)'); // false - * isRGBColor('rgba(.,.,.,.)'); // false - */ -export function isRGBColor(color: string) { - const reg = - /^[rR][gG][Bb][Aa]?\((\s*(2[0-4]\d|25[0-5]|[01]?\d{1,2}),){2}\s*(2[0-4]\d|25[0-5]|[01]?\d{1,2})(,\s*(0\.\d+|1|0))?\)$/; - return reg.test(color); -} - -/** - * 判断是否是HEX格式的颜色值 - * - * @example - * - * isHEXColor('#ffffff'); // true - * isHEXColor('#fff'); // true - * isHEXColor('#ffff'); // false - * isHEXColor('#fffff'); // false - * isHEXColor('#FFFFFF'); // true - * isHEXColor('#7d1919'); // true - * isHEXColor('#7D1919'); // true - * isHEXColor('#7d19199'); // false - * isHEXColor('#7d191g'); // false - * isHEXColor('rgba(0,0,266,2)'); // false - * - */ -export function isHEXColor(color: string) { - const reg = /^#([\da-fA-F]{3}){1,2}$/; - return reg.test(color); -} - -// 移动到RGB.fromHEX -/*export function hexToRgb(hexValue: string) { - // if (!isHEXColor(hexValue)) throw new TypeError("hexValue is not hex color"); - const rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; - const hex = hexValue.replace(rgx, (m, r, g, b) => { - return r + r + g + g + b + b; - }); - const rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) as string[]; - if (!isArray(rgb) || rgb.length < 4) throw new TypeError(); - const r = parseInt(rgb[1], 16); - const g = parseInt(rgb[2], 16); - const b = parseInt(rgb[3], 16); - return `rgb(${r},${g},${b})`; -}*/ - -/** - * RGB转换为HEX - * - * @example - * - * rgbToHex('rgb(0,0,0)'); // '#000000' - * rgbToHex('rgb(132,7,7)'); // '#840707' - * rgbToHex('rgb(101,77,77)'); // '#654d4d' - * - * @throws TypeError 当检测到不合格的颜色值时抛出error - * - */ -export function rgbToHex(color: string) { - if (!isRGBColor(color)) throw new TypeError(); - const rgb = color.split(',') as [string, string, string]; - const r = parseInt(rgb[0].split('(')[1] as string); - const g = parseInt(rgb[1]); - const b = parseInt(rgb[2].split(')')[0] as string); - - return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); -} - -/** - * HSL类型颜色值转换为RGB - * - * @example - * - * hslToRgb('hsl(220,13%,18%)'); // 'rgb(40,44,52)' - * hslToRgb('hsl(0,0%,14%)'); // 'rgb(36,36,36)' - * - */ -export function hslToRgb(hslValue: string): string { - const hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(hslValue) as string[]; - const h = Number(hsl[1]) / 360; - const s = Number(hsl[2]) / 100; - const l = Number(hsl[3]) / 100; - - function hue2rgb(p: number, q: number, t: number) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - } - - let r, g, b; - if (s === 0) { - r = g = b = l; - } else { - const q = l < 0.5 ? l * (1 + s) : l + s - l * s; - const p = 2 * l - q; - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - return `rgb(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)})`; -} diff --git a/src/color/index.ts b/src/color/index.ts index 634a95ba..406537d0 100644 --- a/src/color/index.ts +++ b/src/color/index.ts @@ -1,3 +1,3 @@ -export * from './color'; +export * from './base'; export * from './RGB'; export * from './RGBA'; diff --git a/src/common/DynamicEnum.ts b/src/common/DynamicEnum.ts new file mode 100644 index 00000000..34e1ca33 --- /dev/null +++ b/src/common/DynamicEnum.ts @@ -0,0 +1,82 @@ +import { forEachObj } from '../object'; + +/** + * DynamicEnum 意思是动态的枚举,也可以把他叫做 MapProxy + */ +export class DynamicEnum { + private valueKeyMap: Map = new Map(); + constructor(private originMap: Map) { + this.updateValueKeyMap(); + } + static createByObj(obj: object): DynamicEnum { + const map = new Map(); + forEachObj(obj, (v, k): void => { + map.set(k, v); + }); + return new DynamicEnum(map); + } + private updateValueKeyMap(): void { + const map = new Map(); + this.originMap.forEach((value, key) => { + map.set(value, key); + }); + this.valueKeyMap = map; + } + set(key: K, value: V): void { + if (!this.originMap.has(key)) { + this.originMap.set(key, value); + this.valueKeyMap.set(value, key); + return; + } + const originValue = this.originMap.get(key); + if (originValue === value) return; + this.originMap.set(key, value); + this.updateValueKeyMap(); + } + setOrSwap(key: K, value: V): void { + const originValue = this.originMap.get(key); + const originKey = this.getKeyByValue(value); + if (originKey !== undefined && originValue !== undefined) { + this.originMap.set(originKey, originValue); + } + this.set(key, value); + } + setKeyByValue(value: V, key: K): void { + const originKey = this.valueKeyMap.get(value); + if (originKey === undefined) return; + this.originMap.delete(originKey); + this.originMap.set(key, value); + this.updateValueKeyMap(); + } + map(callbackFn: (value: V, key: K, map: Map) => T): T[] { + const result: T[] = []; + this.originMap.forEach((value, key, map) => result.push(callbackFn(value, key, map))); + return result; + } + deleteByValue(value: V): boolean { + const key = this.getKeyByValue(value); + if (!key) return false; + return this.delete(key); + } + delete(key: K): boolean { + const res = this.originMap.delete(key); + res && this.updateValueKeyMap(); + return res; + } + forEach(callbackFn: (value: V, key: K, map: Map) => void): void { + this.originMap.forEach(callbackFn); + } + getKeyByValue(value: V): undefined | K { + return this.valueKeyMap.get(value); + } + clear(): void { + this.originMap.clear(); + this.valueKeyMap.clear(); + } + get(key: K): undefined | V { + return this.originMap.get(key); + } + get size(): number { + return this.originMap.size; + } +} diff --git a/src/common/createEnum.ts b/src/common/createEnum.ts index e5dad7f9..2cabc2d6 100644 --- a/src/common/createEnum.ts +++ b/src/common/createEnum.ts @@ -1,3 +1,4 @@ +import type { ReverseObject, Mix } from '@tool-pack/types'; import { getReversedObj } from '../object'; /** @@ -13,13 +14,7 @@ import { getReversedObj } from '../object'; * createEnum(['a', 'b']); // { a: '0', b: '1', 0: 'a', 1: 'b' } * */ -export function createEnum( - obj: T, -): Readonly< - T & { - [k: string]: K; - } -> { +export function createEnum(obj: T): Mix> { /* const res: any = {}; for (let k in obj) { if (res.hasOwnProperty(k)) throw new Error("key multiple"); @@ -28,5 +23,5 @@ export function createEnum( Object.freeze(res); // freeze值不可变 // Object.seal(result); // seal值可以变 return res;*/ - return Object.freeze(Object.assign({}, obj, getReversedObj(obj as any))) as any; + return Object.freeze(Object.assign({}, obj, getReversedObj(obj))); } diff --git a/src/common/createEventBus.ts b/src/common/createEventBus.ts new file mode 100644 index 00000000..9a8eb19e --- /dev/null +++ b/src/common/createEventBus.ts @@ -0,0 +1,60 @@ +/** + * 创建一个 event bus + * + * 基于事件发布订阅的 event bus. + * 该方式区别于传统的 event bus 可以监听多个事件,该方式是点对点事件监听的。 + * 比传统的 EventBus 解决了类型安全以及隐式依赖的问题。 + * 其实更好的方式是用 RxJS 的各种 Subject 作为 EventBus,但是仅仅只是用于 EventBus 的话有点杀鸡焉用牛刀,所以该方式可以作为下位替代。 + * + * @example + * // 创建事件,预先声明事件 + * const event = createEventBus<{ a: number; b: number }>(); + * // 事件监听 + * const off = event.on((v, off) => { + * console.log(v.a, v.b); + * off(); // 移除事件监听,相当于一次性事件;跟外面 on 返回的 off 是一样的 + * }); + * // 触发事件 + * event.emit({ a: 1, b: 2 }); + * // 清理事件监听 + * off(); + * // 清理所有事件监听 + * event.clear(); + */ +export function createEventBus() { + type Off = () => void; + type Listener = (payload: T, off: Off) => void; + const listeners: Listener[] = []; + return { + /** + * 触发事件,传递数据 + */ + emit(payload: T): void { + // listeners.slice() 避免边遍历边 off 时遍历缺漏 + listeners.slice().forEach((listener): void => { + // 后面的 listener 有可能被前面的 listener off 掉了 + if (!listeners.includes(listener)) return; + listener(payload, () => off(listener)); + }); + }, + /** + * 添加事件监听,接收数据 + */ + on(listener: Listener): Off { + listeners.push(listener); + return () => off(listener); + }, + /** + * 清理所有事件监听 + */ + clear(): void { + listeners.length = 0; + }, + } as const; + + function off(listener: Listener): void { + const index = listeners.indexOf(listener); + if (index === -1) return; + listeners.splice(index, 1); + } +} diff --git a/src/common/debounce.ts b/src/common/debounce.ts index cb449d1a..cef1ce18 100644 --- a/src/common/debounce.ts +++ b/src/common/debounce.ts @@ -34,10 +34,10 @@ export function debounce any>( callback: CB, delay: number, leading = false, -): CB & { - cancel(): void; +): { flush(): ReturnType; -} { + cancel(): void; +} & CB { let lastThis: unknown; let lastArgs: any; let lastResult: unknown; diff --git a/src/common/emptyFn.ts b/src/common/emptyFn.ts new file mode 100644 index 00000000..885e1911 --- /dev/null +++ b/src/common/emptyFn.ts @@ -0,0 +1,7 @@ +/** + * 空函数,常用于用于默认值 + * 比如在一些 eslint 禁止空函数的场景下使用 + */ +export function emptyFn(): void { + // do nothing +} diff --git a/src/common/getRoot.ts b/src/common/getRoot.ts index 88527970..9ab08eed 100644 --- a/src/common/getRoot.ts +++ b/src/common/getRoot.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-restricted-globals */ /** * 获取全局对象 * diff --git a/src/common/index.ts b/src/common/index.ts index 8c2bde32..840041d9 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -8,4 +8,7 @@ export * from './createUUID'; export * from './createEnum'; export * from './getRoot'; export * from './parseCmdParams'; -export * from './formatBytes'; +export * from './loadingElse'; +export * from './emptyFn'; +export * from './createEventBus'; +export * from './DynamicEnum'; diff --git a/src/common/loadingElse.ts b/src/common/loadingElse.ts new file mode 100644 index 00000000..ff59de3d --- /dev/null +++ b/src/common/loadingElse.ts @@ -0,0 +1,40 @@ +import { isPromiseLike } from '../data-type'; + +/** + * 只在非loading下执行回调 + * + * 例如在滚动事件下执行请求,请求完成前不会再次执行 + * + * @example + * + * ```typescript + * + * const fn = jest.fn(); + * const cb2 = loadingElse(() => sleep(10).then(fn)); + * cb2(); + * cb2(); + * cb2(); + * cb2(); + * cb2(); + * + * await sleep(20); + * expect(fn.mock.calls.length).toBe(1); + * ``` + * + * @param cb + */ +export function loadingElse unknown>(cb: T): T { + let loading = false; + const setLoadingFalse = () => (loading = false); + let result: unknown; + return ((...args) => { + if (loading) return result; + loading = true; + + result = cb(...args); + if (isPromiseLike(result)) { + result.then(setLoadingFalse, setLoadingFalse); + } else setLoadingFalse(); + return result; + }) as T; +} diff --git a/src/common/parseCmdParams.ts b/src/common/parseCmdParams.ts index 783759e1..7e74a4f5 100644 --- a/src/common/parseCmdParams.ts +++ b/src/common/parseCmdParams.ts @@ -24,7 +24,7 @@ export function parseCmdParams( arr: string[], prefix = '-', defaultKey = 'default', -): Map { +): Map { const eqReg = /([^=]+)=([\s\S]+)?/; const isKeyReg = new RegExp(`^${prefix}`); const list = arr.slice(); diff --git a/src/common/polling.ts b/src/common/polling.ts index 42d47de6..8f92f700 100644 --- a/src/common/polling.ts +++ b/src/common/polling.ts @@ -19,7 +19,7 @@ * @param [immediate=true] 是否马上执行第一次 */ export function polling( - callback: (times: number) => void | Promise, + callback: (times: number) => Promise | void, interval: number, immediate = true, ): { diff --git a/src/common/throttle.ts b/src/common/throttle.ts index 7a66fb43..81318d27 100644 --- a/src/common/throttle.ts +++ b/src/common/throttle.ts @@ -75,13 +75,13 @@ import { debounce } from './debounce'; * @param [options.trailing=false] 尾调用 * @param options.invalidCB 间隔期间调用throttle返回的函数执行的回调 例如一个按钮5秒点击一次,不可点击时执行该函数 */ -export function throttle void | any>( +export function throttle any>( callback: CB, interval: number, options: { - leading?: boolean; - trailing?: boolean; invalidCB?: (timeCountDown: number) => void; + trailing?: boolean; + leading?: boolean; } = {}, ): CB { const _options: Required[2]> = { diff --git a/src/coordinate.ts b/src/coordinate.ts deleted file mode 100644 index 61b26003..00000000 --- a/src/coordinate.ts +++ /dev/null @@ -1,382 +0,0 @@ -import { CalcChain } from './CalcChain'; -import { inRange } from './array'; -import { strip } from './number'; - -/** - * 坐标点 - */ -export type Point = [number, number]; - -/** - * 判断某个点是否在某个线上 - * - * @example - * - * isPointInPath([1, 2], [[0, 0], [2, 4]]); // true - * isPointInPath([2, 2], [[0, 0], [2, 4]]); // false - * - * isPointInPath([2, 2], [[0, 0], [4, 4]]); // true - * isPointInPath([1, 2], [[0, 0], [4, 4]]); // false - * isPointInPath([1, 2], [[0, 0], [2, 4], [4, 4]]); // true - * - * isPointInPath([3, 3], [[1, 1], [4, 4]]); // true - * - * @param point 点 - * @param path 路径、线 - */ -export function isPointInPath(point: Point, path: Point[]): boolean { - const [x, y] = point; - for (let i = 1; i < path.length; i++) { - const [x1, y1] = path[i - 1] as Point; - const [x2, y2] = path[i] as Point; - - // 根据向量的坐标运算 判断是否平行 - // 对于非0向量a,b 设a=(x1,y1) b=(x2,y2) 则a平行b <=> x1/x2 = y1/y2 - const vector1 = (y2 - y1) / (x2 - x1); - const vector2 = (y - y1) / (x - x1); - - // 判断是否在范围内 - if (vector2 === vector1 && inRange(x, [x1, x2]) && inRange(y, [y1, y2])) return true; - } - return false; -} - -/** - * 根据三角函数求两点的距离 - * - * @example - * - * getDistance([0, 0], [3, 4]); // 5 - * getDistance([0, 0], [1, 1]); // Math.sqrt(2) - * Math.round(getDistance([0, 0], [1, Math.sqrt(3)])); // 2 - * - * getDistance([0, 0], [0, 5]); // 5 - * getDistance([0, 0], [5, 0]); // 5 - * getDistance([0, 0], [-5, 0]); // 5 - * getDistance([0, 0], [0, -5]); // 5 - * - */ -export function getDistance(origin: Point, target: Point): number { - const [x1, y1] = origin; - const [x2, y2] = target; - const x = x1 - x2; - const y = y1 - y2; - return Math.sqrt(x * x + y * y); -} - -/** - * 根据目标点获取相对于原点的角度 - * - * 注意:默认旋转方向是向上的 所以(0,0)要顶部向着(1,1)是135度,而不是40度 - * 注意:在屏幕里角度是顺时针的与数学中的逆时针坐标不一样 45度是右下而不是右上方 - * - * @example - * - * getAngle([0, 0], [1, 1]); // 135 - * getAngle([0, 0], [1, 1], 'bottom'); // 315 - * getAngle([0, 0], [1, 1], 'left'); // 225 - * getAngle([0, 0], [1, 1], 'right'); // 45 - * - * @param origin 原点 - * @param target 目标点 - * @param direct 需要上下左右哪个方向指向目标,默认是'top' - * @param [direct='top'] - * @returns 角度, 范围:[0,360) - */ -export function getAngle( - origin: Point, - target: Point, - direct: 'top' | 'left' | 'right' | 'bottom' = 'top', -): number { - const [x1, y1] = origin; - const [x2, y2] = target; - - // 相对数学坐标系是对的,对于屏幕坐标系不对 - // x = x1 - x2 - // y = y1 - y2 - // r = Math.sqrt(x * x + y * y) - // angle = Math.round(Math.asin(y / r) / Math.pi * 180) - - // 在两点x轴相同时不对 - // const x = x1 - x2; - // const y = y1 - y2; - // const r = Math.sqrt(x * x + y * y); - // if (r === 0) return 0; - // return Math.round(Math.acos(x / r) / Math.PI * 180) - 90; - - // https://blog.csdn.net/chelen_jak/article/details/80518973 - const angle = Math.atan2(x2 - x1, y2 - y1); //弧度 0.9272952180016122 - const theta = angle * (180 / Math.PI); //角度 53.13010235415598 - - return ( - { - top: 180 - theta, - left: 270 - theta, - bottom: 360 - theta, - right: 450 - theta, - }[direct] % 360 - ); -} - -/** - * 根据半径与角度获取对应坐标点 - * - * 采用的是顺时针角度,也就是0度角位置是在原点正上方,180度是在正下方 - * - * 注意:不要使用[0, 0]作为原点,否则不正确 - * - * @example - * - * const center: Point = [1, 1]; - * const radius = 10; - * - * getRotatePoint(center, radius, 0); // [center[0], center[1] - radius] - * getRotatePoint(center, radius, 90); // [center[0] + radius, center[1]] - * getRotatePoint(center, radius, 180); // [center[0], center[1] + radius] - * getRotatePoint(center, radius, 270); // [center[0] - radius, center[1]] - * - * @param center 中心点 - * @param radius 半径 - * @param rotate 角度 - */ -export function getRotatePoint(center: Point, radius: number, rotate: number): Point { - const angle = (Math.PI / 180) * rotate; - // const angle = NumberCalc.init(Math.PI)["/"](180)["*"](rotate).curVal; - - // 圆的参数方程 圆心(a,b) x = a + r * cos; y = b + r * sin; - // 或正弦定理 a/sinA = b/sinB - // 因为屏幕上的坐标系与数学上的坐标系不同,所以x,y有所变化 - // let x = center[0] + radius * Math.sin(angle); - // let y = center[1] - radius * Math.cos(angle); - const x = CalcChain.init(radius)['*'](Math.sin(angle))['+'](center[0]).value; - const y = CalcChain.init(radius)['*'](Math.cos(angle)).by(center[1], '-').value; - return [x, y]; -} - -/** - * 根据余弦定理(c^2 = a^2 + b^2 - 2 * a * b * cosA)获取任意边长 - * - * @example - * - * getBorderWidthByCos(3, 4, 90); // 5 - * getBorderWidthByCos(1, 1, 90).toFixed(2); // Math.sqrt(2).toFixed(2) - * - * @param a a边 - * @param b b边 - * @param angle 要获取的边长对应的角度 - */ -export function getBorderWidthByCos(a: number, b: number, angle: number) { - // 角度化弧度 - const C = (angle * Math.PI) / 180; - const c2 = a ** 2 + b ** 2 - 2 * a * b * Math.cos(C); - return Math.sqrt(c2); -} - -/** - * 根据正弦定理(a/sinA = b/sinB = c/sinC)获取对应边长 - * - * @example - * - * getBorderWidthBySin(1, 45, 90).toFixed(2); // Math.sqrt(2).toFixed(2) - * getBorderWidthBySin(1, 45, 45); // 1 - * - * @param a a边 - * @param angleA 角A - * @param angleB 要获取的边长对应的角度 - */ -export function getBorderWidthBySin(a: number, angleA: number, angleB: number) { - // 角度化弧度 - const rad = Math.PI / 180; - const radA = rad * angleA; - const radB = rad * angleB; - const resA = a / Math.sin(radA); - return resA * Math.sin(radB); -} - -/** - * 笛卡尔坐标系(平面直角坐标系)转屏幕坐标系 - * --- - * 翻转y轴,保持原图像 - * - * @example - * - * // 直接转换 - * - * // 3 │* - * // 2 │ - * // 1 │ - * // ------------- - * // 0 1 2 3 - * - * // [0, 3] 转换为 [0, 0] - * - * // 0 1 2 3 - * // -*----------- - * // 1 │ - * // 2 │ - * // 3 │ - * - * rectCoordToScreen([0, 3], [3, 3]); // [0, 0] - * - * // 3 │ - * // 2 │ - * // 1 │ - * // -*------------ - * // 0 1 2 3 - * - * // [0, 0] 转换为 [0, 3] - * - * // 0 1 2 3 - * // ------------- - * // 1 │ - * // 2 │ - * // 3 │* - * - * rectCoordToScreen([0, 0], [3, 3]); // [0, 3] - * - * // 3 │ - * // 2 │ - * // 1 │ * - * // -------------- - * // 0 1 2 3 - * - * // [1, 1] 转换为 [1, 2] - * - * // 0 1 2 3 - * // ------------- - * // 1 │ - * // 2 │ * - * // 3 │ - * - * rectCoordToScreen([1, 1], [3, 3]); // [1, 2] - * - * rectCoordToScreen([5, 5], [20, 20]); // [5, 15] - * - * @param curPos 当前坐标点 - * @param curView 当前坐标容器宽高 - * - */ -export function rectCoordToScreen(curPos: Point, curView: Point): Point; -/** - * 笛卡尔坐标系(平面直角坐标系)转屏幕坐标系 - * --- - * 按比例转换,图像会翻转 - * - * @example - * - * // 按比例转换,并翻转图像 - * - * - * // 2 │ - * // 1 │ - * // -*-------- - * // 0 1 2 - * - * // [0, 0] 转换为 [0, 0] - * - * // 0 1 2 3 - * // -*------------ - * // 1 │ - * // 2 │ - * // 3 │ - * rectCoordToScreen([0, 0], [2, 2], [3, 3]); // [0, 0] - * - * // 3 │ - * // 2 │ - * // 1 │ * - * // ------------- - * // 0 1 2 3 - * - * // [0, 3] 转换为 [0, 0] - * - * // 0 1 2 3 - * // ------------- - * // 1 │ * - * // 2 │ - * // 3 │ - * - * rectCoordToScreen([1, 1], [3, 3], [3, 3]); // [1, 1] - * - * rectCoordToScreen([5, 5], [20, 20], [30, 30]); // [7.5, 7.5] - * - * @param curPos 当前坐标点 - * @param curView 当前坐标容器宽高 - * @param targetView 目标坐标容器宽高 - * @param keep 是否保持原图像 - */ -export function rectCoordToScreen( - curPos: Point, - curView: Point, - targetView: Point, - keep?: false, -): Point; -/** - * 笛卡尔坐标系(平面直角坐标系)转屏幕坐标系 - * --- - * 按比例转换,保持原图像 综合以上两种效果:按比例+保持原图像 翻转 - * - * @example - * - * // 3 │* - * // 2 │ - * // 1 │ - * // ------------- - * // 0 1 2 3 - * - * // [0, 3] 转换为 [0, 0] - * - * // 0 1 2 3 - * // -*----------- - * // 1 │ - * // 2 │ - * // 3 │ - * rectCoordToScreen([0, 3], [3, 3], [3, 3], true); // [0, 0] - * - * // 3 │ - * // 2 │ - * // 1 │ * - * // -------------- - * // 0 1 2 3 - * - * // [1, 1] 转换为 [1, 2] - * - * // 0 1 2 3 - * // ------------- - * // 1 │ - * // 2 │ * - * // 3 │ - * - * rectCoordToScreen([1, 1], [3, 3], [3, 3], true); // [1, 2] - * - * - * rectCoordToScreen([5, 5], [20, 20], [30, 30], true); // [7.5, 22.5] - * - * @param curPos 当前坐标点 - * @param curView 当前坐标容器宽高 - * @param targetView 目标坐标容器宽高 - * @param keep 保持为原图像 - */ -export function rectCoordToScreen( - curPos: Point, - curView: Point, - targetView: Point, - keep: true, -): Point; -export function rectCoordToScreen( - curPos: Point, - curView: Point, - targetView?: Point, - keep = false, -): Point { - const [x, y] = curPos; - const [w, h] = curView; - - if (!targetView) return [x, h - y]; - - const [tw, ty] = targetView; - - const x1 = (x / w) * tw; - const y1 = ((keep ? h - y : y) / h) * ty; - - return [strip(x1), strip(y1)]; -} diff --git a/src/coordinate/getAngle.ts b/src/coordinate/getAngle.ts new file mode 100644 index 00000000..4a7ab709 --- /dev/null +++ b/src/coordinate/getAngle.ts @@ -0,0 +1,55 @@ +import type { Point } from '@tool-pack/types'; + +/** + * 根据目标点获取相对于原点的角度 + * + * 注意:默认旋转方向是向上的 所以(0,0)要顶部向着(1,1)是135度,而不是40度 + * 注意:在屏幕里角度是顺时针的与数学中的逆时针坐标不一样 45度是右下而不是右上方 + * + * @example + * + * getAngle([0, 0], [1, 1]); // 135 + * getAngle([0, 0], [1, 1], 'bottom'); // 315 + * getAngle([0, 0], [1, 1], 'left'); // 225 + * getAngle([0, 0], [1, 1], 'right'); // 45 + * + * @param origin 原点 + * @param target 目标点 + * @param direct 需要上下左右哪个方向指向目标,默认是'top' + * @param [direct='top'] + * @returns 角度, 范围:[0,360) + */ +export function getAngle( + origin: Point, + target: Point, + direct: 'bottom' | 'right' | 'left' | 'top' = 'top', +): number { + const [x1, y1] = origin; + const [x2, y2] = target; + + // 相对数学坐标系是对的,对于屏幕坐标系不对 + // x = x1 - x2 + // y = y1 - y2 + // r = Math.sqrt(x * x + y * y) + // angle = Math.round(Math.asin(y / r) / Math.pi * 180) + + // 在两点x轴相同时不对 + // const x = x1 - x2; + // const y = y1 - y2; + // const r = Math.sqrt(x * x + y * y); + // if (r === 0) return 0; + // return Math.round(Math.acos(x / r) / Math.PI * 180) - 90; + + // https://blog.csdn.net/chelen_jak/article/details/80518973 + const angle = Math.atan2(x2 - x1, y2 - y1); //弧度 0.9272952180016122 + const theta = angle * (180 / Math.PI); //角度 53.13010235415598 + + return ( + { + bottom: 360 - theta, + right: 450 - theta, + left: 270 - theta, + top: 180 - theta, + }[direct] % 360 + ); +} diff --git a/src/coordinate/getBorderWidthByCos.ts b/src/coordinate/getBorderWidthByCos.ts new file mode 100644 index 00000000..a392651c --- /dev/null +++ b/src/coordinate/getBorderWidthByCos.ts @@ -0,0 +1,18 @@ +/** + * 根据余弦定理(c^2 = a^2 + b^2 - 2 * a * b * cosA)获取任意边长 + * + * @example + * + * getBorderWidthByCos(3, 4, 90); // 5 + * getBorderWidthByCos(1, 1, 90).toFixed(2); // Math.sqrt(2).toFixed(2) + * + * @param a a边 + * @param b b边 + * @param angle 要获取的边长对应的角度 + */ +export function getBorderWidthByCos(a: number, b: number, angle: number) { + // 角度化弧度 + const C = (angle * Math.PI) / 180; + const c2 = a ** 2 + b ** 2 - 2 * a * b * Math.cos(C); + return Math.sqrt(c2); +} diff --git a/src/coordinate/getBorderWidthBySin.ts b/src/coordinate/getBorderWidthBySin.ts new file mode 100644 index 00000000..b2b60811 --- /dev/null +++ b/src/coordinate/getBorderWidthBySin.ts @@ -0,0 +1,20 @@ +/** + * 根据正弦定理(a/sinA = b/sinB = c/sinC)获取对应边长 + * + * @example + * + * getBorderWidthBySin(1, 45, 90).toFixed(2); // Math.sqrt(2).toFixed(2) + * getBorderWidthBySin(1, 45, 45); // 1 + * + * @param a a边 + * @param angleA 角A + * @param angleB 要获取的边长对应的角度 + */ +export function getBorderWidthBySin(a: number, angleA: number, angleB: number) { + // 角度化弧度 + const rad = Math.PI / 180; + const radA = rad * angleA; + const radB = rad * angleB; + const resA = a / Math.sin(radA); + return resA * Math.sin(radB); +} diff --git a/src/coordinate/getDistance.ts b/src/coordinate/getDistance.ts new file mode 100644 index 00000000..13528f25 --- /dev/null +++ b/src/coordinate/getDistance.ts @@ -0,0 +1,24 @@ +import type { Point } from '@tool-pack/types'; + +/** + * 根据三角函数求两点的距离 + * + * @example + * + * getDistance([0, 0], [3, 4]); // 5 + * getDistance([0, 0], [1, 1]); // Math.sqrt(2) + * Math.round(getDistance([0, 0], [1, Math.sqrt(3)])); // 2 + * + * getDistance([0, 0], [0, 5]); // 5 + * getDistance([0, 0], [5, 0]); // 5 + * getDistance([0, 0], [-5, 0]); // 5 + * getDistance([0, 0], [0, -5]); // 5 + * + */ +export function getDistance(origin: Point, target: Point): number { + const [x1, y1] = origin; + const [x2, y2] = target; + const x = x1 - x2; + const y = y1 - y2; + return Math.sqrt(x * x + y * y); +} diff --git a/src/coordinate/getRotatePoint.ts b/src/coordinate/getRotatePoint.ts new file mode 100644 index 00000000..2d8d151e --- /dev/null +++ b/src/coordinate/getRotatePoint.ts @@ -0,0 +1,37 @@ +import type { Point } from '@tool-pack/types'; +import { CalcChain } from '../CalcChain'; + +/** + * 根据半径与角度获取对应坐标点 + * + * 采用的是顺时针角度,也就是0度角位置是在原点正上方,180度是在正下方 + * + * 注意:不要使用[0, 0]作为原点,否则不正确 + * + * @example + * + * const center: Point = [1, 1]; + * const radius = 10; + * + * getRotatePoint(center, radius, 0); // [center[0], center[1] - radius] + * getRotatePoint(center, radius, 90); // [center[0] + radius, center[1]] + * getRotatePoint(center, radius, 180); // [center[0], center[1] + radius] + * getRotatePoint(center, radius, 270); // [center[0] - radius, center[1]] + * + * @param center 中心点 + * @param radius 半径 + * @param rotate 角度 + */ +export function getRotatePoint(center: Point, radius: number, rotate: number): Point { + const angle = (Math.PI / 180) * rotate; + // const angle = NumberCalc.init(Math.PI)["/"](180)["*"](rotate).curVal; + + // 圆的参数方程 圆心(a,b) x = a + r * cos; y = b + r * sin; + // 或正弦定理 a/sinA = b/sinB + // 因为屏幕上的坐标系与数学上的坐标系不同,所以x,y有所变化 + // let x = center[0] + radius * Math.sin(angle); + // let y = center[1] - radius * Math.cos(angle); + const x = CalcChain.init(radius)['*'](Math.sin(angle))['+'](center[0]).value; + const y = CalcChain.init(radius)['*'](Math.cos(angle)).by(center[1], '-').value; + return [x, y]; +} diff --git a/src/coordinate/index.ts b/src/coordinate/index.ts new file mode 100644 index 00000000..575a00f2 --- /dev/null +++ b/src/coordinate/index.ts @@ -0,0 +1,7 @@ +export * from './isPointInPath'; +export * from './getDistance'; +export * from './getAngle'; +export * from './getRotatePoint'; +export * from './getBorderWidthByCos'; +export * from './getBorderWidthBySin'; +export * from './rectCoordToScreen'; diff --git a/src/coordinate/isPointInPath.ts b/src/coordinate/isPointInPath.ts new file mode 100644 index 00000000..5b643222 --- /dev/null +++ b/src/coordinate/isPointInPath.ts @@ -0,0 +1,36 @@ +import type { Point } from '@tool-pack/types'; +import { inRange } from '../array'; + +/** + * 判断某个点是否在某个线上 + * + * @example + * + * isPointInPath([1, 2], [[0, 0], [2, 4]]); // true + * isPointInPath([2, 2], [[0, 0], [2, 4]]); // false + * + * isPointInPath([2, 2], [[0, 0], [4, 4]]); // true + * isPointInPath([1, 2], [[0, 0], [4, 4]]); // false + * isPointInPath([1, 2], [[0, 0], [2, 4], [4, 4]]); // true + * + * isPointInPath([3, 3], [[1, 1], [4, 4]]); // true + * + * @param point 点 + * @param path 路径、线 + */ +export function isPointInPath(point: Point, path: Point[]): boolean { + const [x, y] = point; + for (let i = 1; i < path.length; i++) { + const [x1, y1] = path[i - 1] as Point; + const [x2, y2] = path[i] as Point; + + // 根据向量的坐标运算 判断是否平行 + // 对于非0向量a,b 设a=(x1,y1) b=(x2,y2) 则a平行b <=> x1/x2 = y1/y2 + const vector1 = (y2 - y1) / (x2 - x1); + const vector2 = (y - y1) / (x - x1); + + // 判断是否在范围内 + if (vector2 === vector1 && inRange(x, [x1, x2]) && inRange(y, [y1, y2])) return true; + } + return false; +} diff --git a/src/coordinate/rectCoordToScreen.ts b/src/coordinate/rectCoordToScreen.ts new file mode 100644 index 00000000..7edf7a9b --- /dev/null +++ b/src/coordinate/rectCoordToScreen.ts @@ -0,0 +1,186 @@ +import type { Point } from '@tool-pack/types'; +import { strip } from '../number'; + +/** + * 笛卡尔坐标系(平面直角坐标系)转屏幕坐标系 + * --- + * 翻转y轴,保持原图像 + * + * @example + * + * // 直接转换 + * + * // 3 │* + * // 2 │ + * // 1 │ + * // ------------- + * // 0 1 2 3 + * + * // [0, 3] 转换为 [0, 0] + * + * // 0 1 2 3 + * // -*----------- + * // 1 │ + * // 2 │ + * // 3 │ + * + * rectCoordToScreen([0, 3], [3, 3]); // [0, 0] + * + * // 3 │ + * // 2 │ + * // 1 │ + * // -*------------ + * // 0 1 2 3 + * + * // [0, 0] 转换为 [0, 3] + * + * // 0 1 2 3 + * // ------------- + * // 1 │ + * // 2 │ + * // 3 │* + * + * rectCoordToScreen([0, 0], [3, 3]); // [0, 3] + * + * // 3 │ + * // 2 │ + * // 1 │ * + * // -------------- + * // 0 1 2 3 + * + * // [1, 1] 转换为 [1, 2] + * + * // 0 1 2 3 + * // ------------- + * // 1 │ + * // 2 │ * + * // 3 │ + * + * rectCoordToScreen([1, 1], [3, 3]); // [1, 2] + * + * rectCoordToScreen([5, 5], [20, 20]); // [5, 15] + * + * @param curPos 当前坐标点 + * @param curView 当前坐标容器宽高 + * + */ +export function rectCoordToScreen(curPos: Point, curView: Point): Point; +/** + * 笛卡尔坐标系(平面直角坐标系)转屏幕坐标系 + * --- + * 按比例转换,图像会翻转 + * + * @example + * + * // 按比例转换,并翻转图像 + * + * + * // 2 │ + * // 1 │ + * // -*-------- + * // 0 1 2 + * + * // [0, 0] 转换为 [0, 0] + * + * // 0 1 2 3 + * // -*------------ + * // 1 │ + * // 2 │ + * // 3 │ + * rectCoordToScreen([0, 0], [2, 2], [3, 3]); // [0, 0] + * + * // 3 │ + * // 2 │ + * // 1 │ * + * // ------------- + * // 0 1 2 3 + * + * // [0, 3] 转换为 [0, 0] + * + * // 0 1 2 3 + * // ------------- + * // 1 │ * + * // 2 │ + * // 3 │ + * + * rectCoordToScreen([1, 1], [3, 3], [3, 3]); // [1, 1] + * + * rectCoordToScreen([5, 5], [20, 20], [30, 30]); // [7.5, 7.5] + * + * @param curPos 当前坐标点 + * @param curView 当前坐标容器宽高 + * @param targetView 目标坐标容器宽高 + * @param keep 是否保持原图像 + */ +export function rectCoordToScreen( + curPos: Point, + curView: Point, + targetView: Point, + keep?: false, +): Point; +/** + * 笛卡尔坐标系(平面直角坐标系)转屏幕坐标系 + * --- + * 按比例转换,保持原图像 综合以上两种效果:按比例+保持原图像 翻转 + * + * @example + * + * // 3 │* + * // 2 │ + * // 1 │ + * // ------------- + * // 0 1 2 3 + * + * // [0, 3] 转换为 [0, 0] + * + * // 0 1 2 3 + * // -*----------- + * // 1 │ + * // 2 │ + * // 3 │ + * rectCoordToScreen([0, 3], [3, 3], [3, 3], true); // [0, 0] + * + * // 3 │ + * // 2 │ + * // 1 │ * + * // -------------- + * // 0 1 2 3 + * + * // [1, 1] 转换为 [1, 2] + * + * // 0 1 2 3 + * // ------------- + * // 1 │ + * // 2 │ * + * // 3 │ + * + * rectCoordToScreen([1, 1], [3, 3], [3, 3], true); // [1, 2] + * + * + * rectCoordToScreen([5, 5], [20, 20], [30, 30], true); // [7.5, 22.5] + * + * @param curPos 当前坐标点 + * @param curView 当前坐标容器宽高 + * @param targetView 目标坐标容器宽高 + * @param keep 保持为原图像 + */ +export function rectCoordToScreen( + curPos: Point, + curView: Point, + targetView: Point, + keep: true, +): Point; +export function rectCoordToScreen( + curPos: Point, + curView: Point, + targetView?: Point, + keep = false, +): Point { + const [x, y] = curPos; + const [w, h] = curView; + if (!targetView) return [x, h - y]; + const [tw, ty] = targetView; + const x1 = (x / w) * tw; + const y1 = ((keep ? h - y : y) / h) * ty; + return [strip(x1), strip(y1)]; +} diff --git a/src/data-type.ts b/src/data-type.ts deleted file mode 100644 index 17ba0fc8..00000000 --- a/src/data-type.ts +++ /dev/null @@ -1,641 +0,0 @@ -/** - * 判断是否内置方法 - * - * @example - * isNative(Array.prototype.forEach); // true - * isNative(Array.prototype.map); // true - * const map = Array.prototype.map; - * isNative(map); // true - * isNative(() => {}); // false - * isNative(Object.assign); // true - * isNative(Object); // true - * isNative(Boolean); // true - * isNative(window.isNaN); // true - * isNative(isNaN); // false - */ -export function isNative(value: unknown): boolean { - const reRegExpChar = /[\\^$.*+?()[\]{}|]/g; - - const reIsNative = RegExp( - `^${Function.prototype.toString - .call(Object.prototype.hasOwnProperty) - .replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\])/g, '$1.*?')}$`, - ); - return isBroadlyObj(value) && reIsNative.test(value as any); -} - -/** - * 获取数据类型 - * - * @example - * // 六大基本类型 string boolean number object null undefined - * typeOf(''); // 'string' - * typeOf(true); // 'boolean' - * typeOf(0); // 'number' - * typeOf(undefined); // 'undefined' - * typeOf({}); // 'object' - * typeOf(null); // 'null' - * // 非6 - * typeOf(() => {}); // 'function' - * typeOf([]); // 'array' - * typeOf(NaN); // 'number' - * typeOf(/abc/); // 'regexp' - * - */ -export function typeOf(target: unknown): string { - const tp = typeof target; - if (tp !== 'object') return tp; - return Object.prototype.toString.call(target).slice(8, -1).toLowerCase(); -} - -/** - * 判断目标是否是对象,不包含Array,Function - * - * 判定方式:typeOf(target) === 'object' - * - * @example - * isObject(123123); // false - * isObject(undefined); // false - * isObject(123123); // false - * isObject(''); // false - * // null - * typeof null === 'object'; // true - * isObject(null); // false - * // array - * typeof [] === 'object'; // true - * isObject([]); // false - * // - * isObject({}); // true - * // function - * const f = () => {}; - * typeof f === 'object'; // false - * isObject(f); // false - * isObject(function () {}); // false - * - */ -export function isObject(target: unknown): target is object { - return typeOf(target) === 'object'; -} - -/** - * 判断是否类对象(object like)|广义上的对象, 包含Array,Function - * - * @alias isBroadlyObj - * - * @example - * - * isObjectLike([1, 2, 3]); // true - * isObjectLike([]); // true - * isObjectLike('1'); // false - * isObjectLike(1); // false - * isObjectLike(true); // false - * isObjectLike(undefined); // false - * isObjectLike(null); // false - * isObjectLike({}); // true - * isObjectLike(() => {}); // true - * - */ -export function isObjectLike(value: unknown): value is object { - const type = typeof value; - return value !== null && (type === 'object' || type === 'function'); -} - -/** - * @see isObjectLike - * @alias isObjectLike - */ -export const isBroadlyObj = isObjectLike; - -/** - * 判断目标是否是数组 - * - * 判定方式:typeOf(target) === 'array' - * - * 跟Array.isArray()一样 - * - * @example - * - * Array.isArray(0.12345667); // false - * isArray(0.12345667); // false - * - * Array.isArray(''); // false - * isArray(''); // false - * - * Array.isArray({}); // false - * isArray({}); // false - * - * Array.isArray({ 0: 1, 1: 2, length: 2 }); // false - * isArray({ 0: 1, 1: 2, length: 2 }); // false - * - * Array.isArray(() => {}); // false - * isArray(() => {}); // false - * - * Array.isArray(true); // false - * isArray(true); // false - * - * Array.isArray(NaN); // false - * isArray(NaN); // false - * - * Array.isArray(undefined); // false - * isArray(undefined); // false - * - * Array.isArray(null); // false - * isArray(null); // false - * - * Array.isArray([1, 2, 3]); // true - * isArray([1, 2, 3]); // true - * - * Array.isArray([]); // true - * isArray([]); // true - * - * Array.isArray(document.getElementsByClassName('test')); // false - * isArray(document.getElementsByClassName('test')); // false - */ -export function isArray(target: unknown): target is Array { - return typeOf(target) === 'array'; -} - -/** - * 类数组对象(包含数组、{0:1,1:2,length:2}、字符串) - * - * jq的实现方式 - * - * @example - * isArrayLike([1, 2, 3]); // true - * isArrayLike([]); // true - * isArrayLike({ length: 1, 0: 1 }); // true - * isArrayLike({ length: 2, 0: 1 }); // false - * isArrayLike('1'); // true - * isArrayLike(1); // false - * isArrayLike(true); // false - * isArrayLike(undefined); // false - * isArrayLike(null); // false - * isArrayLike({}); // false - * isArrayLike(() => {}); // false - * isArrayLike(document.getElementsByClassName('test')); // true - * isArrayLike(document.querySelectorAll('.test')); // true - */ -export function isArrayLike(target: any): target is ArrayLike { - // 检测target的类型 - const type = typeOf(target); - // string也是ArrayLike,但"length" in target会报错 - if (type === 'string') return true; - if ([/*"string",*/ 'null', 'undefined', 'number', 'boolean'].indexOf(type) > -1) return false; - // 如果target非null、undefined等,有length属性,则length等于target.length - // 否则,length为false - const length = !!target && 'length' in target && target.length; - // 如果target是function类型 或者是window对象 则返回false - if (type === 'function' || target === window) { - return false; - } - // target本身是数组,则返回true - // target不是数组,但有length属性且为0,例如{length : 0},则返回true - // target不是数组,但有length属性且为整数数值,target[length - 1]存在,则返回true - return ( - type === 'array' || length === 0 || (isNumber(length) && length > 0 && length - 1 in target) - ); -} - -/** - * 判断目标是否是字符串 - * - * 判定方式:typeOf(target) === 'string' - * - * ```ts - * isString(123123); // false - * isString(''); // true - * isString(``); // true - *``` - */ -export function isString(target: unknown): target is string { - return typeOf(target) === 'string'; -} - -/** - * 判定目标是否是数字 - * - * 判定方式:typeOf(target) === 'number' - * - * @example - * - * isNumber(''); // false - * isNumber({}); // false - * isNumber({ 0: 1, 1: 2, length: 2 }); // false - * isNumber(() => {}); // false - * isNumber(true); // false - * isNumber(undefined); // false - * isNumber(null); // false - * isNumber([1, 2, 3]); // false - * isNumber([]); // false - * isNumber(NaN); // true - * isNumber(123); // true - */ -export function isNumber(target: unknown): target is number { - return typeOf(target) === 'number'; -} - -/** - * 判断目标是否是函数 - * - * 判定方式:typeOf(target) === 'function' - * - * @example - * isFunction(''); // false - * isFunction(() => {}); // true - * isFunction(function () {}); // true - */ -export function isFunction(target: unknown): target is Function { - return typeOf(target) === 'function'; -} - -/** - * 判断目标是否是boolean - * - * 判定方式:typeOf(target) === 'boolean' - * - * @example - * - * isBoolean(0); // false - * isBoolean(123123); // false - * isBoolean(undefined); // false - * isBoolean(''); // false - * isBoolean(null); // false - * isBoolean([]); // false - * isBoolean({}); // false - * - */ -export function isBoolean(target: unknown): target is boolean { - return typeOf(target) === 'boolean'; -} - -/** - * 判断目标是否是undefined - * - * 判定方式:target === void 0 - * - * 最安全的方式还是直接用 typeof target === 'undefined' 判断, - * 这种方式就算target是未声明的变量也不会报错 - * - * @example - * - * isUndefined(0); // false - * isUndefined(123123); // false - * isUndefined(''); // false - * isUndefined(null); // false - * isUndefined([]); // false - * isUndefined(undefined); // true - * let a; - * isUndefined(a); // true - */ -export function isUndefined(target: any): target is undefined { - return target === void 0; -} - -/** - * - * 判断目标是否是 NaN - * - * 跟 es6 的 Number.isNaN 一致,如无必要还是直接用 Number.isNaN 更好 - * - * window.isNaN 会把非数字类型强转为数字类型再判断是不是NaN,不推荐使用 window.isNaN - * - * 判定方式:isNumber(target) && target !== target - * @example - * - * const n = NaN; - * n === n; // false - * Number.isNaN(n); // true - * isNaN(NaN); // true - * isNaN({ a: 1 }); // false - * isNaN(1); // false - * isNaN(0); // false - * isNaN(-1); // false - * isNaN(false); // false - * isNaN(undefined); // false - * Number.isNaN(undefined); // false - * isNaN(null); // false - * Number.isNaN(null); // false - * isNaN(''); // false - * isNaN({}); // false - * isNaN({ a: 1 }); // false - * isNaN([]); // false - * Number.isNaN([]); // false - * isNaN([1, 2, 3]); // false - * isNaN(['bdsdf', 12323]); // false - * isNaN('123'); // false - * isNaN('NaN'); // false - * Number.isNaN('kfsd'); // false - * window.isNaN('NaN' as any); // true - */ -export function isNaN(target: unknown): boolean { - // return String(target) === "NaN"; // "NaN" 会被判断为true - return isNumber(target) && target !== target; -} - -/** - * 判断数字是否整数 - * - * 跟 es6 的 Number.isInteger一致,推荐直接使用 Number.isInteger - * - * 判定方式:value % 1 === 0 - * @example - * - * isInteger(1); // true - * isInteger(Number.MAX_SAFE_INTEGER); // true - * isInteger(Number.MIN_SAFE_INTEGER); // true - * isInteger(0); // true - * isInteger(-0); // true - * isInteger(0.1); // false - * isInteger(-0.1); // false - * isInteger(-1.1); // false - * isInteger(NaN); // false - * isInteger(Infinity); // false - */ -export function isInteger(value: number): boolean { - return value % 1 === 0; -} - -// type t = "number" | "string" | "object" | "array" | "function" | "undefined" | "null" | "boolean" | "regexp" -/** - * 用typeIn("123", ["string", "number"]) 代替 typeOf("123") === "string" || typeOf("123") === "number" - * - * 注意: 只能判断typeOf能够判断的类型 不能判断是否是NaN 是否是"" - * - * 判定方式:types.indexOf(typeOf(target)) > -1 - * - * @example - * inTypes(0, ['string', 'number']); // true - * inTypes(0, ['string', 'function', 'object']); // false - */ -export function inTypes(target: unknown, types: string[]): boolean { - return types.indexOf(typeOf(target)) > -1; -} - -/** - * 判断目标是否是promise like - * - * 参考is-promise - * - * @example - * - * isPromiseLike({}); // false - * isPromiseLike(Promise.resolve()); // true - * isPromiseLike(null); // false - * isPromiseLike(null); // false - * isPromiseLike(undefined); // false - * isPromiseLike(0); // false - * isPromiseLike(-42); // false - * isPromiseLike(42); // false - * isPromiseLike(''); // false - * isPromiseLike('then'); // false - * isPromiseLike(false); // false - * isPromiseLike(true); // false - * isPromiseLike({}); // false - * isPromiseLike({ then: true }); // false - * isPromiseLike([]); // false - * isPromiseLike([true]); // false - * isPromiseLike(() => {}); // false - * - * const promise = { - * then: () => {}, - * }; - * isPromiseLike(promise); // true - * const fn = () => {}; - * fn.then = () => {}; - * isPromiseLike(fn); // true - */ -export function isPromiseLike(target: PromiseLike | S): target is PromiseLike { - const type = typeof target; - return ( - !!target /*null也是object*/ && - (type === 'object' || type === 'function') && - typeof (target as any).then === 'function' - ); -} - -/** - * 判断是否是空object - * - * @example - * isEmptyObject({}); // true - * isEmptyObject({ a: 1 }); // false - * isEmptyObject({ true: 1 }); // false - * isEmptyObject({ false: 1 }); // false - * isEmptyObject({ 0: 1 }); // false - * isEmptyObject({ undefined: 1 }); // false - * isEmptyObject({ null: 1 }); // false - * isEmptyObject([]); // false - * isEmptyObject(function () {}); // false - */ -export function isEmptyObject(target: object): boolean { - if (!isObject(target)) return false; - for (const i in target) { - return i === undefined; - } - return true; -} - -/** - * 判断是否是空值 undefined, null, "", [], {} ,NaN都为true - * - * @example - * - * isEmpty(NaN); // true - * isEmpty(''); // true - * isEmpty({}); // true - * isEmpty([]); // true - * isEmpty({ a: 1 }); // false - * isEmpty([1]); // false - * isEmpty(0); // false - * isEmpty(function () {}); // false - * isEmpty({ a: function () {}})); // false; - */ -export function isEmpty(target: any): boolean { - if ([undefined, null, '', NaN].includes(target)) return true; - switch (typeOf(target)) { - case 'array': - return !target.length; - case 'object': - // {a(){}} 使用JSON.stringify是会判断为空的 - // return JSON.stringify(target) === "{}"; - return isEmptyObject(target); - } - return false; -} - -/** - * 判断两个变量是否相等,值比较,如果是对象则递归判断 - * - * @example - * - * isEqual({ a: 1 }, { a: 1 }); // true - * isEqual({ a: 1 }, { a: 2 }); // false - * isEqual(1, 1); // true - * isEqual(1, 2); // false - * isEqual(1, '1'); // false - * isEqual(0, ''); // false - * isEqual(0, false); // false - * isEqual(0, null); // false - * isEqual(0, undefined); // false - * isEqual(null, undefined); // false - * isEqual(false, undefined); // false - * isEqual(false, null); // false - * isEqual(false, true); // false - * isEqual([1, 2], { 0: 1, 1: 2, length: 2 }); // false - * isEqual(() => {}, () => {}); // false - * isEqual(cm.polling, cm.polling); // true - * isEqual([1, 2], [1, 2]); // true - * isEqual(null, null); // true - * isEqual(undefined, undefined); // true - * isEqual(false, false); // true - * isEqual(NaN, NaN); // true - * isEqual('', ''); // true - */ -export function isEqual(a: any, b: any): boolean { - if (a === b) return true; - const aType = typeOf(a); - const bType = typeOf(b); - if (aType !== bType) return false; - // noinspection FallThroughInSwitchStatementJS - switch (aType) { - case 'boolean': - case 'string': - case 'function': - return false; - case 'number': - return isNaN(b); - // 只有数组或者object不相等的时候才去对比是否相等 - case 'array': - case 'object': - default: - return objectIsEqual(a, b); - } -} - -/** - * 递归判断两个对象是否相等 - * @example - * - * const obj = { a: 1 }; - * objectIsEqual(obj, obj); // true - * objectIsEqual(obj, { a: 1 }); // true - * objectIsEqual(obj, { a: 2 }); // false - */ -export function objectIsEqual(obj1: Record, obj2: Record): boolean { - if (obj1 === obj2) return true; - for (const key in obj1) { - const value1 = obj1[key]; - const value2 = obj2[key]; - if (!isEqual(value1, value2)) { - return false; - } - } - return true; -} - -/** - * 判断两个数据类型是否相等 - * - * @example - * - * isSameType(cm, cm); // true - * isSameType(1, 2); // true - * isSameType('', new String(123)); // true - * isSameType(1, NaN); // true - * isSameType(1, ''); // false - * isSameType({}, []); // false - * isSameType({}, () => 0); // false - * isSameType({}, null); // false - */ -export function isSameType(a: unknown, b: unknown): boolean { - return typeOf(a) === typeOf(b); -} - -/** - * 判断目标是否可迭代 - * - * @example - * - * isIterable(null); // false - * isIterable(undefined); // false - * isIterable(0); // false - * isIterable(true); // false - * isIterable({}); // false - * isIterable(Symbol('123')); // false - * isIterable(''); // true - * isIterable([]); // true - * isIterable([0, 1]); // true - * isIterable(new Map()); // true - * isIterable(new Set()); // true - */ -export function isIterable(target: any): target is Iterable { - try { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - for (const _ of target) { - break; - } - return true; - } catch (e) { - return false; - } -} - -/** - * 判断字符串是否是百分比 - * @example - * - * isPercent('123$%'); // false - * isPercent('3%'); // true - * isPercent('3.0%'); // true - * isPercent('3.1%'); // true - * isPercent('100%'); // true - * isPercent('100%'); // true - * isPercent('100%1'); // false - * isPercent('100% '); // true - * isPercent('10..0% '); // false - * isPercent('10.0.0% '); // false - * isPercent('.1% '); // false - * isPercent(''); // false - * isPercent(' '); // false - */ -export function isPercent(value: string): boolean { - const reg = /^\d+(\.\d+)?%$/; - return reg.test(value.trim()); -} - -/** - * 是否包含中文 - * - * @example - * - * isIncludeChinese('哈'); // true - * isIncludeChinese('哈水电费第三方'); // true - * isIncludeChinese('哈水电费1第三方'); // true - * isIncludeChinese('哈水电费.第三方'); // true - * isIncludeChinese('哈水电费_第三方'); // true - * isIncludeChinese('哈水电费 第三方'); // true - * isIncludeChinese(''); // false - * isIncludeChinese('1231'); // false - * isIncludeChinese('-='); // false - * isIncludeChinese(' '); // false - * isIncludeChinese('$$%%'); // false - */ -export function includesChinese(value: string): boolean { - return /[\u4e00-\u9fa5]/.test(value); -} - -/** - * 判断是否是数组对象 - * - * @example - * isArrayObj(Object.assign([1, 2], { b: '1', c: '2' })); // true - * isArrayObj([]); // false - * isArrayObj({ 0: 1, 1: 2, length: 2, a: 1, b: 2 }); // false - * isArrayObj(document.querySelectorAll('.test')); // false - * isArrayObj(document.getElementsByClassName('test')); // false - */ -export function isArrayObj(value: any): boolean { - const reg = /\d+/; - return isArray(value) && Object.keys(value).some((i) => !reg.test(i)); -} diff --git a/src/data-type/inTypes.ts b/src/data-type/inTypes.ts new file mode 100644 index 00000000..a39c0e54 --- /dev/null +++ b/src/data-type/inTypes.ts @@ -0,0 +1,16 @@ +import { typeOf } from './typeOf'; + +/** + * 用typeIn("123", ["string", "number"]) 代替 typeOf("123") === "string" || typeOf("123") === "number" + * + * 注意: 只能判断typeOf能够判断的类型 不能判断是否是NaN 是否是"" + * + * 判定方式:types.indexOf(typeOf(target)) > -1 + * + * @example + * inTypes(0, ['string', 'number']); // true + * inTypes(0, ['string', 'function', 'object']); // false + */ +export function inTypes(target: unknown, types: string[]): boolean { + return types.indexOf(typeOf(target)) > -1; +} diff --git a/src/data-type/includesChinese.ts b/src/data-type/includesChinese.ts new file mode 100644 index 00000000..f7ecedf8 --- /dev/null +++ b/src/data-type/includesChinese.ts @@ -0,0 +1,20 @@ +/** + * 是否包含中文 + * + * @example + * + * isIncludeChinese('哈'); // true + * isIncludeChinese('哈水电费第三方'); // true + * isIncludeChinese('哈水电费1第三方'); // true + * isIncludeChinese('哈水电费.第三方'); // true + * isIncludeChinese('哈水电费_第三方'); // true + * isIncludeChinese('哈水电费 第三方'); // true + * isIncludeChinese(''); // false + * isIncludeChinese('1231'); // false + * isIncludeChinese('-='); // false + * isIncludeChinese(' '); // false + * isIncludeChinese('$$%%'); // false + */ +export function includesChinese(value: string): boolean { + return /[\u4e00-\u9fa5]/.test(value); +} diff --git a/src/data-type/index.ts b/src/data-type/index.ts new file mode 100644 index 00000000..51d7e315 --- /dev/null +++ b/src/data-type/index.ts @@ -0,0 +1,28 @@ +export * from './isNative'; +export * from './typeOf'; +export * from './isObject'; +export * from './isObjectLike'; +export * from './isBroadlyObj'; +export * from './isArray'; +export * from './isArrayLike'; +export * from './isString'; +export * from './isNumber'; +export * from './isFunction'; +export * from './isBoolean'; +export * from './isUndefined'; +export * from './isNaN'; +export * from './isInteger'; +export * from './inTypes'; +export * from './isPromiseLike'; +export * from './isEmptyObject'; +export * from './isEmpty'; +export * from './isEqual'; +export * from './objectIsEqual'; +export * from './isSameType'; +export * from './isIterable'; +export * from './isPercent'; +export * from './includesChinese'; +export * from './isArrayObj'; +export * from './isUnavailable'; +export * from './isNullish'; +export * from './isASCIIPunctuationSymbol'; diff --git a/src/data-type/isASCIIPunctuationSymbol.ts b/src/data-type/isASCIIPunctuationSymbol.ts new file mode 100644 index 00000000..429008f5 --- /dev/null +++ b/src/data-type/isASCIIPunctuationSymbol.ts @@ -0,0 +1,28 @@ +import { inRanges } from '../array'; + +/** + * 判断字符串内是否全部都是 ascii 标点符号 + * + * 空格不算特殊符号,总共 32 个标点符号 + * + * + * @example + * + * isASCIIPunctuationSymbol('1'); // false + * isASCIIPunctuationSymbol('a'); // false + * isASCIIPunctuationSymbol('A'); // false + * isASCIIPunctuationSymbol(' '); // false + * isASCIIPunctuationSymbol('&'); // true + * isASCIIPunctuationSymbol('&^%%$'); // true + * isASCIIPunctuationSymbol('&sdf'); // false + */ +export function isASCIIPunctuationSymbol(value: string): boolean { + const len = value.length; + if (!len) return false; + + for (let i = 0; i < len; i++) { + if (!inRanges(value.charCodeAt(i), [33, 47], [58, 64], [91, 96], [123, 126])) return false; + } + + return true; +} diff --git a/src/data-type/isArray.ts b/src/data-type/isArray.ts new file mode 100644 index 00000000..3ae80ba4 --- /dev/null +++ b/src/data-type/isArray.ts @@ -0,0 +1,50 @@ +import { typeOf } from './typeOf'; + +/** + * 判断目标是否是数组 + * + * 判定方式:typeOf(target) === 'array' + * + * 跟Array.isArray()一样 + * + * @example + * + * Array.isArray(0.12345667); // false + * isArray(0.12345667); // false + * + * Array.isArray(''); // false + * isArray(''); // false + * + * Array.isArray({}); // false + * isArray({}); // false + * + * Array.isArray({ 0: 1, 1: 2, length: 2 }); // false + * isArray({ 0: 1, 1: 2, length: 2 }); // false + * + * Array.isArray(() => {}); // false + * isArray(() => {}); // false + * + * Array.isArray(true); // false + * isArray(true); // false + * + * Array.isArray(NaN); // false + * isArray(NaN); // false + * + * Array.isArray(undefined); // false + * isArray(undefined); // false + * + * Array.isArray(null); // false + * isArray(null); // false + * + * Array.isArray([1, 2, 3]); // true + * isArray([1, 2, 3]); // true + * + * Array.isArray([]); // true + * isArray([]); // true + * + * Array.isArray(document.getElementsByClassName('test')); // false + * isArray(document.getElementsByClassName('test')); // false + */ +export function isArray(target: unknown): target is Array { + return typeOf(target) === 'array'; +} diff --git a/src/data-type/isArrayLike.ts b/src/data-type/isArrayLike.ts new file mode 100644 index 00000000..fc7b2580 --- /dev/null +++ b/src/data-type/isArrayLike.ts @@ -0,0 +1,44 @@ +import { isNumber } from './isNumber'; +import { typeOf } from './typeOf'; + +/** + * 类数组对象(包含数组、{0:1,1:2,length:2}、字符串) + * + * jq的实现方式 + * + * @example + * isArrayLike([1, 2, 3]); // true + * isArrayLike([]); // true + * isArrayLike({ length: 1, 0: 1 }); // true + * isArrayLike({ length: 2, 0: 1 }); // false + * isArrayLike('1'); // true + * isArrayLike(1); // false + * isArrayLike(true); // false + * isArrayLike(undefined); // false + * isArrayLike(null); // false + * isArrayLike({}); // false + * isArrayLike(() => {}); // false + * isArrayLike(document.getElementsByClassName('test')); // true + * isArrayLike(document.querySelectorAll('.test')); // true + */ +export function isArrayLike(target: any): target is ArrayLike { + // 检测target的类型 + const type = typeOf(target); + // string也是ArrayLike,但"length" in target会报错 + if (type === 'string') return true; + if ([/*"string",*/ 'null', 'undefined', 'number', 'boolean'].indexOf(type) > -1) return false; + // 如果target非null、undefined等,有length属性,则length等于target.length + // 否则,length为false + const length = !!target && 'length' in target && target.length; + // 如果target是function类型 或者是window对象 则返回false + // eslint-disable-next-line no-restricted-globals + if (type === 'function' || target === window) { + return false; + } + // target本身是数组,则返回true + // target不是数组,但有length属性且为0,例如{length : 0},则返回true + // target不是数组,但有length属性且为整数数值,target[length - 1]存在,则返回true + return ( + type === 'array' || length === 0 || (isNumber(length) && length > 0 && length - 1 in target) + ); +} diff --git a/src/data-type/isArrayObj.ts b/src/data-type/isArrayObj.ts new file mode 100644 index 00000000..4c5fda38 --- /dev/null +++ b/src/data-type/isArrayObj.ts @@ -0,0 +1,16 @@ +import { isArray } from './isArray'; + +/** + * 判断是否是数组对象 + * + * @example + * isArrayObj(Object.assign([1, 2], { b: '1', c: '2' })); // true + * isArrayObj([]); // false + * isArrayObj({ 0: 1, 1: 2, length: 2, a: 1, b: 2 }); // false + * isArrayObj(document.querySelectorAll('.test')); // false + * isArrayObj(document.getElementsByClassName('test')); // false + */ +export function isArrayObj(value: any): boolean { + const reg = /\d+/; + return isArray(value) && Object.keys(value).some((i) => !reg.test(i)); +} diff --git a/src/data-type/isBoolean.ts b/src/data-type/isBoolean.ts new file mode 100644 index 00000000..445a7532 --- /dev/null +++ b/src/data-type/isBoolean.ts @@ -0,0 +1,21 @@ +import { typeOf } from './typeOf'; + +/** + * 判断目标是否是boolean + * + * 判定方式:typeOf(target) === 'boolean' + * + * @example + * + * isBoolean(0); // false + * isBoolean(123123); // false + * isBoolean(undefined); // false + * isBoolean(''); // false + * isBoolean(null); // false + * isBoolean([]); // false + * isBoolean({}); // false + * + */ +export function isBoolean(target: unknown): target is boolean { + return typeOf(target) === 'boolean'; +} diff --git a/src/data-type/isBroadlyObj.ts b/src/data-type/isBroadlyObj.ts new file mode 100644 index 00000000..98dd19ce --- /dev/null +++ b/src/data-type/isBroadlyObj.ts @@ -0,0 +1,7 @@ +import { isObjectLike } from './isObjectLike'; + +/** + * @see isObjectLike + * @alias isObjectLike + */ +export const isBroadlyObj = isObjectLike; diff --git a/src/data-type/isEmpty.ts b/src/data-type/isEmpty.ts new file mode 100644 index 00000000..fe1a3dcc --- /dev/null +++ b/src/data-type/isEmpty.ts @@ -0,0 +1,30 @@ +import { isEmptyObject } from './isEmptyObject'; +import { typeOf } from './typeOf'; + +/** + * 判断是否是空值 undefined, null, "", [], {} ,NaN都为true + * + * @example + * + * isEmpty(NaN); // true + * isEmpty(''); // true + * isEmpty({}); // true + * isEmpty([]); // true + * isEmpty({ a: 1 }); // false + * isEmpty([1]); // false + * isEmpty(0); // false + * isEmpty(function () {}); // false + * isEmpty({ a: function () {}})); // false; + */ +export function isEmpty(target: any): boolean { + if ([undefined, null, NaN, ''].includes(target)) return true; + switch (typeOf(target)) { + case 'array': + return !target.length; + case 'object': + // {a(){}} 使用JSON.stringify是会判断为空的 + // return JSON.stringify(target) === "{}"; + return isEmptyObject(target); + } + return false; +} diff --git a/src/data-type/isEmptyObject.ts b/src/data-type/isEmptyObject.ts new file mode 100644 index 00000000..f4728093 --- /dev/null +++ b/src/data-type/isEmptyObject.ts @@ -0,0 +1,23 @@ +import { isObject } from './isObject'; + +/** + * 判断是否是空object + * + * @example + * isEmptyObject({}); // true + * isEmptyObject({ a: 1 }); // false + * isEmptyObject({ true: 1 }); // false + * isEmptyObject({ false: 1 }); // false + * isEmptyObject({ 0: 1 }); // false + * isEmptyObject({ undefined: 1 }); // false + * isEmptyObject({ null: 1 }); // false + * isEmptyObject([]); // false + * isEmptyObject(function () {}); // false + */ +export function isEmptyObject(target: object): boolean { + if (!isObject(target)) return false; + for (const i in target) { + return i === undefined; + } + return true; +} diff --git a/src/data-type/isEqual.ts b/src/data-type/isEqual.ts new file mode 100644 index 00000000..9c43bdc8 --- /dev/null +++ b/src/data-type/isEqual.ts @@ -0,0 +1,51 @@ +import { objectIsEqual } from './objectIsEqual'; +import { typeOf } from './typeOf'; + +/** + * 判断两个变量是否相等,值比较,如果是对象则递归判断 + * + * @example + * + * isEqual({ a: 1 }, { a: 1 }); // true + * isEqual({ a: 1 }, { a: 2 }); // false + * isEqual(1, 1); // true + * isEqual(1, 2); // false + * isEqual(1, '1'); // false + * isEqual(0, ''); // false + * isEqual(0, false); // false + * isEqual(0, null); // false + * isEqual(0, undefined); // false + * isEqual(null, undefined); // false + * isEqual(false, undefined); // false + * isEqual(false, null); // false + * isEqual(false, true); // false + * isEqual([1, 2], { 0: 1, 1: 2, length: 2 }); // false + * isEqual(() => {}, () => {}); // false + * isEqual(cm.polling, cm.polling); // true + * isEqual([1, 2], [1, 2]); // true + * isEqual(null, null); // true + * isEqual(undefined, undefined); // true + * isEqual(false, false); // true + * isEqual(NaN, NaN); // true + * isEqual('', ''); // true + */ +export function isEqual(a: any, b: any): boolean { + if (a === b) return true; + const aType = typeOf(a); + const bType = typeOf(b); + if (aType !== bType) return false; + // noinspection FallThroughInSwitchStatementJS + switch (aType) { + case 'boolean': + case 'string': + case 'function': + return false; + case 'number': + return isNaN(b); + // 只有数组或者object不相等的时候才去对比是否相等 + case 'array': + case 'object': + default: + return objectIsEqual(a, b); + } +} diff --git a/src/data-type/isFunction.ts b/src/data-type/isFunction.ts new file mode 100644 index 00000000..84c49d0b --- /dev/null +++ b/src/data-type/isFunction.ts @@ -0,0 +1,15 @@ +import { typeOf } from './typeOf'; + +/** + * 判断目标是否是函数 + * + * 判定方式:typeOf(target) === 'function' + * + * @example + * isFunction(''); // false + * isFunction(() => {}); // true + * isFunction(function () {}); // true + */ +export function isFunction(target: unknown): target is T { + return typeOf(target) === 'function'; +} diff --git a/src/data-type/isInteger.ts b/src/data-type/isInteger.ts new file mode 100644 index 00000000..70457e30 --- /dev/null +++ b/src/data-type/isInteger.ts @@ -0,0 +1,22 @@ +/** + * 判断数字是否整数 + * + * 跟 es6 的 Number.isInteger一致,推荐直接使用 Number.isInteger + * + * 判定方式:value % 1 === 0 + * @example + * + * isInteger(1); // true + * isInteger(Number.MAX_SAFE_INTEGER); // true + * isInteger(Number.MIN_SAFE_INTEGER); // true + * isInteger(0); // true + * isInteger(-0); // true + * isInteger(0.1); // false + * isInteger(-0.1); // false + * isInteger(-1.1); // false + * isInteger(NaN); // false + * isInteger(Infinity); // false + */ +export function isInteger(value: number): boolean { + return value % 1 === 0; +} diff --git a/src/data-type/isIterable.ts b/src/data-type/isIterable.ts new file mode 100644 index 00000000..e5cd8f69 --- /dev/null +++ b/src/data-type/isIterable.ts @@ -0,0 +1,27 @@ +/** + * 判断目标是否可迭代 + * + * @example + * + * isIterable(null); // false + * isIterable(undefined); // false + * isIterable(0); // false + * isIterable(true); // false + * isIterable({}); // false + * isIterable(Symbol('123')); // false + * isIterable(''); // true + * isIterable([]); // true + * isIterable([0, 1]); // true + * isIterable(new Map()); // true + * isIterable(new Set()); // true + */ +export function isIterable(target: any): target is Iterable { + try { + for (const _ of target) { + break; + } + return true; + } catch (e) { + return false; + } +} diff --git a/src/data-type/isNaN.ts b/src/data-type/isNaN.ts new file mode 100644 index 00000000..d918fd50 --- /dev/null +++ b/src/data-type/isNaN.ts @@ -0,0 +1,42 @@ +import { isNumber } from './isNumber'; + +/** + * + * 判断目标是否是 NaN + * + * 跟 es6 的 Number.isNaN 一致,如无必要还是直接用 Number.isNaN 更好 + * + * window.isNaN 会把非数字类型强转为数字类型再判断是不是NaN,不推荐使用 window.isNaN + * + * 判定方式:isNumber(target) && target !== target + * @example + * + * const n = NaN; + * n === n; // false + * Number.isNaN(n); // true + * isNaN(NaN); // true + * isNaN({ a: 1 }); // false + * isNaN(1); // false + * isNaN(0); // false + * isNaN(-1); // false + * isNaN(false); // false + * isNaN(undefined); // false + * Number.isNaN(undefined); // false + * isNaN(null); // false + * Number.isNaN(null); // false + * isNaN(''); // false + * isNaN({}); // false + * isNaN({ a: 1 }); // false + * isNaN([]); // false + * Number.isNaN([]); // false + * isNaN([1, 2, 3]); // false + * isNaN(['bdsdf', 12323]); // false + * isNaN('123'); // false + * isNaN('NaN'); // false + * Number.isNaN('kfsd'); // false + * window.isNaN('NaN' as any); // true + */ +export function isNaN(target: unknown): boolean { + // return String(target) === "NaN"; // "NaN" 会被判断为true + return isNumber(target) && target !== target; +} diff --git a/src/data-type/isNative.ts b/src/data-type/isNative.ts new file mode 100644 index 00000000..679b0888 --- /dev/null +++ b/src/data-type/isNative.ts @@ -0,0 +1,27 @@ +import { isBroadlyObj } from './isBroadlyObj'; + +/** + * 判断是否内置方法 + * + * @example + * isNative(Array.prototype.forEach); // true + * isNative(Array.prototype.map); // true + * const map = Array.prototype.map; + * isNative(map); // true + * isNative(() => {}); // false + * isNative(Object.assign); // true + * isNative(Object); // true + * isNative(Boolean); // true + * isNative(window.isNaN); // true + * isNative(isNaN); // false + */ +export function isNative(value: unknown): boolean { + const reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + const reIsNative = RegExp( + `^${Function.prototype.toString + .call(Object.prototype.hasOwnProperty) + .replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\])/g, '$1.*?')}$`, + ); + return isBroadlyObj(value) && reIsNative.test(value as any); +} diff --git a/src/data-type/isNullish.ts b/src/data-type/isNullish.ts new file mode 100644 index 00000000..a702eb24 --- /dev/null +++ b/src/data-type/isNullish.ts @@ -0,0 +1,6 @@ +/** + * 判断值是否是null或undefined + */ +export function isNullish(value: unknown): value is undefined | null { + return value === null || value === undefined; +} diff --git a/src/data-type/isNumber.ts b/src/data-type/isNumber.ts new file mode 100644 index 00000000..7ae773a0 --- /dev/null +++ b/src/data-type/isNumber.ts @@ -0,0 +1,24 @@ +import { typeOf } from './typeOf'; + +/** + * 判定目标是否是数字 + * + * 判定方式:typeOf(target) === 'number' + * + * @example + * + * isNumber(''); // false + * isNumber({}); // false + * isNumber({ 0: 1, 1: 2, length: 2 }); // false + * isNumber(() => {}); // false + * isNumber(true); // false + * isNumber(undefined); // false + * isNumber(null); // false + * isNumber([1, 2, 3]); // false + * isNumber([]); // false + * isNumber(NaN); // true + * isNumber(123); // true + */ +export function isNumber(target: unknown): target is number { + return typeOf(target) === 'number'; +} diff --git a/src/data-type/isObject.ts b/src/data-type/isObject.ts new file mode 100644 index 00000000..a2305027 --- /dev/null +++ b/src/data-type/isObject.ts @@ -0,0 +1,30 @@ +import { typeOf } from './typeOf'; + +/** + * 判断目标是否是对象,不包含Array,Function + * + * 判定方式:typeOf(target) === 'object' + * + * @example + * isObject(123123); // false + * isObject(undefined); // false + * isObject(123123); // false + * isObject(''); // false + * // null + * typeof null === 'object'; // true + * isObject(null); // false + * // array + * typeof [] === 'object'; // true + * isObject([]); // false + * // + * isObject({}); // true + * // function + * const f = () => {}; + * typeof f === 'object'; // false + * isObject(f); // false + * isObject(function () {}); // false + * + */ +export function isObject(target: unknown): target is T { + return typeOf(target) === 'object'; +} diff --git a/src/data-type/isObjectLike.ts b/src/data-type/isObjectLike.ts new file mode 100644 index 00000000..4d2ffbba --- /dev/null +++ b/src/data-type/isObjectLike.ts @@ -0,0 +1,22 @@ +/** + * 判断是否类对象(object like)|广义上的对象, 包含Array,Function + * + * @alias isBroadlyObj + * + * @example + * + * isObjectLike([1, 2, 3]); // true + * isObjectLike([]); // true + * isObjectLike('1'); // false + * isObjectLike(1); // false + * isObjectLike(true); // false + * isObjectLike(undefined); // false + * isObjectLike(null); // false + * isObjectLike({}); // true + * isObjectLike(() => {}); // true + * + */ +export function isObjectLike(value: unknown): value is T { + const type = typeof value; + return value !== null && (type === 'object' || type === 'function'); +} diff --git a/src/data-type/isPercent.ts b/src/data-type/isPercent.ts new file mode 100644 index 00000000..e987f988 --- /dev/null +++ b/src/data-type/isPercent.ts @@ -0,0 +1,22 @@ +/** + * 判断字符串是否是百分比 + * @example + * + * isPercent('123$%'); // false + * isPercent('3%'); // true + * isPercent('3.0%'); // true + * isPercent('3.1%'); // true + * isPercent('100%'); // true + * isPercent('100%'); // true + * isPercent('100%1'); // false + * isPercent('100% '); // true + * isPercent('10..0% '); // false + * isPercent('10.0.0% '); // false + * isPercent('.1% '); // false + * isPercent(''); // false + * isPercent(' '); // false + */ +export function isPercent(value: string): boolean { + const reg = /^\d+(\.\d+)?%$/; + return reg.test(value.trim()); +} diff --git a/src/data-type/isPromiseLike.ts b/src/data-type/isPromiseLike.ts new file mode 100644 index 00000000..7a64ab73 --- /dev/null +++ b/src/data-type/isPromiseLike.ts @@ -0,0 +1,41 @@ +/** + * 判断目标是否是promise like + * + * 参考is-promise + * + * @example + * + * isPromiseLike({}); // false + * isPromiseLike(Promise.resolve()); // true + * isPromiseLike(null); // false + * isPromiseLike(null); // false + * isPromiseLike(undefined); // false + * isPromiseLike(0); // false + * isPromiseLike(-42); // false + * isPromiseLike(42); // false + * isPromiseLike(''); // false + * isPromiseLike('then'); // false + * isPromiseLike(false); // false + * isPromiseLike(true); // false + * isPromiseLike({}); // false + * isPromiseLike({ then: true }); // false + * isPromiseLike([]); // false + * isPromiseLike([true]); // false + * isPromiseLike(() => {}); // false + * + * const promise = { + * then: () => {}, + * }; + * isPromiseLike(promise); // true + * const fn = () => {}; + * fn.then = () => {}; + * isPromiseLike(fn); // true + */ +export function isPromiseLike(target: PromiseLike | S): target is PromiseLike { + const type = typeof target; + return ( + !!target /*null也是object*/ && + (type === 'object' || type === 'function') && + typeof (target as any).then === 'function' + ); +} diff --git a/src/data-type/isSameType.ts b/src/data-type/isSameType.ts new file mode 100644 index 00000000..d19e1b06 --- /dev/null +++ b/src/data-type/isSameType.ts @@ -0,0 +1,19 @@ +import { typeOf } from './typeOf'; + +/** + * 判断两个数据类型是否相等 + * + * @example + * + * isSameType(cm, cm); // true + * isSameType(1, 2); // true + * isSameType('', new String(123)); // true + * isSameType(1, NaN); // true + * isSameType(1, ''); // false + * isSameType({}, []); // false + * isSameType({}, () => 0); // false + * isSameType({}, null); // false + */ +export function isSameType(a: unknown, b: unknown): boolean { + return typeOf(a) === typeOf(b); +} diff --git a/src/data-type/isString.ts b/src/data-type/isString.ts new file mode 100644 index 00000000..216db9f6 --- /dev/null +++ b/src/data-type/isString.ts @@ -0,0 +1,16 @@ +import { typeOf } from './typeOf'; + +/** + * 判断目标是否是字符串 + * + * 判定方式:typeOf(target) === 'string' + * + * ```ts + * isString(123123); // false + * isString(''); // true + * isString(``); // true + *``` + */ +export function isString(target: unknown): target is string { + return typeOf(target) === 'string'; +} diff --git a/src/data-type/isUnavailable.ts b/src/data-type/isUnavailable.ts new file mode 100644 index 00000000..e5179166 --- /dev/null +++ b/src/data-type/isUnavailable.ts @@ -0,0 +1,11 @@ +/** + * 是否是不可用的值 + * + * "不可用的值"指的是null | undefined | NaN + * + * + * @param value + */ +export function isUnavailable(value: unknown): boolean { + return [undefined, null, NaN].includes(value as any); +} diff --git a/src/data-type/isUndefined.ts b/src/data-type/isUndefined.ts new file mode 100644 index 00000000..ddc48618 --- /dev/null +++ b/src/data-type/isUndefined.ts @@ -0,0 +1,22 @@ +/** + * 判断目标是否是undefined + * + * 判定方式:target === void 0 + * + * 最安全的方式还是直接用 typeof target === 'undefined' 判断, + * 这种方式就算target是未声明的变量也不会报错 + * + * @example + * + * isUndefined(0); // false + * isUndefined(123123); // false + * isUndefined(''); // false + * isUndefined(null); // false + * isUndefined([]); // false + * isUndefined(undefined); // true + * let a; + * isUndefined(a); // true + */ +export function isUndefined(target: any): target is undefined { + return target === void 0; +} diff --git a/src/data-type/objectIsEqual.ts b/src/data-type/objectIsEqual.ts new file mode 100644 index 00000000..759a1b0f --- /dev/null +++ b/src/data-type/objectIsEqual.ts @@ -0,0 +1,22 @@ +import { isEqual } from './isEqual'; + +/** + * 递归判断两个对象是否相等 + * @example + * + * const obj = { a: 1 }; + * objectIsEqual(obj, obj); // true + * objectIsEqual(obj, { a: 1 }); // true + * objectIsEqual(obj, { a: 2 }); // false + */ +export function objectIsEqual(obj1: Record, obj2: Record): boolean { + if (obj1 === obj2) return true; + for (const key in obj1) { + const value1 = obj1[key]; + const value2 = obj2[key]; + if (!isEqual(value1, value2)) { + return false; + } + } + return true; +} diff --git a/src/data-type/typeOf.ts b/src/data-type/typeOf.ts new file mode 100644 index 00000000..af79f08a --- /dev/null +++ b/src/data-type/typeOf.ts @@ -0,0 +1,23 @@ +/** + * 获取数据类型 + * + * @example + * // 六大基本类型 string boolean number object null undefined + * typeOf(''); // 'string' + * typeOf(true); // 'boolean' + * typeOf(0); // 'number' + * typeOf(undefined); // 'undefined' + * typeOf({}); // 'object' + * typeOf(null); // 'null' + * // 非6 + * typeOf(() => {}); // 'function' + * typeOf([]); // 'array' + * typeOf(NaN); // 'number' + * typeOf(/abc/); // 'regexp' + * + */ +export function typeOf(target: unknown): string { + const tp = typeof target; + if (tp !== 'object') return tp; + return Object.prototype.toString.call(target).slice(8, -1).toLowerCase(); +} diff --git a/src/decorator/Debounce.ts b/src/decorator/Debounce.ts new file mode 100644 index 00000000..88746d19 --- /dev/null +++ b/src/decorator/Debounce.ts @@ -0,0 +1,36 @@ +import type { OmitFirstParameters } from '@tool-pack/types'; +import { decoratorfy } from './decoratorfy'; +import { debounce } from '../common'; + +/** + * 防抖装饰器 + * + * @constructor + * + * @see debounce + * + * @example + * + * class Test { + * times = 0; + * time = 0; + * value: string | number = ''; + * + * @Debounce(1000) + * test(value: string | number) { + * this.times++; + * this.time = Date.now(); + * this.value = value; + * } + * } + * + * const t = new Test(); + * + * t.test(1); + * t.test(2); + * t.test(3); + * t.test(4); + * + */ +export const Debounce = (...args: OmitFirstParameters) => + decoratorfy((descriptor) => debounce(descriptor.value, ...args)); diff --git a/src/decorator.ts b/src/decorator/Polling.ts similarity index 53% rename from src/decorator.ts rename to src/decorator/Polling.ts index 5513fb9e..f4696c58 100644 --- a/src/decorator.ts +++ b/src/decorator/Polling.ts @@ -1,93 +1,7 @@ -import { debounce, polling, throttle } from './common'; import type { OmitFirstParameters } from '@tool-pack/types'; +import { decoratorfy } from './decoratorfy'; +import { polling } from '../common'; -/** - * 把一个函数转变为装饰器 - * - * @see Debounce - * @see Polling - * - * @example - * - * // 防抖装饰器 - * const Debounce = (...args: OmitFirstParameters) => decoratorfy((descriptor) => debounce(descriptor.value, ...args)); - * - */ -export function decoratorfy(callback: (descriptor: PropertyDescriptor, target: any) => Function) { - return function (target: any, _propertyKey: string, descriptor: PropertyDescriptor) { - // 在babel的网站编译的是target包含key,descriptor - if (target.descriptor) { - descriptor = target.descriptor; - } - descriptor.value = callback(descriptor, target); - }; -} - -/** - * 防抖装饰器 - * - * @constructor - * - * @see debounce - * - * @example - * - * class Test { - * times = 0; - * time = 0; - * value: string | number = ''; - * - * @Debounce(1000) - * test(value: string | number) { - * this.times++; - * this.time = Date.now(); - * this.value = value; - * } - * } - * - * const t = new Test(); - * - * t.test(1); - * t.test(2); - * t.test(3); - * t.test(4); - * - */ -export const Debounce = (...args: OmitFirstParameters) => - decoratorfy((descriptor) => debounce(descriptor.value, ...args)); - -/** - * 节流装饰器 - * - * @constructor - * - * @see throttle - * - * @example - * - * class Test { - * times = 0; - * time = 0; - * value: string | number = ''; - * - * @Throttle(100) - * test(value: string | number) { - * this.times++; - * this.time = Date.now(); - * this.value = value; - * } - * } - * - * const t = new Test(); - * - * t.test(1); - * t.test(2); - * t.test(3); - * t.test(4); - * - */ -export const Throttle = (...args: OmitFirstParameters) => - decoratorfy((descriptor) => throttle(descriptor.value, ...args)); // Throttle(1, () => 0); /** * 比setInterval好的地方在于使用promise判断一回执行完毕情况 @@ -189,25 +103,3 @@ export const Polling = (...args: OmitFirstParameters) => } return handle; }); - -/* -export function Singleton(constructor: T): any { - class newClass extends constructor { - private static instance?: newClass; - - private constructor(...args: any[]) { - super(...args); - } - - public static get Ins(): newClass { - if (!newClass.instance) { - newClass.instance = new newClass(); - } - return newClass.instance; - } - - } - - return newClass; -} -*/ diff --git a/src/decorator/Throttle.ts b/src/decorator/Throttle.ts new file mode 100644 index 00000000..7a6f893b --- /dev/null +++ b/src/decorator/Throttle.ts @@ -0,0 +1,36 @@ +import type { OmitFirstParameters } from '@tool-pack/types'; +import { decoratorfy } from './decoratorfy'; +import { throttle } from '../common'; + +/** + * 节流装饰器 + * + * @constructor + * + * @see throttle + * + * @example + * + * class Test { + * times = 0; + * time = 0; + * value: string | number = ''; + * + * @Throttle(100) + * test(value: string | number) { + * this.times++; + * this.time = Date.now(); + * this.value = value; + * } + * } + * + * const t = new Test(); + * + * t.test(1); + * t.test(2); + * t.test(3); + * t.test(4); + * + */ +export const Throttle = (...args: OmitFirstParameters) => + decoratorfy((descriptor) => throttle(descriptor.value, ...args)); diff --git a/src/decorator/decoratorfy.ts b/src/decorator/decoratorfy.ts new file mode 100644 index 00000000..650efc5f --- /dev/null +++ b/src/decorator/decoratorfy.ts @@ -0,0 +1,21 @@ +/** + * 把一个函数转变为装饰器 + * + * @see Debounce + * @see Polling + * + * @example + * + * // 防抖装饰器 + * const Debounce = (...args: OmitFirstParameters) => decoratorfy((descriptor) => debounce(descriptor.value, ...args)); + * + */ +export function decoratorfy(callback: (descriptor: PropertyDescriptor, target: any) => Function) { + return function (target: any, _propertyKey: string, descriptor: PropertyDescriptor) { + // 在babel的网站编译的是target包含key,descriptor + if (target.descriptor) { + descriptor = target.descriptor; + } + descriptor.value = callback(descriptor, target); + }; +} diff --git a/src/decorator/index.ts b/src/decorator/index.ts new file mode 100644 index 00000000..93ab9741 --- /dev/null +++ b/src/decorator/index.ts @@ -0,0 +1,4 @@ +export * from './decoratorfy'; +export * from './Debounce'; +export * from './Throttle'; +export * from './Polling'; diff --git a/src/generator.ts b/src/generator.ts deleted file mode 100644 index 42e9732b..00000000 --- a/src/generator.ts +++ /dev/null @@ -1,283 +0,0 @@ -import { randomInt } from './random'; - -// 使用下面的生成器代替 -// /** -// * 创建一个自增id的闭包函数 -// * @param init {number} 初始值 -// * @param step {number} 每次增加的值 -// */ -// export function createIdFn(init = 0, step = 1) { -// let id = init; -// return function getId(_step = step) { -// const current = id; -// id += _step; -// return current; -// }; -// } - -/** - * 创建一个自增id生成器 - * - * 第一次next传值是无效的 解决方法参考https://es6.ruanyifeng.com/#docs/generator#next-%E6%96%B9%E6%B3%95%E7%9A%84%E5%8F%82%E6%95%B0 - * - * @example - * - * // ----------- 什么参数都不传 ----------- - * const id = idGen(); - * id.next().value; // 0 - * id.next().value; // 1 - * id.next().value; // 2 - * id.next(10).value; // 12 - * id.next().value; // 13 - * - * - * // ----------- 传init与step ----------- - * const id = idGen(10, 2); - * id.next().value; // 10 - * id.next(3).value; // 13 - * id.next(10).value; // 23 - * id.next().value; // 25 - * - * // ----------- next第一次传值无效 ----------- - * - * const id = idGen(); - * id.next(11).value; // 0 // 第一次next传值无效,因为next只能传给下一个yield,而第一次之前没有yield - * id.next().value; // 1 - * id.next().value; // 2 - * - * // ----------- 使用for of迭代 ----------- - * const iter = idGen(); - * let curId = 0; - * for (const id of iter) { - * id; // curId++ - * if (id > 10) { - * iter.return(); // 使用Generator.prototype.return强制中断生成器 - * } - * } - * - * // ----------- 设置max ----------- - * const gen = idGen(0, 1, 3); - * const ids: number[] = []; - * for (const id of gen) { - * ids.push(id); - * } - * - * ids; // [0, 1, 2] - * gen.next(); // { done: true, value: undefined } - * - * - * // ----------- 倒序生成 ----------- - * const gen = idGen(2, -1, -1); - * const ids: number[] = []; - * for (const id of gen) { - * ids.push(id); - * } - * - * ids; // [0, 1, 2].reverse() - * gen.next(); // { done: true, value: undefined } - * - * - * - * @param [init = 0] 初始值 - * @param [step = 1] 每次增加的值 - * @param [end = Number.MAX_SAFE_INTEGER] 最大值;包左不包右原则,所以最后一个值是小于end的 - */ -export function* idGen( - init = 0, - step = 1, - end = Number.MAX_SAFE_INTEGER, -): Generator { - let id = init; - const handle = init < end ? () => id < end : () => id > end; - while (handle()) { - const _step = (yield id) || step; - id += _step; - } -} - -/** - * 创建一个时间累计生成器 - * --- - * createTimeCountUp的Generator版本 - * @see createTimeCountUp - * - * @example - * const t = timeCountUpGen(); - * - * t.next().value; // 0 - * - * await sleep(20); - * t.next().value; // 20 <= t.next().value <= 30 - * - * await sleep(30); - * const beforePause = t.next().value; // 50 <= t.next().value <= 60 - * - * // 暂停 - * t.next(false); - * await sleep(10); - * t.next().value === beforePause; // true - * t.next().value; // 50 <= t.next().value <= 60 - * - * // 继续 - * t.next(true); - * await sleep(10); - * t.next().value; // 60 <= t.next().value <= 70 - * - * // 停止 - * t.return(); - * t.next() // { done: true, value: undefined } - * - * @example - * // 使用for...of - * async function test(){ - * let count = 0; - * const t = timeCountUpGen(); - * for(const v of t){ - * console.log(v); - * await sleep(1000); - * count++ >= 10 && t.return(); - * } - * } - * test(); - * // outputs - * // 1010 - * // 2015 - * // 3024 - * // 4031 - * // 5040 - * // 6048 - * // 7057 - * // 8065 - * // 9073 - * // 10081 - */ -export function createTimeCountUpGen(): Generator { - const startTime = Date.now(); - const pauseState = { - total: 0, - startTime: 0, - }; - - function pause(): void { - // 判断是否已经暂停了,避免二次暂停bug - if (pauseState.startTime === 0) pauseState.startTime = Date.now(); - } - function play(): void { - // 判断是否已经暂停了,避免二次play bug - if (pauseState.startTime === 0) return; - pauseState.total += Date.now() - pauseState.startTime; - pauseState.startTime = 0; - } - - function* g(): ReturnType { - while (true) { - const endTime = pauseState.startTime ? pauseState.startTime : Date.now(); - const nextValue = yield endTime - startTime - pauseState.total; - if (nextValue === void 0) continue; - nextValue ? play() : pause(); - } - } - return g(); -} - -/** - * 创建一个倒计时生成器 - * --- - * createTimeCountDown的生成器版本 - * - * @see createTimeCountDown - * @see createTimeCountUpGen - * - * @example - * - * const t = createTimeCountDownGen(100); - * - * t.next().value; // 95 <= %t.next().value <= 100 - * - * await sleep(10); - * t.next().value; // 85 <= %t.next().value <= 95 - * - * await sleep(10); - * t.next().value; // 75 <= %t.next().value <= 85 - * - * // 暂停 - * const beforePause = t.next(false).value; - * await sleep(20); - * t.next().value; // beforePause - * - * await sleep(20); - * t.next().value; // beforePause - * t.next().value; // 75 <= %t.next().value <= 85 - * - * // 继续 - * t.next(true).value; // 75 <= t.next(true).value <= 85 - * await sleep(10); - * t.next().value; // 65 <= %t.next().value <= 75 - * - * await sleep(10); - * t.next().value; // 55 <= %t.next().value <= 65 - * - * // 停止 - * t.return(); - * t.next(); // { value: undefined, done: true } - * - * @example - * // for...of - * async function test() { - * console.time('t'); - * for (const v of createTimeCountDownGen(10000)) { - * console.log('t', v); - * await sleep(1000); - * } - * console.timeEnd('t'); - * } - * - * test() - * // outputs - * // t 9999 - * // t 8997 - * // t 7987 - * // t 6977 - * // t 5970 - * // t 4961 - * // t 3954 - * // t 2945 - * // t 1938 - * // t 933 - * // t: 10077.828369140625 ms - * - * @param timeout 最大时间 - */ -export function createTimeCountDownGen(timeout: number): ReturnType { - const timeCountUp = createTimeCountUpGen(); - - function* g(): ReturnType { - let result: number; - while ((result = timeout - (timeCountUp.next().value as number)) > 0) { - const nextValue = yield result; - if (nextValue === void 0) continue; - timeCountUp.next(nextValue); - } - } - return g(); -} - -/** - * 数组随机item生成器,直到遍历完为止 - * - * @example - * - * const rand = randomItemGen([1, 2, 3]); - * rand.next().value; // 1|2|3 - * rand.next().value; // 1|2|3 - * rand.next().value; // 1|2|3 - * rand.next(); // { done: true, value: undefined } - * - */ -export function* randomItemGen(arr: T[]): Generator { - const list = arr.slice(); - while (list.length) { - const index = randomInt(list.length); - yield list.splice(index, 1)[0] as T; - } -} diff --git a/src/generator/createTimeCountDownGen.ts b/src/generator/createTimeCountDownGen.ts new file mode 100644 index 00000000..42a1c9e6 --- /dev/null +++ b/src/generator/createTimeCountDownGen.ts @@ -0,0 +1,82 @@ +import { createTimeCountUpGen } from './createTimeCountUpGen'; + +/** + * 创建一个倒计时生成器 + * --- + * createTimeCountDown的生成器版本 + * + * @see createTimeCountDown + * @see createTimeCountUpGen + * + * @example + * + * const t = createTimeCountDownGen(100); + * + * t.next().value; // 95 <= %t.next().value <= 100 + * + * await sleep(10); + * t.next().value; // 85 <= %t.next().value <= 95 + * + * await sleep(10); + * t.next().value; // 75 <= %t.next().value <= 85 + * + * // 暂停 + * const beforePause = t.next(false).value; + * await sleep(20); + * t.next().value; // beforePause + * + * await sleep(20); + * t.next().value; // beforePause + * t.next().value; // 75 <= %t.next().value <= 85 + * + * // 继续 + * t.next(true).value; // 75 <= t.next(true).value <= 85 + * await sleep(10); + * t.next().value; // 65 <= %t.next().value <= 75 + * + * await sleep(10); + * t.next().value; // 55 <= %t.next().value <= 65 + * + * // 停止 + * t.return(); + * t.next(); // { value: undefined, done: true } + * + * @example + * // for...of + * async function test() { + * console.time('t'); + * for (const v of createTimeCountDownGen(10000)) { + * console.log('t', v); + * await sleep(1000); + * } + * console.timeEnd('t'); + * } + * + * test() + * // outputs + * // t 9999 + * // t 8997 + * // t 7987 + * // t 6977 + * // t 5970 + * // t 4961 + * // t 3954 + * // t 2945 + * // t 1938 + * // t 933 + * // t: 10077.828369140625 ms + * + * @param timeout 最大时间 + */ +export function createTimeCountDownGen(timeout: number): ReturnType { + const timeCountUp = createTimeCountUpGen(); + function* g(): ReturnType { + let result: number; + while ((result = timeout - (timeCountUp.next().value as number)) > 0) { + const nextValue = yield result; + if (nextValue === void 0) continue; + timeCountUp.next(nextValue); + } + } + return g(); +} diff --git a/src/generator/createTimeCountUpGen.ts b/src/generator/createTimeCountUpGen.ts new file mode 100644 index 00000000..acb9ee9d --- /dev/null +++ b/src/generator/createTimeCountUpGen.ts @@ -0,0 +1,82 @@ +/** + * 创建一个时间累计生成器 + * --- + * createTimeCountUp的Generator版本 + * @see createTimeCountUp + * + * @example + * const t = timeCountUpGen(); + * + * t.next().value; // 0 + * + * await sleep(20); + * t.next().value; // 20 <= t.next().value <= 30 + * + * await sleep(30); + * const beforePause = t.next().value; // 50 <= t.next().value <= 60 + * + * // 暂停 + * t.next(false); + * await sleep(10); + * t.next().value === beforePause; // true + * t.next().value; // 50 <= t.next().value <= 60 + * + * // 继续 + * t.next(true); + * await sleep(10); + * t.next().value; // 60 <= t.next().value <= 70 + * + * // 停止 + * t.return(); + * t.next() // { done: true, value: undefined } + * + * @example + * // 使用for...of + * async function test(){ + * let count = 0; + * const t = timeCountUpGen(); + * for(const v of t){ + * console.log(v); + * await sleep(1000); + * count++ >= 10 && t.return(); + * } + * } + * test(); + * // outputs + * // 1010 + * // 2015 + * // 3024 + * // 4031 + * // 5040 + * // 6048 + * // 7057 + * // 8065 + * // 9073 + * // 10081 + */ +export function createTimeCountUpGen(): Generator { + const startTime = Date.now(); + const pauseState = { + startTime: 0, + total: 0, + }; + function pause(): void { + // 判断是否已经暂停了,避免二次暂停bug + if (pauseState.startTime === 0) pauseState.startTime = Date.now(); + } + function play(): void { + // 判断是否已经暂停了,避免二次play bug + if (pauseState.startTime === 0) return; + pauseState.total += Date.now() - pauseState.startTime; + pauseState.startTime = 0; + } + function* g(): ReturnType { + while (true) { + const endTime = pauseState.startTime ? pauseState.startTime : Date.now(); + const nextValue = yield endTime - startTime - pauseState.total; + if (nextValue === void 0) continue; + nextValue ? play() : pause(); + } + } + return g(); +} diff --git a/src/generator/idGen.ts b/src/generator/idGen.ts new file mode 100644 index 00000000..06d4b6cd --- /dev/null +++ b/src/generator/idGen.ts @@ -0,0 +1,94 @@ +// 使用下面的生成器代替 +// /** +// * 创建一个自增id的闭包函数 +// * @param init {number} 初始值 +// * @param step {number} 每次增加的值 +// */ +// export function createIdFn(init = 0, step = 1) { +// let id = init; +// return function getId(_step = step) { +// const current = id; +// id += _step; +// return current; +// }; +// } + +/** + * 创建一个自增id生成器 + * + * 第一次next传值是无效的 解决方法参考https://es6.ruanyifeng.com/#docs/generator#next-%E6%96%B9%E6%B3%95%E7%9A%84%E5%8F%82%E6%95%B0 + * + * @example + * + * // ----------- 什么参数都不传 ----------- + * const id = idGen(); + * id.next().value; // 0 + * id.next().value; // 1 + * id.next().value; // 2 + * id.next(10).value; // 12 + * id.next().value; // 13 + * + * + * // ----------- 传init与step ----------- + * const id = idGen(10, 2); + * id.next().value; // 10 + * id.next(3).value; // 13 + * id.next(10).value; // 23 + * id.next().value; // 25 + * + * // ----------- next第一次传值无效 ----------- + * + * const id = idGen(); + * id.next(11).value; // 0 // 第一次next传值无效,因为next只能传给下一个yield,而第一次之前没有yield + * id.next().value; // 1 + * id.next().value; // 2 + * + * // ----------- 使用for of迭代 ----------- + * const iter = idGen(); + * let curId = 0; + * for (const id of iter) { + * id; // curId++ + * if (id > 10) { + * iter.return(); // 使用Generator.prototype.return强制中断生成器 + * } + * } + * + * // ----------- 设置max ----------- + * const gen = idGen(0, 1, 3); + * const ids: number[] = []; + * for (const id of gen) { + * ids.push(id); + * } + * + * ids; // [0, 1, 2] + * gen.next(); // { done: true, value: undefined } + * + * + * // ----------- 倒序生成 ----------- + * const gen = idGen(2, -1, -1); + * const ids: number[] = []; + * for (const id of gen) { + * ids.push(id); + * } + * + * ids; // [0, 1, 2].reverse() + * gen.next(); // { done: true, value: undefined } + * + * + * + * @param [init = 0] 初始值 + * @param [step = 1] 每次增加的值 + * @param [end = Number.MAX_SAFE_INTEGER] 最大值;包左不包右原则,所以最后一个值是小于end的 + */ +export function* idGen( + init = 0, + step = 1, + end = Number.MAX_SAFE_INTEGER, +): Generator { + let id = init; + const handle = init < end ? () => id < end : () => id > end; + while (handle()) { + const _step = (yield id) || step; + id += _step; + } +} diff --git a/src/generator/index.ts b/src/generator/index.ts new file mode 100644 index 00000000..e326b8f7 --- /dev/null +++ b/src/generator/index.ts @@ -0,0 +1,4 @@ +export * from './idGen'; +export * from './createTimeCountUpGen'; +export * from './createTimeCountDownGen'; +export * from './randomItemGen'; diff --git a/src/generator/randomItemGen.ts b/src/generator/randomItemGen.ts new file mode 100644 index 00000000..b930cb51 --- /dev/null +++ b/src/generator/randomItemGen.ts @@ -0,0 +1,21 @@ +import { randomInt } from '../random'; + +/** + * 数组随机item生成器,直到遍历完为止 + * + * @example + * + * const rand = randomItemGen([1, 2, 3]); + * rand.next().value; // 1|2|3 + * rand.next().value; // 1|2|3 + * rand.next().value; // 1|2|3 + * rand.next(); // { done: true, value: undefined } + * + */ +export function* randomItemGen(arr: T[]): Generator { + const list = arr.slice(); + while (list.length) { + const index = randomInt(list.length); + yield list.splice(index, 1)[0] as T; + } +} diff --git a/src/index.ts b/src/index.ts index d485f7b2..4335d94a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,3 +14,5 @@ export * from './decorator'; export * from './url'; export * from './bezier'; export * from './generator'; +export * from './array-buffer'; +export * from './base64'; diff --git a/src/index.typedoc.ts b/src/index.typedoc.ts index 3660c408..f4a98e46 100644 --- a/src/index.typedoc.ts +++ b/src/index.typedoc.ts @@ -67,3 +67,11 @@ export * as Bezier from './bezier'; * 生成器相关工具 */ export * as Generator from './generator'; +/** + * ArrayBuffer 相关 + */ +export * as ArrayBufferUtils from './array-buffer'; +/** + * Base64 相关 + */ +export * as Base64 from './base64'; diff --git a/src/number.ts b/src/number.ts deleted file mode 100644 index 8eae9ae4..00000000 --- a/src/number.ts +++ /dev/null @@ -1,380 +0,0 @@ -import { isNumber } from './data-type'; -import { inRange } from './array'; -import { Tuple } from '@tool-pack/types'; - -/** - * 把错误的数据转正 from number-precision - * - * @example - * - * 1.0000000000041083; // 1.0000000000041083 - * strip(1.0000000000041083); // 1 - * - * 1.0000000000001563; // 1.0000000000001563 - * strip(1.0000000000001563); // 1 - * - * 1.0000000000001563; // 1.0000000000001563 - * strip(1.0000000000001563); // 1 - * - * strip(0.09999999999999998); // 0.1 - * - */ -export function strip(num: number, precision = 12): number { - return +parseFloat(num.toPrecision(precision)); -} - -/** - * 科学计数法转普通小数 - * - * @note 不能转太大的数 比如大于Number.MAX_SAFE_INTEGER - * - * @example - * - * toNonExponential(1e2); // '100' - * toNonExponential(0.0000001); // '0.0000001' - * toNonExponential(0.0000000001); // '0.0000000001' - * - * const num = 100_000_000_000_000_000_000_000; - * num.toString(); // '1e+23' - * num > Number.MAX_SAFE_INTEGER; // true - * toNonExponential(num); // '1e+23' - * - * const num2 = (1_000_000_000_000_000).toExponential(); - * num2.toString(); // '1e+15' - * +num2 > Number.MAX_SAFE_INTEGER; // false - * toNonExponential(+num2); // '1000000000000000' - * - */ -export function toNonExponential(num: number): string { - // toExponential 转为科学计数法 - // const m = num.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/); - const sNum = String(num); - const m = sNum.match(/\d(?:\.(\d*))?e([+-]\d+)/); - if (num > Number.MAX_SAFE_INTEGER || !m || m.length < 3) return sNum; - return num.toFixed(Math.max(0, (m[1] || '').length - Number(m[2]))); -} - -/** - * 获取小数点后面数字的长度,支持科学计数法 - * - * from number-precision - * - * @example - * - * // 数字 - * getNumberLenAfterDot(0.12345667); // 8 - * getNumberLenAfterDot(12345); // 0 - * - * // 字符串 - * getNumberLenAfterDot('0.123456789'); // 9 - * getNumberLenAfterDot('abc'); // 0 - * - * // 科学计数法 - * getNumberLenAfterDot(1.123e5); // 0 - * getNumberLenAfterDot(1.123e2); // 1 - * getNumberLenAfterDot(1.123e2); // 1 - * getNumberLenAfterDot(1e2); // 0 - * getNumberLenAfterDot(1e-2); // 2 - * - */ -export function getNumberLenAfterDot(num: number | string): number { - Number(1000).toPrecision(); - const eSplit = String(num).split(/[eE]/); - const len = (eSplit[0]?.split('.')[1] || '').length - +(eSplit[1] || 0); - return len > 0 ? len : 0; -} - -/** - * 获取两位数乘后都能为整数的数字 - * - * @example - * - * getCommonPow(0.1, 0.11); // 100 - * getCommonPow(1.123e2, 0.11); // 100 - * getCommonPow(1e2, 10); // 1 - * getCommonPow(1e-2, 10); // 100 - * getCommonPow(10.1, 1.00001); // 100000 - * - */ -export function getCommonPow(a: number, b: number): number { - const aLen = getNumberLenAfterDot(a); - const bLen = getNumberLenAfterDot(b); - return Math.pow(10, Math.max(aLen, bLen)); -} - -/** - * @see plus - * @see divide - * @see times - * @see divide - */ -export function calcArr( - num: number, - nums: number[], - callback: (a: number, b: number, pow: number) => number, -): number { - return nums.reduce((a, b) => { - const pow = getCommonPow(a, b); - return callback(a, b, pow); - }, num); -} - -/** - * 加法计算,直接计算有精度问题 - * - * // 0.1 + 0.2 = 0.30000000000000004 - * 0.1 + 0.2; // 0.30000000000000004 - * plus(0.1, 0.2); // 0.3 - * - */ -export function plus(num: number, ...nums: Array) { - return calcArr(num, nums, (a, b, pow) => (a * pow + b * pow) / pow); -} - -/** - * 减法计算,直接计算有精度问题 - * - * @example - * - * // 0.3 - 0.1 = 0.19999999999999998 - * 0.3 - 0.1; // 0.19999999999999998 - * minus(0.3, 0.1); // 0.2 - * - */ -export function minus(num: number, ...nums: Array) { - return calcArr(num, nums, (a, b, pow) => (a * pow - b * pow) / pow); -} - -/** - * 乘法计算,直接计算有精度问题 - * - * @example - * - * // 0.2 * 0.1 = 0.020000000000000004 - * 0.2 * 0.1; // 0.020000000000000004 - * times(0.2, 0.1); // 0.02 - * - */ -export function times(num: number, ...nums: Array) { - return calcArr(num, nums, (a, b, pow) => (pow * a * (b * pow)) / (pow * pow)); -} - -/** - * 除法计算,直接计算有精度问题 - * - * @example - * - * // 0.3 / 0.1 = 2.9999999999999996 - * 0.3 / 0.1; // 2.9999999999999996 - * divide(0.3, 0.1); // 3 - * - */ -export function divide(num: number, ...nums: Array) { - return calcArr(num, nums, (a, b, pow) => (a * pow) / (b * pow)); -} - -/** - * 安全数字 - * - * 如果value小于min,那么返回min,如果value大于max,那么返回max,否则返回value - * - * @example - * - * getSafeNum(0); // 0 - * getSafeNum(0, 1, 100); // 1 - * getSafeNum(50, 1, 100); // 50 - * getSafeNum(101, 1, 100); // 100 - * getSafeNum(101, 1); // 101 - * - * @param value 数字 - * @param [min=-Infinity] 默认-Infinity - * @param [max=Infinity] 默认Infinity - */ -export function getSafeNum(value: number, min = -Infinity, max = Infinity): number { - return Math.max(min, Math.min(value, max)); -} - -/** - * number保留小数位,原来的函数四舍五入不准确 - * - * 原来的toFixed可以把科学计数法的小数,给转成普通小数字符串 - * - * @example - * - * // Number.prototype.toFixed自带四舍五入 - * (0.45).toFixed(1); // '0.5' - * // numToFixed默认使用四舍五入,跟Number.prototype.toFixed保持一致 - * numToFixed(0.45, 1); // '0.5' - * // 关闭四舍五入 - * numToFixed(0.45, 1, false); // '0.4' - * - * @param num 原数字 - * @param [fractionDigits = 0] 保留小数位 - * @param [rounding = true] 是否四舍五入 - */ -export function numToFixed(num: number, fractionDigits = 0, rounding = true): string { - if (!isNumber(fractionDigits) || !inRange(fractionDigits, [0, 100])) { - throw new TypeError('numToFixed() fractionDigits argument must be between 0 and 100'); - } - - if (fractionDigits === 0) return String(~~num); - - const base = 10; - // 加1 四舍五入 - const pow = base ** (fractionDigits + 1); - num = ~~(num * pow); - if (rounding && num) { - // num为0的时候位数已经不对了 - num += 5; - } - num /= pow; - - const split = String(num).split('.'); - const digits = (split[1] || '').substr(0, fractionDigits).padEnd(fractionDigits, '0'); - return split[0] + '.' + digits; -} - -/** - * 代替for循环 - * - * @example - * - * const arr: number[] = []; - * forEachNum(3, (index) => arr.push(index)); - * arr; // [0, 1, 2] - * forEachNum(7, (index) => arr.push(index)); - * arr.length; // 10 - * forEachNum(3, (index): void | false => { - * arr.push(index); - * if (index === 1) return false; - * }); - * arr; // [0, 1, 2, 0, 1, 2, 3, 4, 5, 6, 0, 1] - */ -export function forEachNum(len: number, callback: (index: number) => any | false) { - for (let i = 0; i < len; i++) { - if (callback(i) !== false) continue; - break; - } -} - -/** - * 代替for循环 - * - * forEachNum的反向遍历版本 - * - * @see forEachNum - * - * @example - * - * const arr: number[] = []; - * forEachNumRight(3, (index) => arr.push(index)); - * arr; // [0, 1, 2].reverse() - * forEachNumRight(7, (index) => arr.push(index)); - * arr.length; // 10 - * forEachNumRight(3, (index): void | false => { - * arr.push(index); - * if (index === 1) return false; - * }); - * arr; // [...[0, 1, 2].reverse(), ...[0, 1, 2, 3, 4, 5, 6].reverse(), 2, 1] - * - */ -export function forEachNumRight(len: number, callback: (index: number) => any | false) { - for (let i = len - 1; i >= 0; i--) { - if (callback(i) === false) break; - } -} - -/** - * 阿拉伯数字转为中文数字 - * @param value 数字 - * @param {{}} options 可选参数 - * @param [options.units=['', '十', '百', '千', '万', '十', '百', '千', '亿']] 单位 - * @param [options.numbers=['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']] 数字映射 - */ -export function numberToChinese( - value: number, - options: { units?: string[]; numbers?: Tuple } = {}, -): string { - const { - numbers = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'], - units = ['', '十', '百', '千', '万', '十', '百', '千', '亿'], - } = options; - - const unitLen = units.length; - let key = ~~value; - let chineseNumber = ''; - let times = 0; - - // 个位数 - if (value >= 0 && value < 10) return numbers[value] as string; - while (key >= 1 && times < unitLen) { - const unit = units[times]; - // 11 % 10 => 一 - const end = numbers[key % 10]; - // 101 0没有单位 - if (end !== numbers[0]) { - chineseNumber = unit + chineseNumber; - } - // 11 => 一十一 => 十一 - if (!(key === 1 && times === 1)) { - chineseNumber = end + chineseNumber; - } - key = ~~(key / 10); - times++; - } - // 一万零零一 => 一万零一 | 一万零零零 => 一万 - return chineseNumber.replace(/(零+$)|((零)\3+)/g, '$3'); -} - -/** - * 中文转为阿拉伯数字 - * --- - * @throws new TypeError('发现不符合规则的字符(必须在units和numbers里存在的字符):') - * @param value 中文数字 - * @param {{}} options 可选参数 - * @param [options.units=['', '十', '百', '千', '万', '十', '百', '千', '亿']] 单位 - * @param [options.numbers=['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']] 数字映射 - */ -export function chineseToNumber( - value: string, - options: { units?: string[]; numbers?: Tuple } = {}, -) { - const { - numbers = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'], - units = ['', '十', '百', '千', '万', '十', '百', '千', '亿'], - } = options; - - if (new RegExp(`([^${units.join() + numbers.join()}])`).test(value)) { - throw new TypeError('发现不符合规则的字符(必须在units和numbers里存在的字符):' + RegExp.$1); - } - - // 用万和亿分割 - const arr = value.split(new RegExp(`[${units[4]}${units[8]}]`, 'g')); - const numberArr = arr.map((it) => { - let res = 0; - let unit = 1; - // 从个位数往大数累加 - for (let i = it.length - 1; i > -1; i--) { - const item = it[i] as string; - - const number = numbers.indexOf(item); - if (number > 0) { - res += number * unit; - } - - const unitIndex = units.indexOf(item); - unit = unitIndex > 0 ? 10 ** unitIndex : unit; - } - - // 以十开头的要单独列出来 例如十一完全体是一十一 - if (it[0] === units[1]) { - res += 10; - } - return res; - }); - - // 把分割开的数字拼接回去 - return numberArr.reverse().reduce((res, item, index) => { - return res + 10000 ** index * item; - }, 0); -} diff --git a/src/number/calcArr.ts b/src/number/calcArr.ts new file mode 100644 index 00000000..8cda4523 --- /dev/null +++ b/src/number/calcArr.ts @@ -0,0 +1,18 @@ +import { getCommonPow } from './getCommonPow'; + +/** + * @see plus + * @see divide + * @see times + * @see divide + */ +export function calcArr( + num: number, + nums: number[], + callback: (a: number, b: number, pow: number) => number, +): number { + return nums.reduce((a, b) => { + const pow = getCommonPow(a, b); + return callback(a, b, pow); + }, num); +} diff --git a/src/number/chineseToNumber.ts b/src/number/chineseToNumber.ts new file mode 100644 index 00000000..438ca327 --- /dev/null +++ b/src/number/chineseToNumber.ts @@ -0,0 +1,54 @@ +import type { Tuple } from '@tool-pack/types'; + +/** + * 中文转为阿拉伯数字 + * --- + * @throws new TypeError('发现不符合规则的字符(必须在units和numbers里存在的字符):') + * @param value 中文数字 + * @param {{}} options 可选参数 + * @param [options.units=['', '十', '百', '千', '万', '十', '百', '千', '亿']] 单位 + * @param [options.numbers=['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']] 数字映射 + */ +export function chineseToNumber( + value: string, + options: { + numbers?: Tuple; + units?: string[]; + } = {}, +) { + const { + numbers = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'], + units = ['', '十', '百', '千', '万', '十', '百', '千', '亿'], + } = options; + if (new RegExp(`([^${units.join() + numbers.join()}])`).test(value)) { + throw new TypeError('发现不符合规则的字符(必须在units和numbers里存在的字符):' + RegExp.$1); + } + + // 用万和亿分割 + const arr = value.split(new RegExp(`[${units[4]}${units[8]}]`, 'g')); + const numberArr = arr.map((it) => { + let res = 0; + let unit = 1; + // 从个位数往大数累加 + for (let i = it.length - 1; i > -1; i--) { + const item = it[i] as string; + const number = numbers.indexOf(item); + if (number > 0) { + res += number * unit; + } + const unitIndex = units.indexOf(item); + unit = unitIndex > 0 ? 10 ** unitIndex : unit; + } + + // 以十开头的要单独列出来 例如十一完全体是一十一 + if (it[0] === units[1]) { + res += 10; + } + return res; + }); + + // 把分割开的数字拼接回去 + return numberArr.reverse().reduce((res, item, index) => { + return res + 10000 ** index * item; + }, 0); +} diff --git a/src/number/divide.ts b/src/number/divide.ts new file mode 100644 index 00000000..74504d60 --- /dev/null +++ b/src/number/divide.ts @@ -0,0 +1,15 @@ +import { calcArr } from './calcArr'; + +/** + * 除法计算,直接计算有精度问题 + * + * @example + * + * // 0.3 / 0.1 = 2.9999999999999996 + * 0.3 / 0.1; // 2.9999999999999996 + * divide(0.3, 0.1); // 3 + * + */ +export function divide(num: number, ...nums: Array) { + return calcArr(num, nums, (a, b, pow) => (a * pow) / (b * pow)); +} diff --git a/src/number/forEachNum.ts b/src/number/forEachNum.ts new file mode 100644 index 00000000..db3e58ac --- /dev/null +++ b/src/number/forEachNum.ts @@ -0,0 +1,22 @@ +/** + * 代替for循环 + * + * @example + * + * const arr: number[] = []; + * forEachNum(3, (index) => arr.push(index)); + * arr; // [0, 1, 2] + * forEachNum(7, (index) => arr.push(index)); + * arr.length; // 10 + * forEachNum(3, (index): void | false => { + * arr.push(index); + * if (index === 1) return false; + * }); + * arr; // [0, 1, 2, 0, 1, 2, 3, 4, 5, 6, 0, 1] + */ +export function forEachNum(len: number, callback: (index: number) => false | any) { + for (let i = 0; i < len; i++) { + if (callback(i) !== false) continue; + break; + } +} diff --git a/src/number/forEachNumRight.ts b/src/number/forEachNumRight.ts new file mode 100644 index 00000000..7090dbc4 --- /dev/null +++ b/src/number/forEachNumRight.ts @@ -0,0 +1,26 @@ +/** + * 代替for循环 + * + * forEachNum的反向遍历版本 + * + * @see forEachNum + * + * @example + * + * const arr: number[] = []; + * forEachNumRight(3, (index) => arr.push(index)); + * arr; // [0, 1, 2].reverse() + * forEachNumRight(7, (index) => arr.push(index)); + * arr.length; // 10 + * forEachNumRight(3, (index): void | false => { + * arr.push(index); + * if (index === 1) return false; + * }); + * arr; // [...[0, 1, 2].reverse(), ...[0, 1, 2, 3, 4, 5, 6].reverse(), 2, 1] + * + */ +export function forEachNumRight(len: number, callback: (index: number) => false | any) { + for (let i = len - 1; i >= 0; i--) { + if (callback(i) === false) break; + } +} diff --git a/src/common/formatBytes.ts b/src/number/formatBytes.ts similarity index 71% rename from src/common/formatBytes.ts rename to src/number/formatBytes.ts index 82512e93..fdafd58d 100644 --- a/src/common/formatBytes.ts +++ b/src/number/formatBytes.ts @@ -1,4 +1,4 @@ -import { toNonExponential } from '../number'; +import { shortenNumber } from '../number'; export type BYTE_UNIT = 'YB' | 'ZB' | 'EB' | 'PB' | 'TB' | 'GB' | 'MB' | 'KB' | 'B'; @@ -40,10 +40,10 @@ export type BYTE_UNIT = 'YB' | 'ZB' | 'EB' | 'PB' | 'TB' | 'GB' | 'MB' | 'KB' | export function formatBytes( bytes: number, { - unit, - fractionDigits = 2, exponential = false, - }: { unit?: BYTE_UNIT; fractionDigits?: number; exponential?: boolean } = {}, + fractionDigits = 2, + unit, + }: { fractionDigits?: number; exponential?: boolean; unit?: BYTE_UNIT } = {}, ): string { // 名称 -符号 - 二进制计量 - 十进制计量 - 字节数 - 等于 // KiloByte KB 210 103 1,024 1,024 B @@ -55,35 +55,12 @@ export function formatBytes( // ZettaByte ZB 270 1021 1,180,591,620,717,411,303,424 1,024 EB // YottaByte YB 280 1024 1,208,925,819,614,629,174,706,176 1,024 ZB - const kb = 1024; - const mb = kb ** 2; - const gb = kb ** 3; - const tb = kb ** 4; - const pb = kb ** 5; - const eb = kb ** 6; - const zb = kb ** 7; - const yb = kb ** 8; - const match: [number, BYTE_UNIT][] = [ - [yb, 'YB'], - [zb, 'ZB'], - [eb, 'EB'], - [pb, 'PB'], - [tb, 'TB'], - [gb, 'GB'], - [mb, 'MB'], - [kb, 'KB'], - [0, 'B'], - ]; - - const handler: (item: [number, BYTE_UNIT]) => boolean = unit - ? ([, u]) => u === unit - : ( - (absByte: number) => - ([range]) => - absByte >= range - )(Math.abs(bytes)); - - const [range, _unit] = match.find(handler)!; - const result = Number((bytes / (range || 1)).toFixed(fractionDigits)); - return (exponential ? result : toNonExponential(result)) + _unit; + return ( + shortenNumber(bytes, { + unit: unit ? (unit.replace('B', '') as any) : undefined, + fractionDigits, + kSize: 1024, + exponential, + }) + 'B' + ); } diff --git a/src/number/getCommonPow.ts b/src/number/getCommonPow.ts new file mode 100644 index 00000000..be66057d --- /dev/null +++ b/src/number/getCommonPow.ts @@ -0,0 +1,19 @@ +import { getNumberLenAfterDot } from './getNumberLenAfterDot'; + +/** + * 获取两位数乘后都能为整数的数字 + * + * @example + * + * getCommonPow(0.1, 0.11); // 100 + * getCommonPow(1.123e2, 0.11); // 100 + * getCommonPow(1e2, 10); // 1 + * getCommonPow(1e-2, 10); // 100 + * getCommonPow(10.1, 1.00001); // 100000 + * + */ +export function getCommonPow(a: number, b: number): number { + const aLen = getNumberLenAfterDot(a); + const bLen = getNumberLenAfterDot(b); + return Math.pow(10, Math.max(aLen, bLen)); +} diff --git a/src/number/getNumberLenAfterDot.ts b/src/number/getNumberLenAfterDot.ts new file mode 100644 index 00000000..2354957c --- /dev/null +++ b/src/number/getNumberLenAfterDot.ts @@ -0,0 +1,29 @@ +/** + * 获取小数点后面数字的长度,支持科学计数法 + * + * from number-precision + * + * @example + * + * // 数字 + * getNumberLenAfterDot(0.12345667); // 8 + * getNumberLenAfterDot(12345); // 0 + * + * // 字符串 + * getNumberLenAfterDot('0.123456789'); // 9 + * getNumberLenAfterDot('abc'); // 0 + * + * // 科学计数法 + * getNumberLenAfterDot(1.123e5); // 0 + * getNumberLenAfterDot(1.123e2); // 1 + * getNumberLenAfterDot(1.123e2); // 1 + * getNumberLenAfterDot(1e2); // 0 + * getNumberLenAfterDot(1e-2); // 2 + * + */ +export function getNumberLenAfterDot(num: number | string): number { + Number(1000).toPrecision(); + const eSplit = String(num).split(/[eE]/); + const len = (eSplit[0]?.split('.')[1] || '').length - +(eSplit[1] || 0); + return len > 0 ? len : 0; +} diff --git a/src/number/getSafeNum.ts b/src/number/getSafeNum.ts new file mode 100644 index 00000000..56cc41bc --- /dev/null +++ b/src/number/getSafeNum.ts @@ -0,0 +1,20 @@ +/** + * 安全数字 + * + * 如果value小于min,那么返回min,如果value大于max,那么返回max,否则返回value + * + * @example + * + * getSafeNum(0); // 0 + * getSafeNum(0, 1, 100); // 1 + * getSafeNum(50, 1, 100); // 50 + * getSafeNum(101, 1, 100); // 100 + * getSafeNum(101, 1); // 101 + * + * @param value 数字 + * @param [min=-Infinity] 默认-Infinity + * @param [max=Infinity] 默认Infinity + */ +export function getSafeNum(value: number, min = -Infinity, max = Infinity): number { + return Math.max(min, Math.min(value, max)); +} diff --git a/src/number/index.ts b/src/number/index.ts new file mode 100644 index 00000000..c5f009d5 --- /dev/null +++ b/src/number/index.ts @@ -0,0 +1,17 @@ +export * from './strip'; +export * from './toNonExponential'; +export * from './getNumberLenAfterDot'; +export * from './getCommonPow'; +export * from './calcArr'; +export * from './plus'; +export * from './minus'; +export * from './times'; +export * from './divide'; +export * from './getSafeNum'; +export * from './numToFixed'; +export * from './forEachNum'; +export * from './forEachNumRight'; +export * from './numberToChinese'; +export * from './chineseToNumber'; +export * from './formatBytes'; +export * from './shortenNumber'; diff --git a/src/number/minus.ts b/src/number/minus.ts new file mode 100644 index 00000000..871245d6 --- /dev/null +++ b/src/number/minus.ts @@ -0,0 +1,15 @@ +import { calcArr } from './calcArr'; + +/** + * 减法计算,直接计算有精度问题 + * + * @example + * + * // 0.3 - 0.1 = 0.19999999999999998 + * 0.3 - 0.1; // 0.19999999999999998 + * minus(0.3, 0.1); // 0.2 + * + */ +export function minus(num: number, ...nums: Array) { + return calcArr(num, nums, (a, b, pow) => (a * pow - b * pow) / pow); +} diff --git a/src/number/numToFixed.ts b/src/number/numToFixed.ts new file mode 100644 index 00000000..02cda77e --- /dev/null +++ b/src/number/numToFixed.ts @@ -0,0 +1,39 @@ +import { isNumber } from '../data-type'; +import { inRange } from '../array'; + +/** + * number保留小数位,原来的函数四舍五入不准确 + * + * 原来的toFixed可以把科学计数法的小数,给转成普通小数字符串 + * + * @example + * + * // Number.prototype.toFixed自带四舍五入 + * (0.45).toFixed(1); // '0.5' + * // numToFixed默认使用四舍五入,跟Number.prototype.toFixed保持一致 + * numToFixed(0.45, 1); // '0.5' + * // 关闭四舍五入 + * numToFixed(0.45, 1, false); // '0.4' + * + * @param num 原数字 + * @param [fractionDigits = 0] 保留小数位 + * @param [rounding = true] 是否四舍五入 + */ +export function numToFixed(num: number, fractionDigits = 0, rounding = true): string { + if (!isNumber(fractionDigits) || !inRange(fractionDigits, [0, 100])) { + throw new TypeError('numToFixed() fractionDigits argument must be between 0 and 100'); + } + if (fractionDigits === 0) return String(~~num); + const base = 10; + // 加1 四舍五入 + const pow = base ** (fractionDigits + 1); + num = ~~(num * pow); + if (rounding && num) { + // num为0的时候位数已经不对了 + num += 5; + } + num /= pow; + const split = String(num).split('.'); + const digits = (split[1] || '').substr(0, fractionDigits).padEnd(fractionDigits, '0'); + return split[0] + '.' + digits; +} diff --git a/src/number/numberToChinese.ts b/src/number/numberToChinese.ts new file mode 100644 index 00000000..62d45c4a --- /dev/null +++ b/src/number/numberToChinese.ts @@ -0,0 +1,45 @@ +import type { Tuple } from '@tool-pack/types'; + +/** + * 阿拉伯数字转为中文数字 + * @param value 数字 + * @param {{}} options 可选参数 + * @param [options.units=['', '十', '百', '千', '万', '十', '百', '千', '亿']] 单位 + * @param [options.numbers=['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']] 数字映射 + */ +export function numberToChinese( + value: number, + options: { + numbers?: Tuple; + units?: string[]; + } = {}, +): string { + const { + numbers = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'], + units = ['', '十', '百', '千', '万', '十', '百', '千', '亿'], + } = options; + const unitLen = units.length; + let key = ~~value; + let chineseNumber = ''; + let times = 0; + + // 个位数 + if (value >= 0 && value < 10) return numbers[value] as string; + while (key >= 1 && times < unitLen) { + const unit = units[times]; + // 11 % 10 => 一 + const end = numbers[key % 10]; + // 101 0没有单位 + if (end !== numbers[0]) { + chineseNumber = unit + chineseNumber; + } + // 11 => 一十一 => 十一 + if (!(key === 1 && times === 1)) { + chineseNumber = end + chineseNumber; + } + key = ~~(key / 10); + times++; + } + // 一万零零一 => 一万零一 | 一万零零零 => 一万 + return chineseNumber.replace(/(零+$)|((零)\3+)/g, '$3'); +} diff --git a/src/number/plus.ts b/src/number/plus.ts new file mode 100644 index 00000000..07789db5 --- /dev/null +++ b/src/number/plus.ts @@ -0,0 +1,13 @@ +import { calcArr } from './calcArr'; + +/** + * 加法计算,直接计算有精度问题 + * + * // 0.1 + 0.2 = 0.30000000000000004 + * 0.1 + 0.2; // 0.30000000000000004 + * plus(0.1, 0.2); // 0.3 + * + */ +export function plus(num: number, ...nums: Array) { + return calcArr(num, nums, (a, b, pow) => (a * pow + b * pow) / pow); +} diff --git a/src/number/shortenNumber.ts b/src/number/shortenNumber.ts new file mode 100644 index 00000000..db98d23b --- /dev/null +++ b/src/number/shortenNumber.ts @@ -0,0 +1,144 @@ +import { toNonExponential } from './toNonExponential'; + +export type NUMBER_UNIT = 'Y' | 'Z' | 'E' | 'P' | 'T' | 'G' | 'M' | 'K'; + +/** + * 缩短数字 + * + * @example + * + * const fn = Num.shortenNumber; + * const k = 1000; + * + * fn(k); // '1K' + * fn(k * k); // '1M' + * fn(k * k * k); // '1G' + * fn(k * k * k * k); // '1T' + * fn(k * k * k * k * k); // '1P' + * fn(k ** 6); // '1E' + * fn(k ** 7); // '1Z' + * fn(-(k ** 7)); // '-1Z' + * fn(k ** 8); // '1Y' + * + * // 指定单位 + * fn(k * 0.5 * k, { unit: 'M' }); // '0.5M' + * fn(k * 0.5 * k, { unit: 'G' }); // '0G' + * // 指定小数位 + * fn(k * 0.49 * k, { unit: 'G', fractionDigits: 5 }); // '0.00049G' + * fn(1, { unit: 'G', fractionDigits: 9 }); // '0.000000001G' + * // 使用科学计数法 + * fn(1, { unit: 'G', fractionDigits: 9, exponential: true }); // '1e-9G' + * + * // 包括单位,长度超过 5 位单位才进位 + * fn(100, { maxLength: 5 }); // '100' + * fn(100_00, { maxLength: 5 }); // '10000' + * fn(100_000, { maxLength: 5 }); // '100K' + * fn(1_000_000, { maxLength: 5 }); // '1000K' + * fn(10_000_000, { maxLength: 5 }); // '10M' + * fn(100_000_000, { maxLength: 5 }); // '100M' + * fn(1_000_000_000, { maxLength: 5 }); // '1000M' + * fn(10_000_000_000, { maxLength: 5 }); // '10G' + * fn(1_000_000_000_000, { maxLength: 5 }); // '1000G' + * fn(10_000_000_000_000, { maxLength: 5 }); // '10T' + * fn(100_000_000_000_000, { maxLength: 5 }); // '100T' + * fn(1_000_000_000_000_000, { maxLength: 5 }); // '1000T' + * fn(100_000_000_000_000_000, { maxLength: 5 }); // '100P' + * fn(1_000_000_000_000_000_000_000, { maxLength: 5 }); // '1000E' + * fn(1_000_000_000_000_000_000_000_000, { maxLength: 5 }); // '1000Z' + * fn(1_000_000_000_000_000_000_000_000_000, { maxLength: 5 }); // '1000Y' + * // 最大单位为 Y + * fn(1_000_000_000_000_000_000_000_000_000_000, { maxLength: 5, exponential: true }); // '1e+6Y' + * + * // 指定1k=1024 + * const kb = 1024; + * fn(kb * 0.5 * kb, { kSize: kb }); // '512K' + * fn(kb * 0.5 * kb, { kSize: kb, unit: 'M' }); // '0.5M' + * fn(kb * 50 * kb, { kSize: kb, unit: 'K' }); // '51200K' + * + * @param value 数值 + * @param {{}} options 选项 + * @param options.kSize 1k 的大小;默认为 1000 + * @param options.unit 指定单位 + * @param [options.fractionDigits=2] 指定小数位;默认2 + * @param [options.maxLength=3] 指定数字长度大于多少才进单位,类似战力游戏中的战斗力数值展示,必须大于 3 才有效,因为千分位本来就是三位;默认为 3 + * @param [options.exponential=false] 是否使用科学计数法;默认false + */ +export function shortenNumber( + value: number, + options: { + /** + * 小数位;默认2 + */ + fractionDigits?: number; + /** + * 使用科学计数法 + */ + exponential?: boolean; + /** + * 数字长度大于多少才进单位;默认为 3 + */ + maxLength?: number; + /** + * 单位 + */ + unit?: NUMBER_UNIT; + /** + * 1k 的大小;默认为 1000 + */ + kSize?: number; + } = {}, +): string { + const { exponential = false, fractionDigits = 2, maxLength = 3, kSize = 1000, unit } = options; + + const k = kSize; + const m = k ** 2; + const g = k ** 3; + const t = k ** 4; + const p = k ** 5; + const e = k ** 6; + const z = k ** 7; + const y = k ** 8; + + const rangeMap: [number, NUMBER_UNIT | ''][] = [ + [y, 'Y'], + [z, 'Z'], + [e, 'E'], + [p, 'P'], + [t, 'T'], + [g, 'G'], + [m, 'M'], + [k, 'K'], + [0, ''], + ]; + + type Handler = (item: [number, NUMBER_UNIT | ''], index: number) => boolean; + const handleUnit: Handler = ([, u]) => u === unit; + const handleRange = (): Handler => { + const absValue = Math.abs(value); + return ([range]) => absValue >= range; + }; + const handleMaxLimitRange = (): Handler => { + const absValue = Math.abs(value); + const limit = 10 ** (maxLength - 1); + const end = rangeMap.length - 1; + return ([range], index) => { + if (index === end) return true; + if (absValue < range) return false; + if (absValue <= limit) return true; + return absValue / (range || 1) < limit; + }; + }; + + // 反过来查找 + if (maxLength > 3) rangeMap.reverse(); + + const handler: Handler = unit + ? handleUnit + : maxLength > 3 + ? handleMaxLimitRange() + : handleRange(); + + const [range, _unit] = rangeMap.find(handler)!; + const result = Number((value / (range || 1)).toFixed(fractionDigits)); + return (exponential ? result.toExponential() : toNonExponential(result)) + _unit; +} diff --git a/src/number/strip.ts b/src/number/strip.ts new file mode 100644 index 00000000..95e309d9 --- /dev/null +++ b/src/number/strip.ts @@ -0,0 +1,20 @@ +/** + * 把错误的数据转正 from number-precision + * + * @example + * + * 1.0000000000041083; // 1.0000000000041083 + * strip(1.0000000000041083); // 1 + * + * 1.0000000000001563; // 1.0000000000001563 + * strip(1.0000000000001563); // 1 + * + * 1.0000000000001563; // 1.0000000000001563 + * strip(1.0000000000001563); // 1 + * + * strip(0.09999999999999998); // 0.1 + * + */ +export function strip(num: number, precision = 12): number { + return +parseFloat(num.toPrecision(precision)); +} diff --git a/src/number/times.ts b/src/number/times.ts new file mode 100644 index 00000000..cf1c44f5 --- /dev/null +++ b/src/number/times.ts @@ -0,0 +1,15 @@ +import { calcArr } from './calcArr'; + +/** + * 乘法计算,直接计算有精度问题 + * + * @example + * + * // 0.2 * 0.1 = 0.020000000000000004 + * 0.2 * 0.1; // 0.020000000000000004 + * times(0.2, 0.1); // 0.02 + * + */ +export function times(num: number, ...nums: Array) { + return calcArr(num, nums, (a, b, pow) => (pow * a * (b * pow)) / (pow * pow)); +} diff --git a/src/number/toNonExponential.ts b/src/number/toNonExponential.ts new file mode 100644 index 00000000..62224923 --- /dev/null +++ b/src/number/toNonExponential.ts @@ -0,0 +1,30 @@ +/** + * 科学计数法转普通小数 + * + * @note 不能转太大的数 比如大于Number.MAX_SAFE_INTEGER + * + * @example + * + * toNonExponential(1e2); // '100' + * toNonExponential(0.0000001); // '0.0000001' + * toNonExponential(0.0000000001); // '0.0000000001' + * + * const num = 100_000_000_000_000_000_000_000; + * num.toString(); // '1e+23' + * num > Number.MAX_SAFE_INTEGER; // true + * toNonExponential(num); // '1e+23' + * + * const num2 = (1_000_000_000_000_000).toExponential(); + * num2.toString(); // '1e+15' + * +num2 > Number.MAX_SAFE_INTEGER; // false + * toNonExponential(+num2); // '1000000000000000' + * + */ +export function toNonExponential(num: number): string { + // toExponential 转为科学计数法 + // const m = num.toExponential().match(/\d(?:\.(\d*))?e([+-]\d+)/); + const sNum = String(num); + const m = sNum.match(/\d(?:\.(\d*))?e([+-]\d+)/); + if (num > Number.MAX_SAFE_INTEGER || !m || m.length < 3) return sNum; + return num.toFixed(Math.max(0, (m[1] || '').length - Number(m[2]))); +} diff --git a/src/object/common.ts b/src/object/common.ts deleted file mode 100644 index 844fe691..00000000 --- a/src/object/common.ts +++ /dev/null @@ -1,559 +0,0 @@ -import { forEachRight, unique } from '../array'; -import { forEachObj, reduceObj } from './iterate'; - -/** - * 合并两个object - * - * TODO 可优化 - * - * @example - * - * // 对象合并 - * const a = { one: 1, two: 2, three: 3 }; - * const b = { one: 11, four: 4, five: 5 }; - * deepMerge(a, b); // Object.assign({}, a, b) - * - * // 嵌套对象合并 - * const c = { ...a, test: { a: 1, b: 2, c: 3 } }; - * deepMerge(c, b); // Object.assign({}, c, b) - * deepMerge(c, b).test.a === 1; // true - * // 第二个对象中不存在属性也会重新复制 - * deepMerge(c, b).test !== c.test; // true - * - * // 合并类实例 - * function Fn(this: any) { - * this.a = 100; - * } - * - * Fn.prototype.b = 200; - * - * const d = new Fn(); - * deepMerge(a, d); // Object.assign({}, a, d) - * // 不会合并继承属性 - * deepMerge(a, d).b; // undefined - * - * deepMerge(a, { a: [{ b: 123 }] }); // Object.assign({}, a, { a: [{ b: 123 }] }) - * - */ -export function deepMerge, U extends Record>( - first: T, - second: U, -): T & U { - function assign(receive: Record, obj: any) { - for (const k in obj) { - if (!hasOwn(obj, k)) continue; - const v = obj[k]; - if (v && typeof v === 'object') { - receive[k] = new v.constructor(); - assign(receive[k], v); - } else receive[k] = v; - } - } - - const result: any = {}; - assign(result, first); - assign(result, second); - return result; -} - -/** - * object {key:value}翻转成{value:key} - * - * @example - * const obj = { a: 'aa', b: 'bb' }; - * fn(obj); // { aa: 'a', bb: 'b' } - * - */ -export function getReversedObj(obj: { [k: string]: string }): { [k: string]: string } { - return reduceObj( - obj, - (res, v, k) => { - res[v] = k; - return res; - }, - {} as Record, - ); -} - -/** - * 根据新键值对重命名对象的key,并生成一个新的对象 - * - * 跟pickRename类似,但不会pick,未改动的会原样返回 - * - * @example - * - * renameObjKey({ a: 12, b: undefined, c: 3 }, { test: 'a', bb: 'b' }); // { test: 12,bb: undefined, c: 3, } - * renameObjKey({ a: 12, b: undefined, c: 3 }, { test: 'aa' as any, bb: 'b' }); // { a: 12, bb: undefined, c: 3, } - * renameObjKey({ a: 1, b: 2 }, { a: 'a', aa: 'a', aaa: 'a' }); // { a: 1, aa: 1, aaa: 1, b: 2, } - */ -export function renameObjKey< - T extends object, - K extends keyof T, - O extends { [k: string]: K }, - R extends Omit, ->(originObj: T, keyMap: O): { [k in keyof O]: T[O[k]] } & R { - const result: any = Object.assign({}, originObj); - const delKeys: K[] = []; - const newKeys: string[] = []; - - forEachObj(keyMap, (originKey, k) => { - if (hasOwn(result, originKey)) { - result[k] = result[originKey]; - delKeys.push(originKey); - newKeys.push(k as string); - } - }); - - // 可能新key会与旧key同名,如果是同名则把该key从要删除的key数组中移除 - // delKeys = delKeys.filter(k => newKeys.indexOf(k as string) === -1); - - delKeys.forEach((k) => { - if (newKeys.indexOf(k as string) > -1) return; - delete result[k]; - }); - return result; -} - -/** - * Omit 类似TS的Omit类型 - * @example - * - * omit({ a: 12, b: true, c: 'c' }, ['a']); // { b: true, c: 'c' } - * omit({ a: 12, b: true, c: 'c' }, ['a', 'b']); // { c: 'c' } - * omit({ c: 'c' }, ['c']); // {} - */ -export function omit( - target: T, - keys: readonly K[], -): Omit { - const newKeys = keys.slice(); - return reduceObj( - target, - (initValue, v, k) => { - const index = newKeys.indexOf(k as K); - if (index === -1) { - initValue[k] = v; - } else { - newKeys.splice(index, 1); - } - return initValue; - }, - {} as any, - ); -} - -/** - * 与lodash defaults一样 只替换origin里面的值为undefined的属性 - * - * 在原对象上改 - * - * @example - * - * const origin = { a: 12, b: undefined, c: 3, d: null, 0: undefined }; - * // 0个参数 - * defaults({ ...origin }); // origin - * defaults({ ...origin }, null); // origin - * defaults({ ...origin }, 1); // origin - * // 1个参数 - * defaults({ ...origin }, { a: 1, b: 1 }); // { ...origin, b: 1 } - * defaults({ ...origin }, '123'); // { ...origin, 0: '1', 1: '2', 2: '3' } - */ -export function defaults(origin: T, source: U): T & U; -/** - * 与lodash defaults一样 只替换origin里面的值为undefined的属性 - * - * 在原对象上改 - * - * @example - * - * const origin = { a: 12, b: undefined, c: 3, d: null, 0: undefined }; - * // 2个参数 - * defaults({ ...origin }, { a: 1, b: 1 }, { f: 5 }); // { ...origin, b: 1, f: 5 } - */ -export function defaults(origin: T, source1: U, source2: V): T & U & V; -/** - * 与lodash defaults一样 只替换origin里面的值为undefined的属性 - * - * 在原对象上改 - * - * @example - * - * const origin = { a: 12, b: undefined, c: 3, d: null, 0: undefined }; - * // 3个参数 - * defaults({ ...origin }, { a: 1, b: 1 }, { c: 0, d: 4 }, { f: 5, g: 6 }); // {...origin, b: 1, f: 5, g: 6, } - * - */ -export function defaults(origin: T, source1: U, source2: V, source3: W): T & U & V & W; -/** - * 与lodash defaults一样 只替换origin里面的值为undefined的属性 - * - * 在原对象上改 - * - * @example - * - * const origin = { a: 12, b: undefined, c: 3, d: null, 0: undefined }; - * // 更多参数 - * defaults({ ...origin }, { a: 1, b: 1 }, { c: 0, d: 4 }, { f: 5, g: 6 }, { h: 7, i: 8 }),; // { ...origin, b: 1, f: 5, g: 6, h: 7, i: 8 } - * - */ -export function defaults(origin: object, ...args: object[]): object; -export function defaults(origin: Record, ...args: any[]) { - args.forEach((arg) => { - forEachObj(arg, (v, k) => { - if (v === undefined || origin[k as string] !== undefined) return; - origin[k as string] = v; - }); - }); - return origin; -} - -/** - * 内部更新对象函数 - */ -function _updateObj(target: T, others: object[], k: keyof T): void { - // 从后往前查起 - forEachRight(others, (item): void | false => { - if (item && hasOwn(item, k)) { - target[k] = item[k]; - // 某个对象有这个key,那么就不再往前查 - return false; - } - }); -} - -/** - * 使用其他对象去更新目标对象 - * - * 使用target里面的key去查找其他的对象,如果其他对象里有该key,则把该值赋给target,如果多个对象都有同一个值,则以最后的为准 - * 会更新原对象 - * - * 如果要更新某个class的实例,那么需要使用updateIns - * - * @see updateIns - * - * @example - * - * updateObj({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { d: 4 }); // { a: 1, b: 2, c: 3, } - * updateObj({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { c: undefined }); // { a: 1, b: 2, c: undefined, } - * updateObj({ a: 12, b: undefined, c: 3 }, { aa: 2, bb: 2, dd: 123 }, { c: undefined }); // { a: 12, b: undefined, c: undefined, } - * - * updateObj({ a: 12, b: undefined, c: 3 }, null as any, undefined as any); // { a: 12, b: undefined, c: 3, } - * - * const obj = { a: 1, b: 2 }; - * isEqual(updateObj(obj, obj), obj); // true - * isEqual(updateObj(obj, obj), { a: 1, b: 2 }); // true - * - * @example - * - * // 更新class实例 - * class UpdateTestSuperClass { - * a = 1; - * b = 2; - * private test() { - * return 'super test'; - * } - * fn1() { - * return 'super fn1'; - * } - * get len() { - * this.test(); - * return 0; - * } - * } - * class UpdateTestClass extends UpdateTestSuperClass { - * c = 3; - * fn2() { - * return 'sub fn2'; - * } - * override get len() { - * return 1; - * } - * } - * - * // objUpdate 不会更新实例的方法 - * const ins = updateObj(new UpdateTestClass(), { - * fn1() { - * return 'replace fn1'; - * }, - * fn2() { - * return 'replace fn2'; - * }, - * }); - * ins.fn1(); // 'super fn1' - * ins.fn2(); // 'sub fn2' - * - */ -export function updateObj(target: T, ...others: object[]): T { - if (others[others.length - 1] === target) return target; - forEachObj(target, (_v, k) => _updateObj(target, others, k)); - return target; -} -// export function updateObj(target: T, ...others: object[]): T { -// for (const k in target) { -// for (let i = others.length - 1; i > -1; i--) { -// const item = others[i]; -// if (item && hasOwn(item, k)) { -// target[k] = item[k]; -// break; -// } -// } -// } -// -// return target; -// } - -/** - * 获取class实例的key数组 - * - * @example - * - * class UpdateTestSuperClass { - * a = 1; - * b = 2; - * private test() { - * return 'super test'; - * } - * fn1() { - * return 'super fn1'; - * } - * get len() { - * this.test(); - * return 0; - * } - * } - * class UpdateTestClass extends UpdateTestSuperClass { - * c = 3; - * fn2() { - * return 'sub fn2'; - * } - * override get len() { - * return 1; - * } - * } - * - * const superKeys = ['a', 'b', 'fn1', 'len', 'test'].sort(); - * const subKeys = ['c', 'fn2', ...superKeys].sort(); - * - * getInsKeys(new UpdateTestSuperClass()).sort(); // superKeys - * - * getInsKeys(new UpdateTestClass()).sort(); // subKeys - * - * // 不会继承method - * const obj = { a1: 1, b2: 2, c3: 3, ...new UpdateTestClass() }; - * getInsKeys(obj).sort(); // ['a', 'b', 'c', 'a1', 'b2', 'c3'].sort() - * - * const obj2 = Object.create(new UpdateTestClass()); - * getInsKeys(obj2).sort(); // subKeys - * - * const obj3 = Object.create(null); - * obj3.a = 1; - * obj3.b = 2; - * getInsKeys(obj3).sort(); // ['a', 'b'] - */ -export function getInsKeys(ins: Record): Array { - const result: Array = []; - - let cur: Record = ins; - while (cur) { - // 普通key - result.push(...Object.keys(cur)); - - // 使用 Object.getPrototypeOf 代替 cur.__proto__ - const proto = Object.getPrototypeOf(cur); - - if (!proto || proto === Object.prototype) { - // 构造器为原生函数的话就不是class - // 或者对象原型和 Object 的原型一样则不是class - // 或者 Object.create(null) 创建的纯对象,prototype为null, __proto__为undefined - break; - } else { - // method key - result.push(...Reflect.ownKeys(proto)); - } - - cur = proto; - } - - // 过滤掉构造方法,并去重 - return unique(result.filter((k) => k !== 'constructor')); -} - -/** - * 更新实例对象属性 - * - * updateIns可以代替updateObj使用, - * 不过由于遍历了实例及原型的key,所以理论上updateIns会比updateObj慢一点 - * - * @see updateObj - * - * @example - * - * updateIns({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { d: 4 }); // { a: 1, b: 2, c: 3, } - * updateIns({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { c: undefined }); // { a: 1, b: 2, c: undefined, } - * updateIns({ a: 12, b: undefined, c: 3 }, { aa: 2, bb: 2, dd: 123 }, { c: undefined }); // { a: 12, b: undefined, c: undefined, } - * - * updateIns({ a: 12, b: undefined, c: 3 }, null as any, undefined as any); // { a: 12, b: undefined, c: 3, } - * - * const obj = { a: 1, b: 2 }; - * isEqual(updateIns(obj, obj), obj); // true - * isEqual(updateIns(obj, obj), { a: 1, b: 2 }); // true - * - * @example - * - * // 更新class实例 - * class UpdateTestSuperClass { - * a = 1; - * b = 2; - * private test() { - * return 'super test'; - * } - * fn1() { - * return 'super fn1'; - * } - * get len() { - * this.test(); - * return 0; - * } - * } - * class UpdateTestClass extends UpdateTestSuperClass { - * c = 3; - * fn2() { - * return 'sub fn2'; - * } - * override get len() { - * return 1; - * } - * } - * - * // updateIns 会更新实例的方法 - * const ins = fn(new UpdateTestClass(), { - * fn1() { - * return 'replace fn1'; - * }, - * fn2() { - * return 'replace fn2'; - * }, - * }); - * ins.fn1(); // 'replace fn1' - * ins.fn2(); // 'replace fn2' - * - */ -export function updateIns(target: T, ...others: object[]): T { - if (others[others.length - 1] === target) return target; - - const keys = getInsKeys(target); - keys.forEach((k) => _updateObj(target, others, k as keyof T)); - - return target; -} - -/** - * 判断对象是否包含某个属性。 - * - * 因为直接object.hasOwnProperty(key)的话object可能会是null,所以另外封装一个函数使用。 - * 可以用作类型守卫:见example。 - * - * TODO 该工具与Object.hasOwn一致,属于polyfill性质,不过Object.hasOwn毕竟是es2022的新api,过几年后可移除该polyfill工具 - * - * @example - * - * const o = { a: 1 }; - * let k = 'a'; - * k = 'c'; - * // 报错需要在tsconfig.json设置 - * // "suppressImplicitAnyIndexErrors": false, - * // "noImplicitAny": true, - * o[k] = 2; // 此处没有类型守卫会报错 - * if (hasOwn(o, k)) { - * o[k] = 3; // 有类型守卫,安全 - * } - * - * @param obj - * @param key - */ -export function hasOwn(obj: T, key: PropertyKey): key is keyof T { - return Object.prototype.hasOwnProperty.call(obj, key as keyof T); -} - -/** - * 对象或数组key交换 - * - * @example - * - * // 对象属性交换 - * swap({ a: 1, b: 2 }, 'a', 'b'); // { b: 1, a: 2 } - * swap({ a: 1, b: 2 }, 'a', 'c' as any); // { c: 1, b: 2, a: undefined } - * // 数组item交换 - * swap([1, 2], 1, 0); // [2, 1] - * swap([1, 2], 1, 2); // [1, undefined, 2] - */ -export function swap( - obj: T, - k1: K1, - k2: K2, -): T { - const temp = obj[k1]; - obj[k1] = obj[k2] as any; - obj[k2] = temp as any; - return obj; -} - -/** - * 查找对象中与param key类似的key - * - * @example - * - * // array - * likeKeys([1, 2, 3, 4, 5, 6, 7], '0'); // ['0'] - * likeKeys([1, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1], '0'); // ['0', '10'] - * - * // object - * likeKeys({ test: 1, test2: 2, test3: 3 }, 'test'); // ['test', 'test2', 'test3'] - * - * // map - * const map = new Map([ - * ['aa', 1], - * ['bb', 2], - * ['hello', 'world'], - * ]); - * likeKeys(map, /a+|b+/); // ['aa', 'bb'] - */ -export function likeKeys(target: object | Map, key: string | RegExp): string[] { - const reg = new RegExp(key); - if ('undefined' !== typeof Map && target instanceof Map) { - // keys = [...obj.keys()]; // babel编译成es5会编译成[].concat,无法使用 - const keys: string[] = []; - for (const k of target.keys()) { - if (reg.test(k)) keys.push(k); - } - return keys; - } - - return Object.keys(target).filter((key) => reg.test(key)); -} - -/** - * 影子对象 - * --- - * 有时候需要根据一个对象新建一个对象,而且对该对象的操作不能影响原对象, - * 使用解构或者Object.assign生成一个新对象太浪费空间 - * - * 直接使用内部操作也是可以的,该方法主要是可以避免声明一个中间变量 - * - * @example - * - * const origin = { a: 1, b: 2 }; - * const res = shadowObj(origin, { c: 3 }); - * console.log(res, res.a === origin.a, res.b === origin.b); // { c: 3 }, true, true - * - * @param origin 原对象 - * @param cover 覆盖原对象 - */ -export function shadowObj>( - origin: T, - cover: C, -): T extends C ? T : T & C { - const result = Object.create(origin); - Object.assign(result, cover); - return result; -} diff --git a/src/object/common/_updateObj.ts b/src/object/common/_updateObj.ts new file mode 100644 index 00000000..fca063d5 --- /dev/null +++ b/src/object/common/_updateObj.ts @@ -0,0 +1,16 @@ +import { forEachRight } from '../../array'; +import { hasOwn } from './hasOwn'; + +/** + * 内部更新对象函数 + */ +export function _updateObj(target: T, others: object[], k: keyof T): void { + // 从后往前查起 + forEachRight(others, (item): false | void => { + if (item && hasOwn(item, k)) { + target[k] = item[k]; + // 某个对象有这个key,那么就不再往前查 + return false; + } + }); +} diff --git a/src/object/common/deepMerge.ts b/src/object/common/deepMerge.ts new file mode 100644 index 00000000..1f5f4ce3 --- /dev/null +++ b/src/object/common/deepMerge.ts @@ -0,0 +1,55 @@ +import { hasOwn } from './hasOwn'; + +/** + * 合并两个object + * + * TODO 可优化 + * + * @example + * + * // 对象合并 + * const a = { one: 1, two: 2, three: 3 }; + * const b = { one: 11, four: 4, five: 5 }; + * deepMerge(a, b); // Object.assign({}, a, b) + * + * // 嵌套对象合并 + * const c = { ...a, test: { a: 1, b: 2, c: 3 } }; + * deepMerge(c, b); // Object.assign({}, c, b) + * deepMerge(c, b).test.a === 1; // true + * // 第二个对象中不存在属性也会重新复制 + * deepMerge(c, b).test !== c.test; // true + * + * // 合并类实例 + * function Fn(this: any) { + * this.a = 100; + * } + * + * Fn.prototype.b = 200; + * + * const d = new Fn(); + * deepMerge(a, d); // Object.assign({}, a, d) + * // 不会合并继承属性 + * deepMerge(a, d).b; // undefined + * + * deepMerge(a, { a: [{ b: 123 }] }); // Object.assign({}, a, { a: [{ b: 123 }] }) + * + */ +export function deepMerge, U extends Record>( + first: T, + second: U, +): T & U { + function assign(receive: Record, obj: any) { + for (const k in obj) { + if (!hasOwn(obj, k)) continue; + const v = obj[k]; + if (v && typeof v === 'object') { + receive[k] = new v.constructor(); + assign(receive[k], v); + } else receive[k] = v; + } + } + const result: any = {}; + assign(result, first); + assign(result, second); + return result; +} diff --git a/src/object/common/defaults.ts b/src/object/common/defaults.ts new file mode 100644 index 00000000..d558e8dc --- /dev/null +++ b/src/object/common/defaults.ts @@ -0,0 +1,66 @@ +import { forEachObj } from '../iterate'; + +/** + * 与lodash defaults一样 只替换origin里面的值为undefined的属性 + * + * 在原对象上改 + * + * @example + * + * const origin = { a: 12, b: undefined, c: 3, d: null, 0: undefined }; + * // 0个参数 + * defaults({ ...origin }); // origin + * defaults({ ...origin }, null); // origin + * defaults({ ...origin }, 1); // origin + * // 1个参数 + * defaults({ ...origin }, { a: 1, b: 1 }); // { ...origin, b: 1 } + * defaults({ ...origin }, '123'); // { ...origin, 0: '1', 1: '2', 2: '3' } + */ +export function defaults(origin: T, source: U): T & U; +/** + * 与lodash defaults一样 只替换origin里面的值为undefined的属性 + * + * 在原对象上改 + * + * @example + * + * const origin = { a: 12, b: undefined, c: 3, d: null, 0: undefined }; + * // 2个参数 + * defaults({ ...origin }, { a: 1, b: 1 }, { f: 5 }); // { ...origin, b: 1, f: 5 } + */ +export function defaults(origin: T, source1: U, source2: V): T & U & V; +/** + * 与lodash defaults一样 只替换origin里面的值为undefined的属性 + * + * 在原对象上改 + * + * @example + * + * const origin = { a: 12, b: undefined, c: 3, d: null, 0: undefined }; + * // 3个参数 + * defaults({ ...origin }, { a: 1, b: 1 }, { c: 0, d: 4 }, { f: 5, g: 6 }); // {...origin, b: 1, f: 5, g: 6, } + * + */ +export function defaults(origin: T, source1: U, source2: V, source3: W): T & U & V & W; +/** + * 与lodash defaults一样 只替换origin里面的值为undefined的属性 + * + * 在原对象上改 + * + * @example + * + * const origin = { a: 12, b: undefined, c: 3, d: null, 0: undefined }; + * // 更多参数 + * defaults({ ...origin }, { a: 1, b: 1 }, { c: 0, d: 4 }, { f: 5, g: 6 }, { h: 7, i: 8 }),; // { ...origin, b: 1, f: 5, g: 6, h: 7, i: 8 } + * + */ +export function defaults(origin: object, ...args: object[]): object; +export function defaults(origin: Record, ...args: any[]) { + args.forEach((arg) => { + forEachObj(arg, (v, k) => { + if (v === undefined || origin[k as string] !== undefined) return; + origin[k as string] = v; + }); + }); + return origin; +} diff --git a/src/object/common/getInsKeys.ts b/src/object/common/getInsKeys.ts new file mode 100644 index 00000000..919fee52 --- /dev/null +++ b/src/object/common/getInsKeys.ts @@ -0,0 +1,74 @@ +import { unique } from '../../array'; + +/** + * 获取class实例的key数组 + * + * @example + * + * class UpdateTestSuperClass { + * a = 1; + * b = 2; + * private test() { + * return 'super test'; + * } + * fn1() { + * return 'super fn1'; + * } + * get len() { + * this.test(); + * return 0; + * } + * } + * class UpdateTestClass extends UpdateTestSuperClass { + * c = 3; + * fn2() { + * return 'sub fn2'; + * } + * override get len() { + * return 1; + * } + * } + * + * const superKeys = ['a', 'b', 'fn1', 'len', 'test'].sort(); + * const subKeys = ['c', 'fn2', ...superKeys].sort(); + * + * getInsKeys(new UpdateTestSuperClass()).sort(); // superKeys + * + * getInsKeys(new UpdateTestClass()).sort(); // subKeys + * + * // 不会继承method + * const obj = { a1: 1, b2: 2, c3: 3, ...new UpdateTestClass() }; + * getInsKeys(obj).sort(); // ['a', 'b', 'c', 'a1', 'b2', 'c3'].sort() + * + * const obj2 = Object.create(new UpdateTestClass()); + * getInsKeys(obj2).sort(); // subKeys + * + * const obj3 = Object.create(null); + * obj3.a = 1; + * obj3.b = 2; + * getInsKeys(obj3).sort(); // ['a', 'b'] + */ +export function getInsKeys(ins: Record): Array { + const result: Array = []; + let cur: Record = ins; + while (cur) { + // 普通key + result.push(...Object.keys(cur)); + + // 使用 Object.getPrototypeOf 代替 cur.__proto__ + const proto = Object.getPrototypeOf(cur); + if (!proto || proto === Object.prototype) { + // 构造器为原生函数的话就不是class + // 或者对象原型和 Object 的原型一样则不是class + // 或者 Object.create(null) 创建的纯对象,prototype为null, __proto__为undefined + break; + } else { + // method key + result.push(...Reflect.ownKeys(proto)); + } + cur = proto; + } + + // 过滤掉构造方法,并去重 + return unique(result.filter((k) => k !== 'constructor')); +} diff --git a/src/object/common/getReversedObj.ts b/src/object/common/getReversedObj.ts new file mode 100644 index 00000000..f3bea9b9 --- /dev/null +++ b/src/object/common/getReversedObj.ts @@ -0,0 +1,21 @@ +import type { ReverseObject } from '@tool-pack/types'; +import { reduceObj } from '../iterate'; + +/** + * object {key:value}翻转成{value:key} + * + * @example + * const obj = { a: 'aa', b: 'bb' }; + * fn(obj); // { aa: 'a', bb: 'b' } + * + */ +export function getReversedObj(obj: T): ReverseObject { + return reduceObj( + obj, + (res, v, k) => { + res[v] = k; + return res; + }, + {} as any, + ); +} diff --git a/src/object/common/hasOwn.ts b/src/object/common/hasOwn.ts new file mode 100644 index 00000000..e57ec28e --- /dev/null +++ b/src/object/common/hasOwn.ts @@ -0,0 +1,27 @@ +/** + * 判断对象是否包含某个属性。 + * + * 因为直接object.hasOwnProperty(key)的话object可能会是null,所以另外封装一个函数使用。 + * 可以用作类型守卫:见example。 + * + * TODO 该工具与Object.hasOwn一致,属于polyfill性质,不过Object.hasOwn毕竟是es2022的新api,过几年后可移除该polyfill工具 + * + * @example + * + * const o = { a: 1 }; + * let k = 'a'; + * k = 'c'; + * // 报错需要在tsconfig.json设置 + * // "suppressImplicitAnyIndexErrors": false, + * // "noImplicitAny": true, + * o[k] = 2; // 此处没有类型守卫会报错 + * if (hasOwn(o, k)) { + * o[k] = 3; // 有类型守卫,安全 + * } + * + * @param obj + * @param key + */ +export function hasOwn(obj: T, key: PropertyKey): key is keyof T { + return Object.prototype.hasOwnProperty.call(obj, key as keyof T); +} diff --git a/src/object/common/index.ts b/src/object/common/index.ts new file mode 100644 index 00000000..8ba883b5 --- /dev/null +++ b/src/object/common/index.ts @@ -0,0 +1,12 @@ +export * from './deepMerge'; +export * from './getReversedObj'; +export * from './renameObjKey'; +export * from './omit'; +export * from './defaults'; +export * from './updateObj'; +export * from './getInsKeys'; +export * from './updateIns'; +export * from './hasOwn'; +export * from './swap'; +export * from './likeKeys'; +export * from './shadowObj'; diff --git a/src/object/common/likeKeys.ts b/src/object/common/likeKeys.ts new file mode 100644 index 00000000..ffcf42af --- /dev/null +++ b/src/object/common/likeKeys.ts @@ -0,0 +1,32 @@ +/** + * 查找对象中与param key类似的key + * + * @example + * + * // array + * likeKeys([1, 2, 3, 4, 5, 6, 7], '0'); // ['0'] + * likeKeys([1, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1], '0'); // ['0', '10'] + * + * // object + * likeKeys({ test: 1, test2: 2, test3: 3 }, 'test'); // ['test', 'test2', 'test3'] + * + * // map + * const map = new Map([ + * ['aa', 1], + * ['bb', 2], + * ['hello', 'world'], + * ]); + * likeKeys(map, /a+|b+/); // ['aa', 'bb'] + */ +export function likeKeys(target: Map | object, key: string | RegExp): string[] { + const reg = new RegExp(key); + if ('undefined' !== typeof Map && target instanceof Map) { + // keys = [...obj.keys()]; // babel编译成es5会编译成[].concat,无法使用 + const keys: string[] = []; + for (const k of target.keys()) { + if (reg.test(k)) keys.push(k); + } + return keys; + } + return Object.keys(target).filter((key) => reg.test(key)); +} diff --git a/src/object/common/omit.ts b/src/object/common/omit.ts new file mode 100644 index 00000000..8489e189 --- /dev/null +++ b/src/object/common/omit.ts @@ -0,0 +1,29 @@ +import { reduceObj } from '../iterate'; + +/** + * Omit 类似TS的Omit类型 + * @example + * + * omit({ a: 12, b: true, c: 'c' }, ['a']); // { b: true, c: 'c' } + * omit({ a: 12, b: true, c: 'c' }, ['a', 'b']); // { c: 'c' } + * omit({ c: 'c' }, ['c']); // {} + */ +export function omit( + target: T, + keys: readonly K[], +): Omit { + const newKeys = keys.slice(); + return reduceObj( + target, + (initValue, v, k) => { + const index = newKeys.indexOf(k as K); + if (index === -1) { + initValue[k] = v; + } else { + newKeys.splice(index, 1); + } + return initValue; + }, + {} as any, + ); +} diff --git a/src/object/common/renameObjKey.ts b/src/object/common/renameObjKey.ts new file mode 100644 index 00000000..bbb1c074 --- /dev/null +++ b/src/object/common/renameObjKey.ts @@ -0,0 +1,42 @@ +import { forEachObj } from '../iterate'; +import { hasOwn } from './hasOwn'; + +/** + * 根据新键值对重命名对象的key,并生成一个新的对象 + * + * 跟pickRename类似,但不会pick,未改动的会原样返回 + * + * @example + * + * renameObjKey({ a: 12, b: undefined, c: 3 }, { test: 'a', bb: 'b' }); // { test: 12,bb: undefined, c: 3, } + * renameObjKey({ a: 12, b: undefined, c: 3 }, { test: 'aa' as any, bb: 'b' }); // { a: 12, bb: undefined, c: 3, } + * renameObjKey({ a: 1, b: 2 }, { a: 'a', aa: 'a', aaa: 'a' }); // { a: 1, aa: 1, aaa: 1, b: 2, } + */ +export function renameObjKey< + T extends object, + K extends keyof T, + O extends { + [k: string]: K; + }, + R extends Omit, +>(originObj: T, keyMap: O): { [k in keyof O]: T[O[k]] } & R { + const result: any = Object.assign({}, originObj); + const delKeys: K[] = []; + const newKeys: string[] = []; + forEachObj(keyMap, (originKey, k) => { + if (hasOwn(result, originKey)) { + result[k] = result[originKey]; + delKeys.push(originKey); + newKeys.push(k as string); + } + }); + + // 可能新key会与旧key同名,如果是同名则把该key从要删除的key数组中移除 + // delKeys = delKeys.filter(k => newKeys.indexOf(k as string) === -1); + + delKeys.forEach((k) => { + if (newKeys.indexOf(k as string) > -1) return; + delete result[k]; + }); + return result; +} diff --git a/src/object/common/shadowObj.ts b/src/object/common/shadowObj.ts new file mode 100644 index 00000000..09143e88 --- /dev/null +++ b/src/object/common/shadowObj.ts @@ -0,0 +1,25 @@ +/** + * 影子对象 + * --- + * 有时候需要根据一个对象新建一个对象,而且对该对象的操作不能影响原对象, + * 使用解构或者Object.assign生成一个新对象太浪费空间 + * + * 直接使用内部操作也是可以的,该方法主要是可以避免声明一个中间变量 + * + * @example + * + * const origin = { a: 1, b: 2 }; + * const res = shadowObj(origin, { c: 3 }); + * console.log(res, res.a === origin.a, res.b === origin.b); // { c: 3 }, true, true + * + * @param origin 原对象 + * @param cover 覆盖原对象 + */ +export function shadowObj>( + origin: T, + cover: C, +): T extends C ? T : T & C { + const result = Object.create(origin); + Object.assign(result, cover); + return result; +} diff --git a/src/object/common/swap.ts b/src/object/common/swap.ts new file mode 100644 index 00000000..c4cd3afb --- /dev/null +++ b/src/object/common/swap.ts @@ -0,0 +1,22 @@ +/** + * 对象或数组key交换 + * + * @example + * + * // 对象属性交换 + * swap({ a: 1, b: 2 }, 'a', 'b'); // { b: 1, a: 2 } + * swap({ a: 1, b: 2 }, 'a', 'c' as any); // { c: 1, b: 2, a: undefined } + * // 数组item交换 + * swap([1, 2], 1, 0); // [2, 1] + * swap([1, 2], 1, 2); // [1, undefined, 2] + */ +export function swap( + obj: T, + k1: K1, + k2: K2, +): T { + const temp = obj[k1]; + obj[k1] = obj[k2] as any; + obj[k2] = temp as any; + return obj; +} diff --git a/src/object/common/updateIns.ts b/src/object/common/updateIns.ts new file mode 100644 index 00000000..24687b6a --- /dev/null +++ b/src/object/common/updateIns.ts @@ -0,0 +1,69 @@ +import { getInsKeys } from './getInsKeys'; +import { _updateObj } from './_updateObj'; + +/** + * 更新实例对象属性 + * + * updateIns可以代替updateObj使用, + * 不过由于遍历了实例及原型的key,所以理论上updateIns会比updateObj慢一点 + * + * @see updateObj + * + * @example + * + * updateIns({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { d: 4 }); // { a: 1, b: 2, c: 3, } + * updateIns({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { c: undefined }); // { a: 1, b: 2, c: undefined, } + * updateIns({ a: 12, b: undefined, c: 3 }, { aa: 2, bb: 2, dd: 123 }, { c: undefined }); // { a: 12, b: undefined, c: undefined, } + * + * updateIns({ a: 12, b: undefined, c: 3 }, null as any, undefined as any); // { a: 12, b: undefined, c: 3, } + * + * const obj = { a: 1, b: 2 }; + * isEqual(updateIns(obj, obj), obj); // true + * isEqual(updateIns(obj, obj), { a: 1, b: 2 }); // true + * + * @example + * + * // 更新class实例 + * class UpdateTestSuperClass { + * a = 1; + * b = 2; + * private test() { + * return 'super test'; + * } + * fn1() { + * return 'super fn1'; + * } + * get len() { + * this.test(); + * return 0; + * } + * } + * class UpdateTestClass extends UpdateTestSuperClass { + * c = 3; + * fn2() { + * return 'sub fn2'; + * } + * override get len() { + * return 1; + * } + * } + * + * // updateIns 会更新实例的方法 + * const ins = fn(new UpdateTestClass(), { + * fn1() { + * return 'replace fn1'; + * }, + * fn2() { + * return 'replace fn2'; + * }, + * }); + * ins.fn1(); // 'replace fn1' + * ins.fn2(); // 'replace fn2' + * + */ +export function updateIns(target: T, ...others: object[]): T { + if (others[others.length - 1] === target) return target; + const keys = getInsKeys(target); + keys.forEach((k) => _updateObj(target, others, k as keyof T)); + return target; +} diff --git a/src/object/common/updateObj.ts b/src/object/common/updateObj.ts new file mode 100644 index 00000000..e9173873 --- /dev/null +++ b/src/object/common/updateObj.ts @@ -0,0 +1,84 @@ +import { _updateObj } from './_updateObj'; +import { forEachObj } from '../iterate'; + +/** + * 使用其他对象去更新目标对象 + * + * 使用target里面的key去查找其他的对象,如果其他对象里有该key,则把该值赋给target,如果多个对象都有同一个值,则以最后的为准 + * 会更新原对象 + * + * 如果要更新某个class的实例,那么需要使用updateIns + * + * @see updateIns + * + * @example + * + * updateObj({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { d: 4 }); // { a: 1, b: 2, c: 3, } + * updateObj({ a: 12, b: undefined, c: 3 }, { a: 1 }, { b: 2 }, { c: undefined }); // { a: 1, b: 2, c: undefined, } + * updateObj({ a: 12, b: undefined, c: 3 }, { aa: 2, bb: 2, dd: 123 }, { c: undefined }); // { a: 12, b: undefined, c: undefined, } + * + * updateObj({ a: 12, b: undefined, c: 3 }, null as any, undefined as any); // { a: 12, b: undefined, c: 3, } + * + * const obj = { a: 1, b: 2 }; + * isEqual(updateObj(obj, obj), obj); // true + * isEqual(updateObj(obj, obj), { a: 1, b: 2 }); // true + * + * @example + * + * // 更新class实例 + * class UpdateTestSuperClass { + * a = 1; + * b = 2; + * private test() { + * return 'super test'; + * } + * fn1() { + * return 'super fn1'; + * } + * get len() { + * this.test(); + * return 0; + * } + * } + * class UpdateTestClass extends UpdateTestSuperClass { + * c = 3; + * fn2() { + * return 'sub fn2'; + * } + * override get len() { + * return 1; + * } + * } + * + * // objUpdate 不会更新实例的方法 + * const ins = updateObj(new UpdateTestClass(), { + * fn1() { + * return 'replace fn1'; + * }, + * fn2() { + * return 'replace fn2'; + * }, + * }); + * ins.fn1(); // 'super fn1' + * ins.fn2(); // 'sub fn2' + * + */ +export function updateObj(target: T, ...others: object[]): T { + if (others[others.length - 1] === target) return target; + forEachObj(target, (_v, k) => _updateObj(target, others, k)); + return target; +} + +// export function updateObj(target: T, ...others: object[]): T { +// for (const k in target) { +// for (let i = others.length - 1; i > -1; i--) { +// const item = others[i]; +// if (item && hasOwn(item, k)) { +// target[k] = item[k]; +// break; +// } +// } +// } +// +// return target; +// } diff --git a/src/object/iterate.ts b/src/object/iterate.ts deleted file mode 100644 index 07546044..00000000 --- a/src/object/iterate.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { hasOwn } from './common'; - -/** - * 遍历对象属性 - * - * 代替Object.keys(obj).forEach - * - * @example - * - * const obj = { a: 1, b: 2, c: 3 }; - * function feo(obj: object) { - * const arr: any[] = []; - * - * forEachObj(obj, (v, k, obj) => { - * arr.push([v, k, obj]); - * }); - * return arr; - * } - * - * isEqual(feo(obj), - * Object.keys(obj).reduce((res, key) => { - * res.push([obj[key], key, obj]); - * return res; - * }, [] as any[]), - * ); // true - * - * feo(obj).length; // 3 - * // 不会遍历继承的属性 - * feo(Object.create(obj)).length; // 0 - * - * @param obj 要遍历的对象 - * @param callbackFn 返回false的时候中断 - * @param elseCB 遍历完后执行 - * @returns {boolean} isDone - */ -export function forEachObj( - obj: T, - callbackFn: (value: T[keyof T], key: keyof T, obj: T) => void | false, - elseCB?: () => any, -): boolean { - for (const k in obj) { - if (!hasOwn(obj, k)) continue; - const v = obj[k]; - if (callbackFn(v, k, obj) === false) return false; - } - elseCB && elseCB(); - return true; -} - -/** - * 替换数组或对象的value - * - * @example - * - * const obj = { a: 1, b: 2 }; - * replaceValues(obj, String); // { a: '1', b: '2' } - * console.log(obj); // { a: '1', b: '2' } - * - * const arr = [1, 2, 3]; - * replaceValues(arr, String); // ['1', '2', '3'] - * console.log(arr); // ['1', '2', '3'] - */ -export function replaceValues | Array>( - target: T, - replacement: (v: unknown, k: string, target: T) => unknown, -) { - forEachObj(target, (v, k): void => { - (target as any)[k] = replacement(v, k as string, target); - }); - return target; -} - -/** - * - * 代替Object.keys(obj).reduce - * - * @example - * - * const obj = { a: 1, b: 2, c: '3' }; - * reduceObj(obj, (r, v, k) => ((r[v] = k), r), {} as Record); // { 1: 'a', 2: 'b', 3: 'c' } - * - * @param obj 要遍历的对象 - * @param callbackFn 回调 - * @param initialValue 初始值 数组中可以省略,默认使用数组中的第一项作为初始值,但object不存在第一项,所以不能省略 - */ -export function reduceObj( - obj: T, - callbackFn: (previousValue: R, value: T[keyof T], key: keyof T, obj: T) => R, - initialValue: R, -): R { - let result = initialValue; - forEachObj(obj, (v, k, o) => { - result = callbackFn(result, v, k, o); - }); - return result; -} - -/** - * 过滤对象属性 - * - * 代替Object.keys(target).filter() - * - * @example - * - * const obj = { a: '', b: 123, c: 0, d: undefined, e: false, f: NaN, g: null }; - * filterObj(obj); // { b: 123 } - * filterObj(obj, (v) => v !== undefined); // omit(obj, ['d']) - * - */ -export function filterObj( - obj: Record, - predicate: (v: any, k: string) => boolean = (v) => v, -): object { - return reduceObj( - obj, - (init, v, k) => { - if (predicate(v, k)) { - init[k] = v; - } - return init; - }, - {} as Record, - ); -} diff --git a/src/object/iterate/filterObj.ts b/src/object/iterate/filterObj.ts new file mode 100644 index 00000000..7208d6a5 --- /dev/null +++ b/src/object/iterate/filterObj.ts @@ -0,0 +1,29 @@ +import { reduceObj } from '../iterate'; + +/** + * 过滤对象属性 + * + * 代替Object.keys(target).filter() + * + * @example + * + * const obj = { a: '', b: 123, c: 0, d: undefined, e: false, f: NaN, g: null }; + * filterObj(obj); // { b: 123 } + * filterObj(obj, (v) => v !== undefined); // omit(obj, ['d']) + * + */ +export function filterObj( + obj: Record, + predicate: (v: any, k: string) => boolean = (v) => v, +): object { + return reduceObj( + obj, + (init, v, k) => { + if (predicate(v, k)) { + init[k] = v; + } + return init; + }, + {} as Record, + ); +} diff --git a/src/object/iterate/forEachObj.ts b/src/object/iterate/forEachObj.ts new file mode 100644 index 00000000..a8a3d537 --- /dev/null +++ b/src/object/iterate/forEachObj.ts @@ -0,0 +1,48 @@ +import { hasOwn } from '../common'; + +/** + * 遍历对象属性 + * + * 代替Object.keys(obj).forEach + * + * @example + * + * const obj = { a: 1, b: 2, c: 3 }; + * function feo(obj: object) { + * const arr: any[] = []; + * + * forEachObj(obj, (v, k, obj) => { + * arr.push([v, k, obj]); + * }); + * return arr; + * } + * + * isEqual(feo(obj), + * Object.keys(obj).reduce((res, key) => { + * res.push([obj[key], key, obj]); + * return res; + * }, [] as any[]), + * ); // true + * + * feo(obj).length; // 3 + * // 不会遍历继承的属性 + * feo(Object.create(obj)).length; // 0 + * + * @param obj 要遍历的对象 + * @param callbackFn 返回false的时候中断 + * @param elseCB 遍历完后执行 + * @returns {boolean} isDone + */ +export function forEachObj( + obj: T, + callbackFn: (value: T[keyof T], key: keyof T, obj: T) => false | void, + elseCB?: () => any, +): boolean { + for (const k in obj) { + if (!hasOwn(obj, k)) continue; + const v = obj[k]; + if (callbackFn(v, k, obj) === false) return false; + } + elseCB && elseCB(); + return true; +} diff --git a/src/object/iterate/index.ts b/src/object/iterate/index.ts new file mode 100644 index 00000000..89dc3fc9 --- /dev/null +++ b/src/object/iterate/index.ts @@ -0,0 +1,4 @@ +export * from './forEachObj'; +export * from './replaceValues'; +export * from './reduceObj'; +export * from './filterObj'; diff --git a/src/object/iterate/reduceObj.ts b/src/object/iterate/reduceObj.ts new file mode 100644 index 00000000..cabae4cc --- /dev/null +++ b/src/object/iterate/reduceObj.ts @@ -0,0 +1,26 @@ +import { forEachObj } from './forEachObj'; + +/** + * + * 代替Object.keys(obj).reduce + * + * @example + * + * const obj = { a: 1, b: 2, c: '3' }; + * reduceObj(obj, (r, v, k) => ((r[v] = k), r), {} as Record); // { 1: 'a', 2: 'b', 3: 'c' } + * + * @param obj 要遍历的对象 + * @param callbackFn 回调 + * @param initialValue 初始值 数组中可以省略,默认使用数组中的第一项作为初始值,但object不存在第一项,所以不能省略 + */ +export function reduceObj( + obj: T, + callbackFn: (previousValue: R, value: T[keyof T], key: keyof T, obj: T) => R, + initialValue: R, +): R { + let result = initialValue; + forEachObj(obj, (v, k, o) => { + result = callbackFn(result, v, k, o); + }); + return result; +} diff --git a/src/object/iterate/replaceValues.ts b/src/object/iterate/replaceValues.ts new file mode 100644 index 00000000..ad37e672 --- /dev/null +++ b/src/object/iterate/replaceValues.ts @@ -0,0 +1,24 @@ +import { forEachObj } from './forEachObj'; + +/** + * 替换数组或对象的value + * + * @example + * + * const obj = { a: 1, b: 2 }; + * replaceValues(obj, String); // { a: '1', b: '2' } + * console.log(obj); // { a: '1', b: '2' } + * + * const arr = [1, 2, 3]; + * replaceValues(arr, String); // ['1', '2', '3'] + * console.log(arr); // ['1', '2', '3'] + */ +export function replaceValues | Array>( + target: T, + replacement: (v: unknown, k: string, target: T) => unknown, +) { + forEachObj(target, (v, k): void => { + (target as any)[k] = replacement(v, k as string, target); + }); + return target; +} diff --git a/src/object/path.ts b/src/object/path.ts deleted file mode 100644 index 64c0cdaa..00000000 --- a/src/object/path.ts +++ /dev/null @@ -1,200 +0,0 @@ -import { - DotTrim, - RemoveStrStart, - TransferPath, - TransferPathOf, - TypeOfPath, -} from '@tool-pack/types'; -import { isBroadlyObj, typeOf } from '../data-type'; -import { hasOwn } from './common'; -import { reduceObj } from './iterate'; - -/** - * 对象属性路径转换: obj[a] => obj.a - * - * @example - * translateObjPath('a[b][c].d[e][f]'); // 'a.b.c.d.e.f' - * translateObjPath('a.b.c.d.e.f'); // 'a.b.c.d.e.f' - * translateObjPath('a.b.c.d.e.f', 'a'); // 'b.c.d.e.f' - * translateObjPath('a[b][c].d.e.f', 'a\\[b\\]\\[c\\]'); // 'd.e.f' - * translateObjPath('a.b.c.d.e.f', 'a.b.c'); // 'd.e.f' - * translateObjPath('a[][][]'); // 'a' - * - * @param path 路径 - * @param [objName = ""] 对象名 - */ -export function translateObjPath

( - path: P, - objName: S = '' as S, -): DotTrim>> { - let result: any = path; - // obj[a] => obj.a - result = result.replace(new RegExp(`^${objName}`), ''); - result = result.replace(/\[([^\]]+)]/g, '.$1'); - result = result.replace(/^\.|\[]/g, ''); - return result; -} - -/** - * 通过object路径获取值 - * - * 支持类型字面量推导,const v:number = getObjValueByPath({ a: { b: { c: 123 } } }, 'a.b.c'); v的类型是number - * - * @example - * - * // object - * getObjValueByPath({ a: { b: { c: 123 } } }, 'a.b.c'); // 123 - * getObjValueByPath({ a: { b: { c: 123 } } }, 'a[b][c]'); // 123 - * getObjValueByPath({ a: { b: { c: '123' } } }, 'a[b].c'); // '123' - * - * // array - * getObjValueByPath([[[1]]], '0.0.0'); // 1 - * getObjValueByPath([[[1]]], '[0][0][0]'); // 1 - * getObjValueByPath([[[1]]], '[0][0].0'); // 1 - * - */ -export function getObjValueByPath< - T extends Record, - P extends string, - S extends string = '', ->( - obj: T, - path: TransferPathOf, - objName: S = '' as S, -): TypeOfPath>>> { - const p = translateObjPath(path, objName) as string; - return p.split('.').reduce((init, v) => { - if (!isBroadlyObj(init)) return undefined; - return init[v as keyof typeof init]; - }, obj as any); -} - -// getObjValueByPath({a: {b: {b_c: 123,d:'d'}}}, "a.b.b_c"); // number -// getObjValueByPath({a: {b: {c: 123}}}, "obj[a][b][c]", "obj"); // number -// getObjValueByPath({a: 123, b: {c: false}}, "obj[b][c]", "obj"); // boolean - -type SetObjValueByPathOnExist = (a: any, b: any, isEnd: boolean, path: string) => any; - -/** - * 通过object路径设置值 如果路径中不存在则会自动创建对应的对象 - * - * 支持类型推导检测 - * - * @example - * - * setObjValueByPath({ a: { b: { c: 123 } } }, 'obj[a][b][c]', 333, undefined, 'obj'); // {a: { b: { c: 333 } }} - * setObjValueByPath({ a: { b: { c: 123 } } }, 'obj[a][b][c]', true as any, undefined, 'obj'); // {a: { b: { c: true } }} - * - * @param obj 对象 - * @param path 路径 - * @param value 设置值 - * @param onExist 当要改动位置已经有值时的回调 - * @param [objName = ""] 对象名 - */ -export function setObjValueByPath< - T extends object, - P extends string, - S extends string = '', - NO_START extends string = DotTrim>, - Path extends string = TransferPath, ->( - obj: T, - path: TransferPathOf, - value: TypeOfPath, - onExist: SetObjValueByPathOnExist = (_a, b): any => b, - objName: S = '' as S, -): T { - const p = translateObjPath(path, objName) as string; - const split = p.split('.'); - const end = split.length - 1; - split.reduce( - ([init, currentPath], key, index) => { - currentPath = currentPath + (currentPath ? '.' + key : key); - if (index === end) { - if (hasOwn(init, key)) { - value = onExist(init[key], value, true, currentPath); - } - init[key] = value; - return [init[key], currentPath] as any; - } - - if (!isBroadlyObj(init[key])) { - init[key] = hasOwn(init, key) ? onExist(init[key], {}, false, currentPath) : {}; - } - return [init[key], currentPath]; - }, - [obj, ''] as [Record, string], - ); - return obj; -} - -/** - * 获取object的路径数组 - * - * @example - * - * getObjPathEntries({a: 1}) // => [["[a]", 1]] - * getObjPathEntries({a: 1},"obj") // => [["obj[a]", 1]] - * - * @param obj 对象 - * @param [objName = ""] 对象名 - */ -export function getObjPathEntries(obj: object, objName = ''): Array<[string, any]> { - return reduceObj( - obj, - (init, v, k) => { - const key = `${objName}[${k as string}]`; - if (isBroadlyObj(v)) { - init.push(...getObjPathEntries(v, key)); - } else { - init.push([key, v]); - } - return init; - }, - [] as Array<[string, any]>, - ); -} - -// 根据路径还原整个object -export function revertObjFromPath(pathArr: string[]): object { - function getKV(path: string): { key: string; value: string; innerKey: string } { - const [k, value] = path.split('=').map((item) => decodeURIComponent(item)) as [string, string]; - let key = k; - let innerKey = ''; - const reg = /\[([^[\]]*)]|\.\[?([^[\]]*)]?/g; - if (reg.test(key)) { - innerKey = RegExp.$1 || RegExp.$2; - key = key.replace(reg, ''); - } - // key = key.replace(/\[[^\[\]]*]/g, ""); - return { key, value, innerKey }; - } - - return pathArr.reduce((result, path) => { - const { key, value, innerKey } = getKV(path); - const resultValue = result[key]; - - // no-fallthrough - switch (typeOf(resultValue)) { - case 'undefined': - if (!innerKey) { - result[key] = value; - } else { - const arr: any[] = []; - arr[innerKey as any] = value; - result[key] = arr; - } - break; - case 'string': - result[key] = [resultValue]; - // eslint-disable-next-line no-fallthrough - case 'array': - if (!innerKey) { - result[key].push(value); - } else { - result[key][innerKey] = value; - } - } - return result; - }, {} as Record); -} diff --git a/src/object/path/getObjPathEntries.ts b/src/object/path/getObjPathEntries.ts new file mode 100644 index 00000000..cbc6de05 --- /dev/null +++ b/src/object/path/getObjPathEntries.ts @@ -0,0 +1,29 @@ +import { isBroadlyObj } from '../../data-type'; +import { reduceObj } from '../iterate'; + +/** + * 获取object的路径数组 + * + * @example + * + * getObjPathEntries({a: 1}) // => [["[a]", 1]] + * getObjPathEntries({a: 1},"obj") // => [["obj[a]", 1]] + * + * @param obj 对象 + * @param [objName = ""] 对象名 + */ +export function getObjPathEntries(obj: object, objName = ''): Array<[string, any]> { + return reduceObj( + obj, + (init, v, k) => { + const key = `${objName}[${k as string}]`; + if (isBroadlyObj(v)) { + init.push(...getObjPathEntries(v, key)); + } else { + init.push([key, v]); + } + return init; + }, + [] as Array<[string, any]>, + ); +} diff --git a/src/object/path/getObjValueByPath.ts b/src/object/path/getObjValueByPath.ts new file mode 100644 index 00000000..a21bf5f4 --- /dev/null +++ b/src/object/path/getObjValueByPath.ts @@ -0,0 +1,47 @@ +import type { + RemoveStrStart, + TransferPathOf, + TransferPath, + TypeOfPath, + DotTrim, +} from '@tool-pack/types'; +import { translateObjPath } from './translateObjPath'; +import { isBroadlyObj } from '../../data-type'; + +/** + * 通过object路径获取值 + * + * 支持类型字面量推导,const v:number = getObjValueByPath({ a: { b: { c: 123 } } }, 'a.b.c'); v的类型是number + * + * @example + * + * // object + * getObjValueByPath({ a: { b: { c: 123 } } }, 'a.b.c'); // 123 + * getObjValueByPath({ a: { b: { c: 123 } } }, 'a[b][c]'); // 123 + * getObjValueByPath({ a: { b: { c: '123' } } }, 'a[b].c'); // '123' + * + * // array + * getObjValueByPath([[[1]]], '0.0.0'); // 1 + * getObjValueByPath([[[1]]], '[0][0][0]'); // 1 + * getObjValueByPath([[[1]]], '[0][0].0'); // 1 + * + */ +export function getObjValueByPath< + T extends Record, + P extends string, + S extends string = '', +>( + obj: T, + path: TransferPathOf, + objName: S = '' as S, +): TypeOfPath>>> { + const p = translateObjPath(path, objName) as string; + return p.split('.').reduce((init, v) => { + if (!isBroadlyObj(init)) return undefined; + return init[v as keyof typeof init]; + }, obj as any); +} + +// getObjValueByPath({a: {b: {b_c: 123,d:'d'}}}, "a.b.b_c"); // number +// getObjValueByPath({a: {b: {c: 123}}}, "obj[a][b][c]", "obj"); // number +// getObjValueByPath({a: 123, b: {c: false}}, "obj[b][c]", "obj"); // boolean diff --git a/src/object/path/index.ts b/src/object/path/index.ts new file mode 100644 index 00000000..641dde01 --- /dev/null +++ b/src/object/path/index.ts @@ -0,0 +1,5 @@ +export * from './translateObjPath'; +export * from './getObjValueByPath'; +export * from './setObjValueByPath'; +export * from './getObjPathEntries'; +export * from './revertObjFromPath'; diff --git a/src/object/path/revertObjFromPath.ts b/src/object/path/revertObjFromPath.ts new file mode 100644 index 00000000..a1162a6a --- /dev/null +++ b/src/object/path/revertObjFromPath.ts @@ -0,0 +1,55 @@ +import { typeOf } from '../../data-type'; + +// 根据路径还原整个object +export function revertObjFromPath(pathArr: string[]): object { + function getKV(path: string): { + innerKey: string; + value: string; + key: string; + } { + const [k, value] = path.split('=').map((item) => decodeURIComponent(item)) as [string, string]; + let key = k; + let innerKey = ''; + const reg = /\[([^[\]]*)]|\.\[?([^[\]]*)]?/g; + if (reg.test(key)) { + innerKey = RegExp.$1 || RegExp.$2; + key = key.replace(reg, ''); + } + // key = key.replace(/\[[^\[\]]*]/g, ""); + return { + innerKey, + value, + key, + }; + } + return pathArr.reduce( + (result, path) => { + const { innerKey, value, key } = getKV(path); + const resultValue = result[key]; + + // no-fallthrough + switch (typeOf(resultValue)) { + case 'undefined': + if (!innerKey) { + result[key] = value; + } else { + const arr: any[] = []; + arr[innerKey as any] = value; + result[key] = arr; + } + break; + case 'string': + result[key] = [resultValue]; + + case 'array': + if (!innerKey) { + result[key].push(value); + } else { + result[key][innerKey] = value; + } + } + return result; + }, + {} as Record, + ); +} diff --git a/src/object/path/setObjValueByPath.ts b/src/object/path/setObjValueByPath.ts new file mode 100644 index 00000000..3c126e0a --- /dev/null +++ b/src/object/path/setObjValueByPath.ts @@ -0,0 +1,64 @@ +import type { + RemoveStrStart, + TransferPathOf, + TransferPath, + TypeOfPath, + DotTrim, +} from '@tool-pack/types'; +import { translateObjPath } from './translateObjPath'; +import { isBroadlyObj } from '../../data-type'; +import { hasOwn } from '../common'; + +/** + * 通过object路径设置值 如果路径中不存在则会自动创建对应的对象 + * + * 支持类型推导检测 + * + * @example + * + * setObjValueByPath({ a: { b: { c: 123 } } }, 'obj[a][b][c]', 333, undefined, 'obj'); // {a: { b: { c: 333 } }} + * setObjValueByPath({ a: { b: { c: 123 } } }, 'obj[a][b][c]', true as any, undefined, 'obj'); // {a: { b: { c: true } }} + * + * @param obj 对象 + * @param path 路径 + * @param value 设置值 + * @param onExist 当要改动位置已经有值时的回调 + * @param [objName = ""] 对象名 + */ +export function setObjValueByPath< + T extends object, + P extends string, + S extends string = '', + NO_START extends string = DotTrim>, + Path extends string = TransferPath, +>( + obj: T, + path: TransferPathOf, + value: TypeOfPath, + onExist: SetObjValueByPathOnExist = (_a, b): any => b, + objName: S = '' as S, +): T { + const p = translateObjPath(path, objName) as string; + const split = p.split('.'); + const end = split.length - 1; + split.reduce( + ([init, currentPath], key, index) => { + currentPath = currentPath + (currentPath ? '.' + key : key); + if (index === end) { + if (hasOwn(init, key)) { + value = onExist(init[key], value, true, currentPath); + } + init[key] = value; + return [init[key], currentPath] as any; + } + if (!isBroadlyObj(init[key])) { + init[key] = hasOwn(init, key) ? onExist(init[key], {}, false, currentPath) : {}; + } + return [init[key], currentPath]; + }, + [obj, ''] as [Record, string], + ); + return obj; +} + +type SetObjValueByPathOnExist = (a: any, b: any, isEnd: boolean, path: string) => any; diff --git a/src/object/path/translateObjPath.ts b/src/object/path/translateObjPath.ts new file mode 100644 index 00000000..3bf17a97 --- /dev/null +++ b/src/object/path/translateObjPath.ts @@ -0,0 +1,27 @@ +import type { RemoveStrStart, TransferPath, DotTrim } from '@tool-pack/types'; + +/** + * 对象属性路径转换: obj[a] => obj.a + * + * @example + * translateObjPath('a[b][c].d[e][f]'); // 'a.b.c.d.e.f' + * translateObjPath('a.b.c.d.e.f'); // 'a.b.c.d.e.f' + * translateObjPath('a.b.c.d.e.f', 'a'); // 'b.c.d.e.f' + * translateObjPath('a[b][c].d.e.f', 'a\\[b\\]\\[c\\]'); // 'd.e.f' + * translateObjPath('a.b.c.d.e.f', 'a.b.c'); // 'd.e.f' + * translateObjPath('a[][][]'); // 'a' + * + * @param path 路径 + * @param [objName = ""] 对象名 + */ +export function translateObjPath

( + path: P, + objName: S = '' as S, +): DotTrim>> { + let result: any = path; + // obj[a] => obj.a + result = result.replace(new RegExp(`^${objName}`), ''); + result = result.replace(/\[([^\]]+)]/g, '.$1'); + result = result.replace(/^\.|\[]/g, ''); + return result; +} diff --git a/src/object/pick.ts b/src/object/pick.ts deleted file mode 100644 index 03689182..00000000 --- a/src/object/pick.ts +++ /dev/null @@ -1,265 +0,0 @@ -import { isNaN, isObject } from '../data-type'; -import { forEachRight } from '../array'; -import { hasOwn } from './common'; -import { forEachObj, reduceObj } from './iterate'; - -/** - * 通过key数组挑选出key数组组成的对象 - * - * @example - * - * const obj = { a: 1, b: '2', c: ['12313', 111], d: false, e: { a: 1 }, f: undefined }; - * - * pickByKeys(obj, []); // {} - * pickByKeys(obj, ['a']); // { a: 1 } - * pickByKeys(obj, ['b']); // { b: obj.b } - * pickByKeys(obj, ['c']); // { c: obj.c } - * pickByKeys(obj, ['a'], (v) => v + 1000); // { a: 1001 } - * // 不存在于对象中的属性会忽略 - * pickByKeys(obj, ['g' as any]); // {} - * - * @param originObj 遍历对象 - * @param pickKeys 需要挑选的key数组 - * @param cb 对值进行修改 - */ -export function pickByKeys( - originObj: T, - pickKeys: K[], - cb?: (value: T[K], key: K, originObj: T) => Pick[K], -): Pick { - const callback = cb || ((v) => v); - return pickKeys.reduce((res, key) => { - res[key] = callback(originObj[key], key, originObj); - return res; - }, {} as any); -} - -// 不完美的地方:k === "a"时应该限定返回值类型为number -/*pickByKeys({ a: 123, b: '111', c: false }, ['a', 'b'], (v, k, o) => { - if (k === 'a') { - return '123123'; - } - return v; -});*/ - -/** - * pick并且重命名 - * - * 新属性名作为键名的好处是可以多个属性对应一个值 - * - * @example - * - * const obj = { a: 1, b: '2', c: ['12313', 111], d: false, e: { a: 1 }, f: undefined }; - * - * pickRename(obj, {}); // {} - * pickRename(obj, { A: 'a' }); // { A: 1 } - * pickRename(obj, { B: 'b' }); // { B: obj.b } - * pickRename(obj, { C: 'c' }); // { C: obj.c } - * pickRename(obj, { D: 'd' }); // { D: obj.d } - * pickRename(obj, { E: 'e' }); // { E: obj.e } - * // 不存在于对象中的属性会忽略 - * pickRename(obj, { G: 'G' as any }); // {} - * - * @param originObj 需要遍历的对象 - * @param pickKeyMap key map - * @param cb 对值进行修改 - */ -export function pickRename( - originObj: T, - pickKeyMap: O, - cb?: (value: T[O[keyof O]], key: O[keyof O], originObj: T) => T[O[keyof O]], -): { [k in keyof O]: T[O[k]] } { - const callback = cb || ((v) => v); - /* const renames = Object.keys(renamePickObj) as (keyof O)[]; - return renames.reduce((result, rename) => { - const pick = renamePickObj[rename]; - if (originObj.hasOwnProperty(pick)) { - result[rename] = callback(originObj[pick], pick, originObj); - } - return result; - }, {} as any);*/ - return reduceObj( - pickKeyMap, - (result, pick, rename) => { - result[rename] = callback(originObj[pick], pick, originObj); - return result; - }, - {} as any, - ); -} - -/* -export function pickRename2< - T extends object, - K extends keyof T, - O extends { [k: string]: K | ((t: T) => T[K]) }, ->(originObj: T, renamePickObj: O): { [k in keyof O]: O[k] extends K ? T[O[k]] : T[K] } { - return {} as any; -} - -pickRename2( - { a: 123, b: '222' }, - { - c: 'a', - d: (obj) => obj.a, - }, -); -*/ - -/** - * pickByKeys与pickRename的合体函数 - * - * @see pickByKeys - * - * @overload 通过key数组挑选,功能与pickByKeys函数一致 - * - */ -export function pick( - originObj: T, - pickKeys: KS, - cb?: (value: T[K], key: K, fromObj: T) => T[K], -): { [key in K]: T[key] }; -/** - * pickByKeys与pickRename的合体函数 - * - * @overload 通过key map挑选并重命名, 功能与pickRename函数一致 - * - * @see pickRename - */ -export function pick( - originObj: T, - pickKeyMap: O, - cb?: (value: T[O[keyof O]], key: O[keyof O], fromObj: T) => T[O[keyof O]], -): { [k in keyof O]: T[O[k]] }; -export function pick(originObj: object, picks: any[], cb?: Function) { - const isObj = isObject(picks); - // ------- 第一种写法 ------- - // const callback = cb || (v => v); - // const pickKeys = isObj ? Object.keys(picks) : picks; - // const getOriginObjKey = isObj ? k => picks[k] : k => k; - // return pickKeys.reduce((res, k) => { - // const originObjKey = getOriginObjKey(k); - // if (originObj.hasOwnProperty(originObjKey)) { - // res[k] = callback(originObj[originObjKey], originObjKey, originObj); - // } - // return res; - // }, {} as any); - // ------- 第二种写法 ------- - // 更简洁 减少判断次数 - // TO DO 需要判断返回值类型是否改变了 改变则抛出异常 - return isObj - ? pickRename(originObj, picks as any, cb as any) - : pickByKeys(originObj, picks, cb as any); -} - -// pick({a: 132, b: "123123"}, ["a", "b"]); - -/** - * 从其他对象中挑出与原对象值不一样的或原对象中不存在的键值对所组成的新对象 - * - * @example - * - * pickDiff({ a: 1 }, []); // {} - * pickDiff({ a: 1 }, [{ a: 1 }]); // {} - * pickDiff({ a: 1 }, [{ a: 2 }]); // { a: 2 } - * pickDiff({ a: 1 }, [{ b: 2 }]); // { b: 2 } - * pickDiff({ a: 1 }, [{ b: 2 }, { a: 1, c: 3 }, { a: 3 }]); // { a: 3, b: 2, c: 3 } - * pickDiff({ a: NaN }, [{ a: NaN, b: 1 }]); // { b: 1 } - * - * const a = { a: { id: 123 } }; - * const b = { a: { id: 123 } }; - * // 虽然值一样,但引用不一样,所以a会被pick出来 - * pickDiff(a, [b]); // { a: { id: 123 } } - * // 通过id判断两个对象是否一样 - * pickDiff(a, [b], (v1, v2, k, origin, obj) => v1.id === v2.id}); // {} - * - */ -export function pickDiff( - origin: object, - objs: object[], - verify?: (originV: any, objV: any, k: string | number, origin: object, obj: object) => boolean, -): { [k: string]: any } { - const verifyFn = - verify || - ((originV, objV, k, origin) => { - return (hasOwn(origin, k) && originV === objV) || (isNaN(originV) && isNaN(objV)); - }); - return objs.reduce((result, obj) => { - forEachObj(obj, (v, k) => { - if (verifyFn(origin[k], v, k, origin, obj)) return; - result[k] = v; - }); - return result; - }, {}); -} - -/** - * 从其他对象中挑出与原对象中不存在的键值对所组成的新对象 - * - * @overload 返回值支持ts类型推导 - * - * @example - * - * pickExternal({ a: 1 }, { a: 2 }); // {} - * pickExternal({ a: 1 }, { b: 2 }); // { b: 2 } - * pickExternal({ a: 1 }, { b: 2, c: 3 }); // { b: 2, c: 3 } - * pickExternal({ a: 1, b: 2 }, { b: 2, c: 3 }); // { c: 3 } - * - */ -export function pickExternal( - origin: T, - other: K, -): Omit; -/** - * 从其他对象中挑出与原对象中不存在的键值对所组成的新对象 - * - * @overload 返回值不支持ts类型推导, 返回的对象类型始终是 Record - * - * pickExternal({ a: 1, b: 2 }, { b: 2, c: 3 }, { b: 2, c: 3 }); // { c: 3 } - */ -export function pickExternal(origin: object, ...others: object[]): Record; -export function pickExternal(origin: object, ...others: object[]) { - return pickDiff(origin, others, (_originV, _objV, k) => hasOwn(origin, k)); -} - -/** - * 根据与target对比,挑出与target同key不同value的key所组成的object - * - * @example - * - * const obj1 = { a: 12, b: undefined, c: 3 }; - * pickUpdated(obj1, [{ a: 1 }, { b: 2 }, { d: 3 }]); // { a: 1, b: 2 } - * pickUpdated(obj1, [{ a: 1 }, { a: 2 }, { a: 5 }]); // { a: 5 } - * pickUpdated(obj1, [{ a: 1 }, { a: 2 }, { a: 12 }]); // {} - * pickUpdated(obj1, [{ a: 12 }, { b: undefined }, { c: 3 }]); // {} - * pickUpdated({}, [{ a: 1 }, { b: 2 }, { d: 3 }]); // {} - * pickUpdated({ a: NaN }, [{ a: 1 }, { a: NaN }]); // {} - * pickUpdated({ a: NaN }, [{ a: 1 }, null as any]); // { a: 1 } - * pickUpdated({ a: NaN }, [null as any]); // {} - * pickUpdated({ a: NaN }, [undefined as any]); // {} - * - * @param target 目标对象 - * @param objs 相当于assign(...objs) 同样的key只会取最后一个 - * @param compareFn 比较回调 - */ -export function pickUpdated( - target: T, - objs: object[], - compareFn: (a: unknown, b: unknown) => boolean = (a, b) => a === b || (isNaN(a) && isNaN(b)), -): Partial<{ [k in keyof T]: any }> { - return reduceObj( - target, - (result, _v, k) => { - forEachRight(objs, function (item: any): void | false { - if (item && hasOwn(item, k)) { - if (!compareFn(target[k], item[k])) { - result[k] = item[k]; - } - return false; - } - }); - return result; - }, - {} as any, - ); -} diff --git a/src/object/pick/index.ts b/src/object/pick/index.ts new file mode 100644 index 00000000..a36bb1e7 --- /dev/null +++ b/src/object/pick/index.ts @@ -0,0 +1,6 @@ +export * from './pickByKeys'; +export * from './pickRename'; +export * from './pick'; +export * from './pickDiff'; +export * from './pickExternal'; +export * from './pickUpdated'; diff --git a/src/object/pick/pick.ts b/src/object/pick/pick.ts new file mode 100644 index 00000000..ba94116a --- /dev/null +++ b/src/object/pick/pick.ts @@ -0,0 +1,55 @@ +import { isObject } from '../../data-type'; +import { pickRename } from './pickRename'; +import { pickByKeys } from './pickByKeys'; + +/** + * pickByKeys与pickRename的合体函数 + * + * @see pickByKeys + * + * @overload 通过key数组挑选,功能与pickByKeys函数一致 + * + */ +export function pick( + originObj: T, + pickKeys: KS, + cb?: (value: T[K], key: K, fromObj: T) => T[K], +): { [key in K]: T[key] }; +/** + * pickByKeys与pickRename的合体函数 + * + * @overload 通过key map挑选并重命名, 功能与pickRename函数一致 + * + * @see pickRename + */ +export function pick< + T extends object, + K extends keyof T, + O extends { + [k: string]: K; + }, +>( + originObj: T, + pickKeyMap: O, + cb?: (value: T[O[keyof O]], key: O[keyof O], fromObj: T) => T[O[keyof O]], +): { [k in keyof O]: T[O[k]] }; +export function pick(originObj: object, picks: any[], cb?: Function) { + const isObj = isObject(picks); + // ------- 第一种写法 ------- + // const callback = cb || (v => v); + // const pickKeys = isObj ? Object.keys(picks) : picks; + // const getOriginObjKey = isObj ? k => picks[k] : k => k; + // return pickKeys.reduce((res, k) => { + // const originObjKey = getOriginObjKey(k); + // if (originObj.hasOwnProperty(originObjKey)) { + // res[k] = callback(originObj[originObjKey], originObjKey, originObj); + // } + // return res; + // }, {} as any); + // ------- 第二种写法 ------- + // 更简洁 减少判断次数 + // TO DO 需要判断返回值类型是否改变了 改变则抛出异常 + return isObj + ? pickRename(originObj, picks as any, cb as any) + : pickByKeys(originObj, picks, cb as any); +} diff --git a/src/object/pick/pickByKeys.ts b/src/object/pick/pickByKeys.ts new file mode 100644 index 00000000..7942fc5a --- /dev/null +++ b/src/object/pick/pickByKeys.ts @@ -0,0 +1,38 @@ +/** + * 通过key数组挑选出key数组组成的对象 + * + * @example + * + * const obj = { a: 1, b: '2', c: ['12313', 111], d: false, e: { a: 1 }, f: undefined }; + * + * pickByKeys(obj, []); // {} + * pickByKeys(obj, ['a']); // { a: 1 } + * pickByKeys(obj, ['b']); // { b: obj.b } + * pickByKeys(obj, ['c']); // { c: obj.c } + * pickByKeys(obj, ['a'], (v) => v + 1000); // { a: 1001 } + * // 不存在于对象中的属性会忽略 + * pickByKeys(obj, ['g' as any]); // {} + * + * @param originObj 遍历对象 + * @param pickKeys 需要挑选的key数组 + * @param cb 对值进行修改 + */ +export function pickByKeys( + originObj: T, + pickKeys: K[], + cb?: (value: T[K], key: K, originObj: T) => Pick[K], +): Pick { + const callback = cb || ((v) => v); + return pickKeys.reduce((res, key) => { + res[key] = callback(originObj[key], key, originObj); + return res; + }, {} as any); +} + +// 不完美的地方:k === "a"时应该限定返回值类型为number +/*pickByKeys({ a: 123, b: '111', c: false }, ['a', 'b'], (v, k, o) => { + if (k === 'a') { + return '123123'; + } + return v; +});*/ diff --git a/src/object/pick/pickDiff.ts b/src/object/pick/pickDiff.ts new file mode 100644 index 00000000..0942903b --- /dev/null +++ b/src/object/pick/pickDiff.ts @@ -0,0 +1,44 @@ +import { forEachObj } from '../iterate'; +import { isNaN } from '../../data-type'; +import { hasOwn } from '../common'; + +/** + * 从其他对象中挑出与原对象值不一样的或原对象中不存在的键值对所组成的新对象 + * + * @example + * + * pickDiff({ a: 1 }, []); // {} + * pickDiff({ a: 1 }, [{ a: 1 }]); // {} + * pickDiff({ a: 1 }, [{ a: 2 }]); // { a: 2 } + * pickDiff({ a: 1 }, [{ b: 2 }]); // { b: 2 } + * pickDiff({ a: 1 }, [{ b: 2 }, { a: 1, c: 3 }, { a: 3 }]); // { a: 3, b: 2, c: 3 } + * pickDiff({ a: NaN }, [{ a: NaN, b: 1 }]); // { b: 1 } + * + * const a = { a: { id: 123 } }; + * const b = { a: { id: 123 } }; + * // 虽然值一样,但引用不一样,所以a会被pick出来 + * pickDiff(a, [b]); // { a: { id: 123 } } + * // 通过id判断两个对象是否一样 + * pickDiff(a, [b], (v1, v2, k, origin, obj) => v1.id === v2.id}); // {} + * + */ +export function pickDiff( + origin: object, + objs: object[], + verify?: (originV: any, objV: any, k: string | number, origin: object, obj: object) => boolean, +): { + [k: string]: any; +} { + const verifyFn = + verify || + ((originV, objV, k, origin) => { + return (hasOwn(origin, k) && originV === objV) || (isNaN(originV) && isNaN(objV)); + }); + return objs.reduce((result, obj) => { + forEachObj(obj, (v, k) => { + if (verifyFn(origin[k], v, k, origin, obj)) return; + result[k] = v; + }); + return result; + }, {}); +} diff --git a/src/object/pick/pickExternal.ts b/src/object/pick/pickExternal.ts new file mode 100644 index 00000000..d65d8b62 --- /dev/null +++ b/src/object/pick/pickExternal.ts @@ -0,0 +1,31 @@ +import { pickDiff } from './pickDiff'; +import { hasOwn } from '../common'; + +/** + * 从其他对象中挑出与原对象中不存在的键值对所组成的新对象 + * + * @overload 返回值支持ts类型推导 + * + * @example + * + * pickExternal({ a: 1 }, { a: 2 }); // {} + * pickExternal({ a: 1 }, { b: 2 }); // { b: 2 } + * pickExternal({ a: 1 }, { b: 2, c: 3 }); // { b: 2, c: 3 } + * pickExternal({ a: 1, b: 2 }, { b: 2, c: 3 }); // { c: 3 } + * + */ +export function pickExternal( + origin: T, + other: K, +): Omit; +/** + * 从其他对象中挑出与原对象中不存在的键值对所组成的新对象 + * + * @overload 返回值不支持ts类型推导, 返回的对象类型始终是 Record + * + * pickExternal({ a: 1, b: 2 }, { b: 2, c: 3 }, { b: 2, c: 3 }); // { c: 3 } + */ +export function pickExternal(origin: object, ...others: object[]): Record; +export function pickExternal(origin: object, ...others: object[]) { + return pickDiff(origin, others, (_originV, _objV, k) => hasOwn(origin, k)); +} diff --git a/src/object/pick/pickRename.ts b/src/object/pick/pickRename.ts new file mode 100644 index 00000000..b15196e0 --- /dev/null +++ b/src/object/pick/pickRename.ts @@ -0,0 +1,71 @@ +import { reduceObj } from '../iterate'; + +/** + * pick并且重命名 + * + * 新属性名作为键名的好处是可以多个属性对应一个值 + * + * @example + * + * const obj = { a: 1, b: '2', c: ['12313', 111], d: false, e: { a: 1 }, f: undefined }; + * + * pickRename(obj, {}); // {} + * pickRename(obj, { A: 'a' }); // { A: 1 } + * pickRename(obj, { B: 'b' }); // { B: obj.b } + * pickRename(obj, { C: 'c' }); // { C: obj.c } + * pickRename(obj, { D: 'd' }); // { D: obj.d } + * pickRename(obj, { E: 'e' }); // { E: obj.e } + * // 不存在于对象中的属性会忽略 + * pickRename(obj, { G: 'G' as any }); // {} + * + * @param originObj 需要遍历的对象 + * @param pickKeyMap key map + * @param cb 对值进行修改 + */ +export function pickRename< + T extends object, + K extends keyof T, + O extends { + [k: string]: K; + }, +>( + originObj: T, + pickKeyMap: O, + cb?: (value: T[O[keyof O]], key: O[keyof O], originObj: T) => T[O[keyof O]], +): { [k in keyof O]: T[O[k]] } { + const callback = cb || ((v) => v); + /* const renames = Object.keys(renamePickObj) as (keyof O)[]; + return renames.reduce((result, rename) => { + const pick = renamePickObj[rename]; + if (originObj.hasOwnProperty(pick)) { + result[rename] = callback(originObj[pick], pick, originObj); + } + return result; + }, {} as any);*/ + return reduceObj( + pickKeyMap, + (result, pick, rename) => { + result[rename] = callback(originObj[pick], pick, originObj); + return result; + }, + {} as any, + ); +} + +/* +export function pickRename2< + T extends object, + K extends keyof T, + O extends { [k: string]: K | ((t: T) => T[K]) }, +>(originObj: T, renamePickObj: O): { [k in keyof O]: O[k] extends K ? T[O[k]] : T[K] } { + return {} as any; +} + +pickRename2( + { a: 123, b: '222' }, + { + c: 'a', + d: (obj) => obj.a, + }, +); +*/ diff --git a/src/object/pick/pickUpdated.ts b/src/object/pick/pickUpdated.ts new file mode 100644 index 00000000..4f932cbd --- /dev/null +++ b/src/object/pick/pickUpdated.ts @@ -0,0 +1,46 @@ +import { forEachRight } from '../../array'; +import { isNaN } from '../../data-type'; +import { reduceObj } from '../iterate'; +import { hasOwn } from '../common'; + +/** + * 根据与target对比,挑出与target同key不同value的key所组成的object + * + * @example + * + * const obj1 = { a: 12, b: undefined, c: 3 }; + * pickUpdated(obj1, [{ a: 1 }, { b: 2 }, { d: 3 }]); // { a: 1, b: 2 } + * pickUpdated(obj1, [{ a: 1 }, { a: 2 }, { a: 5 }]); // { a: 5 } + * pickUpdated(obj1, [{ a: 1 }, { a: 2 }, { a: 12 }]); // {} + * pickUpdated(obj1, [{ a: 12 }, { b: undefined }, { c: 3 }]); // {} + * pickUpdated({}, [{ a: 1 }, { b: 2 }, { d: 3 }]); // {} + * pickUpdated({ a: NaN }, [{ a: 1 }, { a: NaN }]); // {} + * pickUpdated({ a: NaN }, [{ a: 1 }, null as any]); // { a: 1 } + * pickUpdated({ a: NaN }, [null as any]); // {} + * pickUpdated({ a: NaN }, [undefined as any]); // {} + * + * @param target 目标对象 + * @param objs 相当于assign(...objs) 同样的key只会取最后一个 + * @param compareFn 比较回调 + */ +export function pickUpdated( + target: T, + objs: object[], + compareFn: (a: unknown, b: unknown) => boolean = (a, b) => a === b || (isNaN(a) && isNaN(b)), +): Partial<{ [k in keyof T]: any }> { + return reduceObj( + target, + (result, _v, k) => { + forEachRight(objs, function (item: any): false | void { + if (item && hasOwn(item, k)) { + if (!compareFn(target[k], item[k])) { + result[k] = item[k]; + } + return false; + } + }); + return result; + }, + {} as any, + ); +} diff --git a/src/object/tree/getTreeMaxDeep.ts b/src/object/tree/getTreeMaxDeep.ts new file mode 100644 index 00000000..38ca156d --- /dev/null +++ b/src/object/tree/getTreeMaxDeep.ts @@ -0,0 +1,24 @@ +import { forEachObj } from '../iterate'; + +/** + * 获取object树的最大层数 tree是object的话,tree就是层数1 + * + * @example + * + * getTreeMaxDeep({}); // 1 + * getTreeMaxDeep({ a: 1 }); // 2 + * getTreeMaxDeep(null as any); // 0 + * getTreeMaxDeep({ a: { b: 1 } }); // 3 + * + */ +export function getTreeMaxDeep(tree: object): number { + function deeps(obj: object, num = 0): number { + if (typeof tree !== 'object' || tree === null) return num; + const arr: number[] = [++num]; + forEachObj(obj, (v) => { + arr.push(deeps(v, num)); + }); + return Math.max(...arr); + } + return deeps(tree); +} diff --git a/src/object/tree.ts b/src/object/tree/getTreeNodeLen.ts similarity index 52% rename from src/object/tree.ts rename to src/object/tree/getTreeNodeLen.ts index b3794f75..57a73ea6 100644 --- a/src/object/tree.ts +++ b/src/object/tree/getTreeNodeLen.ts @@ -1,28 +1,4 @@ -import { forEachObj } from './iterate'; - -/** - * 获取object树的最大层数 tree是object的话,tree就是层数1 - * - * @example - * - * getTreeMaxDeep({}); // 1 - * getTreeMaxDeep({ a: 1 }); // 2 - * getTreeMaxDeep(null as any); // 0 - * getTreeMaxDeep({ a: { b: 1 } }); // 3 - * - */ -export function getTreeMaxDeep(tree: object): number { - function deeps(obj: object, num = 0): number { - if (typeof tree !== 'object' || tree === null) return num; - const arr: number[] = [++num]; - forEachObj(obj, (v) => { - arr.push(deeps(v, num)); - }); - return Math.max(...arr); - } - - return deeps(tree); -} +import { forEachObj } from '../iterate'; /** * 获取树某层的节点数 0是tree本身 @@ -39,7 +15,6 @@ export function getTreeMaxDeep(tree: object): number { export function getTreeNodeLen(tree: object, nodeNumber = 1): number { let result = 0; if (typeof tree !== 'object' || tree === null || nodeNumber < 0) return result; - function deeps(obj: object, num = 0) { if (nodeNumber === num++) { result++; @@ -49,7 +24,6 @@ export function getTreeNodeLen(tree: object, nodeNumber = 1): number { deeps(v, num); }); } - deeps(tree); return result; } diff --git a/src/object/tree/index.ts b/src/object/tree/index.ts new file mode 100644 index 00000000..dd5de04e --- /dev/null +++ b/src/object/tree/index.ts @@ -0,0 +1,2 @@ +export * from './getTreeMaxDeep'; +export * from './getTreeNodeLen'; diff --git a/src/promise.ts b/src/promise.ts deleted file mode 100644 index bac42a58..00000000 --- a/src/promise.ts +++ /dev/null @@ -1,232 +0,0 @@ -/** - * 等待一段时间后再执行后面的代码 - * - * @example - * // 等待100毫秒 - * await sleep(100); - * /* do something *\/ - * - * @param ms 等待时间,单位毫秒 - */ -export function sleep(ms: number): Promise { - return new Promise((res) => setTimeout(res, ms)); -} - -/** - * 一种队列,分支wait和do - * - * 和async、await组合的区别是,lazy支持运行时编程 - * - * @example - * - * lazy() - * .wait(10) - * .do( - * () => - * new Promise(() => { - * // promise不resolve,那么后面的永远不会执行 - * }), - * ) - * .wait(20) - * .do((done) => { - * // 普通函数需要调用done才会继续 - * done(); - * }); - * - */ -export function lazy() { - let queue = Promise.resolve(); - - function then(cb: (done: Function, value: any) => void) { - const q = queue; - queue = new Promise((res) => { - q.then((value) => { - return cb(res, value); - }); - }); - } - - const obj = { - /** - * @param {number} ms 等待毫秒数 - */ - wait(ms: number) { - then((done, value) => setTimeout(() => done(value), ms)); - return obj; - }, - - /** - * @param {((done: Function) => void) | (() => Promise)} cb 回调返回一个值或返回一个promise 供下一个do回调调用 - */ - do(cb: (done: Function, value: unknown) => void | Promise) { - then((done, value) => { - const res = cb(done, value); - if (res && res.then) { - res.then((val) => done(val)); - } - }); - return obj; - }, - }; - - return obj; -} - -/** - * 串行版promise.all,执行完一个才会去执行下一个 - * - * @example - * - * let timeStart = Date.now(); - * let timeEnd = timeStart; - * let num = 0; - * const list = [ - * () => new Promise((res) => { - * setTimeout(() => { - * timeEnd = Date.now(); - * num = 200; - * res(200); - * }, 200); - * }), - * () => ((num = 2), Promise.resolve(2)), - * ]; - * const res = await syncPromiseAll(list); - * - * inRange(timeEnd - timeStart, [200, 300]); // true - * res; // [200, 2] - * num; // 2 - * - */ -export function syncPromiseAll(list: ((list: T[]) => Promise)[]): Promise { - return list.reduce( - (p, next) => - p.then((resList) => - next(resList).then((res) => { - resList.push(res); - return resList; - }), - ), - Promise.resolve([] as T[]), - ); -} - -/** - * promise队列 - * - * 任何一个reject都会中断队列 (跟reduceAsync类似) - * 队列第一个会接收initValue作为参数,其余会接收上一个promise返回值作为参数 - * - * @example - * - * const v = await promiseQueue( - * [(v) => Promise.resolve(`${v} thank you`), (v) => Promise.resolve(`${v} im fine`)], - * 'hello', - * ); - * v; // 'hello thank you im fine' - * - * const v2 = await promiseQueue([(v: any) => `${v} thank you`, (v: any) => `${v} im fine`] as any, 'hello'); - * v2; // 'hello thank you im fine' - * - * - */ -export function promiseQueue( - queue: Array<(lastValue: unknown) => Promise>, - initValue: T, -) { - return queue.reduce( - (p, next) => p.then((res) => next(res)), - Promise.resolve(initValue) as Promise, - ); -} - -/*export async function promiseQueue(queue: Array<(lastValue: unknown) => Promise>, initValue: T) { - let lastValue: unknown = initValue; - await forEachAsync(async (promise) => { - lastValue = await promise(lastValue); - }, queue); - return lastValue; -}*/ - -/** - * 回调支持promise的debounce - * - * 如果callback执行了的话,那么不论是否resolved都不会再被reject - * - * @example - * - * let times = 0; - * - * const dbFn = debounceAsync(() => { - * return new Promise((resolve) => { - * resolve(times++); - * }); - * }, 100); - * - * await Promise.allSettled([dbFn(), dbFn(), dbFn(), dbFn()]); - * - * times; // 1 - * - */ -export function debounceAsync Promise>( - callback: CB, - delay: number, -): CB { - let timer: any = null; - let rej: Function; - - return function (this: any, ...args: any[]) { - return new Promise((resolve, reject) => { - if (timer !== null) { - clearTimeout(timer); - timer = null; - rej('debounceAsync reject'); - } - rej = reject; - timer = setTimeout(async () => { - timer = null; - const result = await callback.apply(this, args); - resolve(result); - }, delay); - }); - } as CB; -} - -/** - * 不使用setTimeout,使用promise实现的debounce - * - * 前一个promise未完成即reject,最后一个或者中断前调用的才会执行 - * 无法阻止cb被调用 不推荐使用 - * - * 只有debounceByPromise(()=>{})().then的.then是防抖的,回调不防抖 - * - * @example - * - * const dbFn = debounceByPromise((time = 50) => { - * const p = new Promise((resolve) => { - * setTimeout(() => { - * resolve(time); - * }, time); - * }); - * p.then(() => { - * times++; - * }); - * return p; - * }); - * - * const res = await Promise.any([dbFn(40), dbFn(20), dbFn(60), dbFn(30)]); - * res; // 30 - * - * - */ -export function debounceByPromise Promise>(callback: CB): CB { - let rejectFn: Function; - return function (this: any, ...args: any[]): Promise { - rejectFn && rejectFn(); - // eslint-disable-next-line no-async-promise-executor - return new Promise(async (res, rej) => { - rejectFn = rej; - const result = await callback.apply(this, args); - res(result); - }); - } as CB; -} diff --git a/src/promise/debounceAsync.ts b/src/promise/debounceAsync.ts new file mode 100644 index 00000000..b6e13781 --- /dev/null +++ b/src/promise/debounceAsync.ts @@ -0,0 +1,42 @@ +/** + * 回调支持promise的debounce + * + * 如果callback执行了的话,那么不论是否resolved都不会再被reject + * + * @example + * + * let times = 0; + * + * const dbFn = debounceAsync(() => { + * return new Promise((resolve) => { + * resolve(times++); + * }); + * }, 100); + * + * await Promise.allSettled([dbFn(), dbFn(), dbFn(), dbFn()]); + * + * times; // 1 + * + */ +export function debounceAsync Promise>( + callback: CB, + delay: number, +): CB { + let timer: any = null; + let rej: Function; + return function (this: any, ...args: any[]) { + return new Promise((resolve, reject) => { + if (timer !== null) { + clearTimeout(timer); + timer = null; + rej('debounceAsync reject'); + } + rej = reject; + timer = setTimeout(async () => { + timer = null; + const result = await callback.apply(this, args); + resolve(result); + }, delay); + }); + } as CB; +} diff --git a/src/promise/debounceByPromise.ts b/src/promise/debounceByPromise.ts new file mode 100644 index 00000000..a4b1e598 --- /dev/null +++ b/src/promise/debounceByPromise.ts @@ -0,0 +1,39 @@ +/** + * 不使用setTimeout,使用promise实现的debounce + * + * 前一个promise未完成即reject,最后一个或者中断前调用的才会执行 + * 无法阻止cb被调用 不推荐使用 + * + * 只有debounceByPromise(()=>{})().then的.then是防抖的,回调不防抖 + * + * @example + * + * const dbFn = debounceByPromise((time = 50) => { + * const p = new Promise((resolve) => { + * setTimeout(() => { + * resolve(time); + * }, time); + * }); + * p.then(() => { + * times++; + * }); + * return p; + * }); + * + * const res = await Promise.any([dbFn(40), dbFn(20), dbFn(60), dbFn(30)]); + * res; // 30 + * + * + */ +export function debounceByPromise Promise>(callback: CB): CB { + let rejectFn: Function; + return function (this: any, ...args: any[]): Promise { + rejectFn && rejectFn(); + + return new Promise(async (res, rej) => { + rejectFn = rej; + const result = await callback.apply(this, args); + res(result); + }); + } as CB; +} diff --git a/src/promise/index.ts b/src/promise/index.ts new file mode 100644 index 00000000..9dab9fc4 --- /dev/null +++ b/src/promise/index.ts @@ -0,0 +1,7 @@ +export * from './sleep'; +export * from './lazy'; +export * from './syncPromiseAll'; +export * from './promiseQueue'; +export * from './debounceAsync'; +export * from './debounceByPromise'; +export * from './nextTick'; diff --git a/src/promise/lazy.ts b/src/promise/lazy.ts new file mode 100644 index 00000000..2eb6421c --- /dev/null +++ b/src/promise/lazy.ts @@ -0,0 +1,55 @@ +/** + * 一种队列,分支wait和do + * + * 和async、await组合的区别是,lazy支持运行时编程 + * + * @example + * + * lazy() + * .wait(10) + * .do( + * () => + * new Promise(() => { + * // promise不resolve,那么后面的永远不会执行 + * }), + * ) + * .wait(20) + * .do((done) => { + * // 普通函数需要调用done才会继续 + * done(); + * }); + * + */ +export function lazy() { + let queue = Promise.resolve(); + function then(cb: (done: Function, value: any) => void) { + const q = queue; + queue = new Promise((res) => { + q.then((value) => { + return cb(res, value); + }); + }); + } + const obj = { + /** + * @param {((done: Function) => void) | (() => Promise)} cb 回调返回一个值或返回一个promise 供下一个do回调调用 + */ + do(cb: (done: Function, value: unknown) => Promise | void) { + then((done, value) => { + const res = cb(done, value); + if (res && res.then) { + res.then((val) => done(val)); + } + }); + return obj; + }, + /** + * @param {number} ms 等待毫秒数 + */ + wait(ms: number) { + then((done, value) => setTimeout(() => done(value), ms)); + return obj; + }, + }; + return obj; +} diff --git a/src/promise/nextTick.ts b/src/promise/nextTick.ts new file mode 100644 index 00000000..494031db --- /dev/null +++ b/src/promise/nextTick.ts @@ -0,0 +1,40 @@ +/** + * 使用promise实现的nextTick + * + * @override ## 返回Promise + * + * @example + * + * nextTick().then(() => { + * // do something + * }); + * + * // or + * + * await nextTick(); + * // do something + */ +export function nextTick(): Promise; +/** + * 使用promise实现的nextTick + * + * @override ## 传入回调,返回中断闭包函数 + * + * @example + * + * const abort = nextTick(() => { + * // do something + * }); + * abort(); // abort + */ +export function nextTick(then: () => unknown): () => void; +export function nextTick(then?: () => unknown): Promise | (() => void) { + const p = Promise.resolve(); + if (!then) return p; + + let aborted = false; + p.then(() => !aborted && then()); + return () => { + aborted = true; + }; +} diff --git a/src/promise/promiseQueue.ts b/src/promise/promiseQueue.ts new file mode 100644 index 00000000..ee1a9bd6 --- /dev/null +++ b/src/promise/promiseQueue.ts @@ -0,0 +1,36 @@ +/** + * promise队列 + * + * 任何一个reject都会中断队列 (跟reduceAsync类似) + * 队列第一个会接收initValue作为参数,其余会接收上一个promise返回值作为参数 + * + * @example + * + * const v = await promiseQueue( + * [(v) => Promise.resolve(`${v} thank you`), (v) => Promise.resolve(`${v} im fine`)], + * 'hello', + * ); + * v; // 'hello thank you im fine' + * + * const v2 = await promiseQueue([(v: any) => `${v} thank you`, (v: any) => `${v} im fine`] as any, 'hello'); + * v2; // 'hello thank you im fine' + * + * + */ +export function promiseQueue( + queue: Array<(lastValue: unknown) => Promise>, + initValue: T, +) { + return queue.reduce( + (p, next) => p.then((res) => next(res)), + Promise.resolve(initValue) as Promise, + ); +} + +/*export async function promiseQueue(queue: Array<(lastValue: unknown) => Promise>, initValue: T) { + let lastValue: unknown = initValue; + await forEachAsync(async (promise) => { + lastValue = await promise(lastValue); + }, queue); + return lastValue; +}*/ diff --git a/src/promise/sleep.ts b/src/promise/sleep.ts new file mode 100644 index 00000000..155af545 --- /dev/null +++ b/src/promise/sleep.ts @@ -0,0 +1,13 @@ +/** + * 等待一段时间后再执行后面的代码 + * + * @example + * // 等待100毫秒 + * await sleep(100); + * /* do something *\/ + * + * @param ms 等待时间,单位毫秒 + */ +export function sleep(ms: number): Promise { + return new Promise((res) => setTimeout(res, ms)); +} diff --git a/src/promise/syncPromiseAll.ts b/src/promise/syncPromiseAll.ts new file mode 100644 index 00000000..ecf0c54b --- /dev/null +++ b/src/promise/syncPromiseAll.ts @@ -0,0 +1,37 @@ +/** + * 串行版promise.all,执行完一个才会去执行下一个 + * + * @example + * + * let timeStart = Date.now(); + * let timeEnd = timeStart; + * let num = 0; + * const list = [ + * () => new Promise((res) => { + * setTimeout(() => { + * timeEnd = Date.now(); + * num = 200; + * res(200); + * }, 200); + * }), + * () => ((num = 2), Promise.resolve(2)), + * ]; + * const res = await syncPromiseAll(list); + * + * inRange(timeEnd - timeStart, [200, 300]); // true + * res; // [200, 2] + * num; // 2 + * + */ +export function syncPromiseAll(list: ((list: T[]) => Promise)[]): Promise { + return list.reduce( + (p, next) => + p.then((resList) => + next(resList).then((res) => { + resList.push(res); + return resList; + }), + ), + Promise.resolve([] as T[]), + ); +} diff --git a/src/random.ts b/src/random.ts deleted file mode 100644 index 82bb0891..00000000 --- a/src/random.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { createArray } from './array'; -import { isArrayLike, isNumber } from './data-type'; - -/** - * min end都不传 return Math.random() - * - * @example - * - * randomFloat(); // 生成0-1之间的浮点数 - * - */ -export function randomFloat(): number; -/** - * 生成0-max之间的随机数, min = 0,不包含max - * - * @example - * - * randomFloat(10); // 生成0-10之间的浮点数 - */ -export function randomFloat(max: number): number; -/** - * 生成min到max之间的随机数 包含min不包含max - * - * @example - * - * randomFloat(2, 10); // 生成2-10之间的浮点数 - */ -export function randomFloat(min: number, max: number): number; -/** - * 生成min到max之间的随机数组 包含min不包含max, len:数组长度 - * - * @example - * - * randomFloat(2, 8, 10); // 生成长度为10的随机数组,每个成员的范围是2-8 - * - */ -export function randomFloat(min: number, max: number, len: number): number[]; -/** - * 生成随机浮点数 - */ -export function randomFloat(min?: number, max?: number, len?: number): number | number[] { - // randomFloat() - if (!arguments.length) return Math.random(); - - let _min = min as number; - let _max = max as number; - - // randomFloat(max) - if (arguments.length === 1) { - _max = _min; - _min = 0; - } - - // randomFloat(min, max) - if (len === undefined) { - const dif = _max - _min; - return Math.random() * dif + _min; - } - return createArray({ len, fill: () => randomFloat(_min, _max) }); -} - -/** - * min end都不传 返回范围:0 - Number.MAX_SAFE_INTEGER - * - * @example - * - * randomFloat(); // 生成0-Number.MAX_SAFE_INTEGER之间的整数 - */ -export function randomInt(): number; -/** - * min = 0 生成0-max之间的随机数,不包含max - * - * @example - * - * randomInt(10); // 生成0-10之间的整数 - */ -export function randomInt(max: number): number; -/** - * 生成min到max之间的随机数 包含min不包含max - * - * @example - * - * randomInt(2,10); // 生成2-10之间的整数 - */ -export function randomInt(min: number, max: number): number; -/** - * 生成min到max之间的随机数组 包含min不包含max len:数组长度 - * - * @example - * - * randomInt(5,10,7); // 生成长度为7的整数数组,每个成员范围为5-10之间 - */ -export function randomInt(min: number, max: number, len: number): number[]; -export function randomInt(min?: number, max?: number, len?: number): number | number[] { - // randomInt() - if (!arguments.length) return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); - - let _min = min as number; - let _max = max as number; - // randomInt(max) - if (arguments.length === 1) { - _max = _min; - _min = 0; - } - - if (len === undefined) { - const dif = _max - _min; - // 直接调用randomFloat的话randomInt(-10,10)永远都不会出现-10 - // 用~~做整数转换的时候,数字太大会变为负数: 如1000 * 60 * 60 * 24 * 30 - // return ~~(Math.random() * dif) + (min as number); - return Math.floor(Math.random() * dif) + _min; - } - return createArray({ len, fill: () => randomInt(_min, _max) }); -} - -/** - * 随机获取数组中的一个 - * - * @example - * - * randomItem([1, 2, 3]); // 返回1-3中的一个 - * - */ -export function randomItem(arr: T[]): T { - const index = randomInt(arr.length); - return arr[index] as T; -} - -/** - * 数组洗牌,不会改变原数组 - * - * @example - * - * const arr = shuffle([1,2,3,4,5]); // 返回一个打乱顺序后的数组 - */ -export function shuffle>(arr: A): A { - if (!isArrayLike(arr)) throw new TypeError(); - const newArr: any = Array.prototype.slice.call(arr); - let m = newArr.length; - while (m) { - const i = randomInt(m--); - [newArr[m], newArr[i]] = [newArr[i], newArr[m]]; - } - return newArr; -} - -/* -export function shuffle(arr: ArrayLike): T[] { - if (!isArrayLike(arr)) throw new TypeError(); - const result: T[] = []; - const indexArr = createArray({len: arr.length}); - while (indexArr.length) { - const index = randomInt(indexArr.length); - const arrIndex = indexArr.splice(index, 1)[0]; - result.push(arr[arrIndex]); - } - return result; -} -*/ - -/** - * 随机RGB颜色 - * - * @example - * - * randomRGB(); // 'rgb([0-255], [0-255], [0-255])' - * - */ -export function randomRGB(): string { - const num = randomInt(0, 255, 3); - return `rgb(${num[0]},${num[1]},${num[2]})`; -} - -/** - * 随机RGBA颜色 - * - * @example - * - * randomRGBA(); // 'rgb([0-255], [0-255], [0-255], [0-1])' - * - */ -export function randomRGBA(): string { - const num = randomInt(0, 255, 3); - const opacity = +randomFloat().toFixed(2); - return `rgba(${num[0]},${num[1]},${num[2]},${opacity})`; -} - -/** - * 随机HEX颜色 - * - * @example - * - * randomHEX(); // '#[0-9a-f]{6}' - * - */ -export function randomHEX(): string { - const num = randomInt(0xffffff).toString(16); - return '#' + num.padStart(6, '0'); -} - -/** - * 随机颜色,无参数时默认为HEX格式的颜色 - * - * @see randomHEX - * - * @example - * - * randomColor(); // '#[0-9a-f]{6}' - */ -export function randomColor(): string; -/** - * 随机类型颜色 - * - * @see randomHEX - * @see randomRGB - * @see randomRGBA - * - * @example - * - * // 随机HEX颜色 - * randomColor('HEX'); - * // 随机RGB颜色 - * randomColor('RGB'); - * // 随机RGBA颜色 - * randomColor('RGBA'); - * - */ -export function randomColor(type: 'HEX' | 'RGB' | 'RGBA'): string; -/** - * 生成HEX颜色数组 - */ -export function randomColor(len: number): string[]; -/** - * 生成 'HEX' | 'RGB' | 'RGBA' 颜色数组 - */ -export function randomColor(type: 'HEX' | 'RGB' | 'RGBA', len: number): string[]; -export function randomColor(type?: string | number, len?: number): string[] | string { - if (isNumber(type)) { - len = type; - type = 'HEX'; - } - if (type === undefined) { - type = 'HEX'; - } - type = type.toUpperCase(); - if (len === undefined) { - const map = { - HEX: randomHEX, - RGB: randomRGB, - RGBA: randomRGBA, - }; - return (map[type as keyof typeof map] || map.HEX)(); - } else { - return createArray({ len, fill: () => randomColor(type as 'HEX' | 'RGB' | 'RGBA') }); - } -} diff --git a/src/random/index.ts b/src/random/index.ts new file mode 100644 index 00000000..285af56a --- /dev/null +++ b/src/random/index.ts @@ -0,0 +1,8 @@ +export * from './randomFloat'; +export * from './randomInt'; +export * from './randomItem'; +export * from './shuffle'; +export * from './randomRGB'; +export * from './randomRGBA'; +export * from './randomHEX'; +export * from './randomColor'; diff --git a/src/random/randomColor.ts b/src/random/randomColor.ts new file mode 100644 index 00000000..cf96e711 --- /dev/null +++ b/src/random/randomColor.ts @@ -0,0 +1,65 @@ +import { randomRGBA } from './randomRGBA'; +import { isNumber } from '../data-type'; +import { randomHEX } from './randomHEX'; +import { randomRGB } from './randomRGB'; +import { createArray } from '../array'; + +/** + * 随机颜色,无参数时默认为HEX格式的颜色 + * + * @see randomHEX + * + * @example + * + * randomColor(); // '#[0-9a-f]{6}' + */ +export function randomColor(): string; +/** + * 随机类型颜色 + * + * @see randomHEX + * @see randomRGB + * @see randomRGBA + * + * @example + * + * // 随机HEX颜色 + * randomColor('HEX'); + * // 随机RGB颜色 + * randomColor('RGB'); + * // 随机RGBA颜色 + * randomColor('RGBA'); + * + */ +export function randomColor(type: 'RGBA' | 'HEX' | 'RGB'): string; +/** + * 生成HEX颜色数组 + */ +export function randomColor(len: number): string[]; +/** + * 生成 'HEX' | 'RGB' | 'RGBA' 颜色数组 + */ +export function randomColor(type: 'RGBA' | 'HEX' | 'RGB', len: number): string[]; +export function randomColor(type?: string | number, len?: number): string[] | string { + if (isNumber(type)) { + len = type; + type = 'HEX'; + } + if (type === undefined) { + type = 'HEX'; + } + type = type.toUpperCase(); + if (len === undefined) { + const map = { + RGBA: randomRGBA, + HEX: randomHEX, + RGB: randomRGB, + }; + return (map[type as keyof typeof map] || map.HEX)(); + } else { + return createArray({ + fill: () => randomColor(type as 'RGBA' | 'HEX' | 'RGB'), + len, + }); + } +} diff --git a/src/random/randomFloat.ts b/src/random/randomFloat.ts new file mode 100644 index 00000000..bfb2220d --- /dev/null +++ b/src/random/randomFloat.ts @@ -0,0 +1,61 @@ +import { createArray } from '../array'; + +/** + * min end都不传 return Math.random() + * + * @example + * + * randomFloat(); // 生成0-1之间的浮点数 + * + */ +export function randomFloat(): number; +/** + * 生成0-max之间的随机数, min = 0,不包含max + * + * @example + * + * randomFloat(10); // 生成0-10之间的浮点数 + */ +export function randomFloat(max: number): number; +/** + * 生成min到max之间的随机数 包含min不包含max + * + * @example + * + * randomFloat(2, 10); // 生成2-10之间的浮点数 + */ +export function randomFloat(min: number, max: number): number; +/** + * 生成min到max之间的随机数组 包含min不包含max, len:数组长度 + * + * @example + * + * randomFloat(2, 8, 10); // 生成长度为10的随机数组,每个成员的范围是2-8 + * + */ +export function randomFloat(min: number, max: number, len: number): number[]; +/** + * 生成随机浮点数 + */ +export function randomFloat(min?: number, max?: number, len?: number): number[] | number { + // randomFloat() + if (!arguments.length) return Math.random(); + let _min = min as number; + let _max = max as number; + + // randomFloat(max) + if (arguments.length === 1) { + _max = _min; + _min = 0; + } + + // randomFloat(min, max) + if (len === undefined) { + const dif = _max - _min; + return Math.random() * dif + _min; + } + return createArray({ + fill: () => randomFloat(_min, _max), + len, + }); +} diff --git a/src/random/randomHEX.ts b/src/random/randomHEX.ts new file mode 100644 index 00000000..851ede68 --- /dev/null +++ b/src/random/randomHEX.ts @@ -0,0 +1,14 @@ +import { randomInt } from './randomInt'; + +/** + * 随机HEX颜色 + * + * @example + * + * randomHEX(); // '#[0-9a-f]{6}' + * + */ +export function randomHEX(): string { + const num = randomInt(0xffffff).toString(16); + return '#' + num.padStart(6, '0'); +} diff --git a/src/random/randomInt.ts b/src/random/randomInt.ts new file mode 100644 index 00000000..4db662c7 --- /dev/null +++ b/src/random/randomInt.ts @@ -0,0 +1,56 @@ +import { createArray } from '../array'; + +/** + * min end都不传 返回范围:0 - Number.MAX_SAFE_INTEGER + * + * @example + * + * randomFloat(); // 生成0-Number.MAX_SAFE_INTEGER之间的整数 + */ +export function randomInt(): number; +/** + * min = 0 生成0-max之间的随机数,不包含max + * + * @example + * + * randomInt(10); // 生成0-10之间的整数 + */ +export function randomInt(max: number): number; +/** + * 生成min到max之间的随机数 包含min不包含max + * + * @example + * + * randomInt(2,10); // 生成2-10之间的整数 + */ +export function randomInt(min: number, max: number): number; +/** + * 生成min到max之间的随机数组 包含min不包含max len:数组长度 + * + * @example + * + * randomInt(5,10,7); // 生成长度为7的整数数组,每个成员范围为5-10之间 + */ +export function randomInt(min: number, max: number, len: number): number[]; +export function randomInt(min?: number, max?: number, len?: number): number[] | number { + // randomInt() + if (!arguments.length) return Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); + let _min = min as number; + let _max = max as number; + // randomInt(max) + if (arguments.length === 1) { + _max = _min; + _min = 0; + } + if (len === undefined) { + const dif = _max - _min; + // 直接调用randomFloat的话randomInt(-10,10)永远都不会出现-10 + // 用~~做整数转换的时候,数字太大会变为负数: 如1000 * 60 * 60 * 24 * 30 + // return ~~(Math.random() * dif) + (min as number); + return Math.floor(Math.random() * dif) + _min; + } + return createArray({ + fill: () => randomInt(_min, _max), + len, + }); +} diff --git a/src/random/randomItem.ts b/src/random/randomItem.ts new file mode 100644 index 00000000..b75cd2de --- /dev/null +++ b/src/random/randomItem.ts @@ -0,0 +1,14 @@ +import { randomInt } from './randomInt'; + +/** + * 随机获取数组中的一个 + * + * @example + * + * randomItem([1, 2, 3]); // 返回1-3中的一个 + * + */ +export function randomItem(arr: T[]): T { + const index = randomInt(arr.length); + return arr[index] as T; +} diff --git a/src/random/randomRGB.ts b/src/random/randomRGB.ts new file mode 100644 index 00000000..a24cbb10 --- /dev/null +++ b/src/random/randomRGB.ts @@ -0,0 +1,14 @@ +import { randomInt } from './randomInt'; + +/** + * 随机RGB颜色 + * + * @example + * + * randomRGB(); // 'rgb([0-255], [0-255], [0-255])' + * + */ +export function randomRGB(): string { + const num = randomInt(0, 255, 3); + return `rgb(${num[0]},${num[1]},${num[2]})`; +} diff --git a/src/random/randomRGBA.ts b/src/random/randomRGBA.ts new file mode 100644 index 00000000..2cfec807 --- /dev/null +++ b/src/random/randomRGBA.ts @@ -0,0 +1,16 @@ +import { randomFloat } from './randomFloat'; +import { randomInt } from './randomInt'; + +/** + * 随机RGBA颜色 + * + * @example + * + * randomRGBA(); // 'rgb([0-255], [0-255], [0-255], [0-1])' + * + */ +export function randomRGBA(): string { + const num = randomInt(0, 255, 3); + const opacity = +randomFloat().toFixed(2); + return `rgba(${num[0]},${num[1]},${num[2]},${opacity})`; +} diff --git a/src/random/shuffle.ts b/src/random/shuffle.ts new file mode 100644 index 00000000..a234b925 --- /dev/null +++ b/src/random/shuffle.ts @@ -0,0 +1,34 @@ +import { isArrayLike } from '../data-type'; +import { randomInt } from './randomInt'; + +/** + * 数组洗牌,不会改变原数组 + * + * @example + * + * const arr = shuffle([1,2,3,4,5]); // 返回一个打乱顺序后的数组 + */ +export function shuffle>(arr: A): A { + if (!isArrayLike(arr)) throw new TypeError(); + const newArr: any = Array.prototype.slice.call(arr); + let m = newArr.length; + while (m) { + const i = randomInt(m--); + [newArr[m], newArr[i]] = [newArr[i], newArr[m]]; + } + return newArr; +} + +/* +export function shuffle(arr: ArrayLike): T[] { + if (!isArrayLike(arr)) throw new TypeError(); + const result: T[] = []; + const indexArr = createArray({len: arr.length}); + while (indexArr.length) { + const index = randomInt(indexArr.length); + const arrIndex = indexArr.splice(index, 1)[0]; + result.push(arr[arrIndex]); + } + return result; +} +*/ diff --git a/src/string.ts b/src/string.ts deleted file mode 100644 index 898967f4..00000000 --- a/src/string.ts +++ /dev/null @@ -1,526 +0,0 @@ -import type { StrTemplate, TupleM2N, ToCamelCase } from '@tool-pack/types'; -import { forEachObj } from './object'; - -/** - * 数字千位分隔 - * - * Number.prototype.toLocaleString 也能转成千位分隔数字字符串 - * - * @example - * - * // 小数位不转换 - * formatNumber(123456789); // '123,456,789' - * formatNumber(123); // '123' - * formatNumber(5763423); // '5,763,423' - * formatNumber(123123.1111); // '123,123.1111' - * - * // 小数位转换 - * formatNumber(123.11, true); // '123.11' - * formatNumber(123123.1111, true); // '123,123.111,1' - * formatNumber(12312311.111111, true); // '12,312,311.111,111' - * formatNumber(12312311.111111); // '12,312,311.111111' - * formatNumber(12312311.111111, true, ' '); // '12 312 311.111 111' - * - * @param num - * @param [isFormatDecimalPlaces=false] 是否格式化小数位 - * @param [delimiter = ","] - */ -export function formatNumber( - num: string | number, - isFormatDecimalPlaces = false, - delimiter = ',', -): string { - // 123123.1111 => 123,123.1,111 - // return String(num).replace(/\B(?=(?:\d{3})+(?!\d))/g, delimiter); - const split = String(num).split('.') as TupleM2N; - split[0] = split[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, delimiter); - if (split.length === 1 || !isFormatDecimalPlaces) return split.join('.'); - split[1] = split[1].replace(/(\d{3})/g, `$1${delimiter}`); - return split.join('.').replace(new RegExp(`${delimiter}$`), ''); -} - -/** - * 模仿c语言的模板字符串 - * - * 目前只支持%s,给不能用``模板字符串的环境使用,像一些es5环境也可以用来事先准备好模板用于替换 - * - * @overload 都是字符串的话ts提示会直接拼接好字符串 - * - * @example - * - * strTemplate('1%s3', '2'); // '123' - * strTemplate('hell%s worl%s', 'o', 'd'); // 'hello world' - * strTemplate('hell%s worl%s'); // 'hell worl' - * - */ -export function strTemplate( - str: T, - ...params: S -): StrTemplate; -/** - * 模仿c语言的模板字符串 - * - * 目前只支持%s,给不能用``模板字符串的环境使用,像一些es5环境也可以用来事先准备好模板用于替换 - * - * @overload 这样的ts提示不准确,%s会变为类型而不是字面值 - * - * @example - * - * ```ts - * strTemplate('1%s%s86', 0, '0') // return: 10086; // type alias: `1${number}${string}86` - * ``` - * - */ -export function strTemplate( - str: T, - ...params: S -): StrTemplate; -export function strTemplate(str: string, ...params: any[]) { - /* - // es5; typescript不需要str, ...params参数` - var args = Array.prototype.slice.call(arguments, 0); - if (!args.length) return ""; - var str = args[0]; - var params = args.slice(1); - */ - return (str as any).replace(/%s/g, function () { - return params.length ? params.shift() : ''; - }) as any; -} - -/** - * 从字符串中删除指定字符串(from)中重复的第n(num)个字符串(str) - * - * @example - * - * removeStrByNum('123/456/78', 2, '/'); // '123/45678' - * removeStrByNum('123,456,,78', 2, ','); // '123,456,78' - * removeStrByNum('hello thank you i m fine', 4, ' '); // 'hello thank you im fine' - * - * @param from 原字符串 - * @param num 要移除的字符串出现的第几次 - * @param removeStr 要查找并移除的字符串 - */ -export function removeStrByNum(from: string, num: number, removeStr: string): string { - let times = 1; - return String(from).replace(new RegExp(removeStr, 'g'), (v) => (times++ === num ? '' : v)); -} - -/** - * 根据模板创建出字符串 - * - * 除了面试题暂时找不到应用场景 - * - * @example - * - * ```ts - * // 基础用法 - * smartRepeat('2[a]'); // 'aa' - * smartRepeat('1[a]'); // 'a' - * - * // 无效数量 - * smartRepeat('[a]'); // '[a]' - * - * // 嵌套 - * smartRepeat('2[2[a]2[b]]'); // 'aabbaabb' - * smartRepeat('2[2[a]2[b]2[c]]'); // 'aabbccaabbcc' - * smartRepeat('2[2[a]2[bc]]'); // 'aabcbcaabcbc' - * smartRepeat('2[2[a]77]'); // 'aa77aa77' - * smartRepeat('2[1[1]2[2]3[2[5]2[6]]]'); // '122556655665566122556655665566' - * smartRepeat('2[1[a]3[b]2[3[c]4[d]]]'); // 'abbbcccddddcccddddabbbcccddddcccdddd' - * smartRepeat('2[1[1]3[b]2[1[1]4[d]]]'); // '1bbb1dddd1dddd1bbb1dddd1dddd' - * - * // 多余的]当普通字符处理 - * smartRepeat('2[2]]'); // '22]' - * - * // `[${string}]`前面非数字则保持原样 - * smartRepeat('2[b][2]'); // 'bb[2]' - * // `[${string}]`前面是数字则补上前面的数字 - * smartRepeat('2[2][2]'); // '2222222222222222222222' - * smartRepeat('2[2][2]').length; // 22 - * - * ``` - */ -export function smartRepeat(format: string): string { - let exec; - - const re = /(\d+)\[([^[\]]+)](?!\d+\[)/; - while ((exec = re.exec(format))) { - const [, count, repeatValue] = exec; - // 第一种方式 - format = format.replace(re, (repeatValue as string).repeat(Number(count))); - // 第二种方式 - // const start = format.substring(0, exec.index); - // const end = format.substring(exec.index + exec[0].length); - // format = start + strRepeat(repeatValue, count) + end; - } - return format; -} - -/** - * 首字母大写 - * - * @example - * - * capitalize('A'); // 'A' - * capitalize('1'); // '1' - * capitalize('ab'); // 'Ab' - * capitalize('Ab'); // 'Ab' - * capitalize('aa'); // 'Aa' - * capitalize(''); // '' - * - */ -export function capitalize(value: S): Capitalize { - if (!value.length) return value as any; - const first = value[0] as string; - return `${first.toUpperCase()}${value.substring(1).toLowerCase()}` as any; -} - -/** - * 从驼峰转其他命名格式 - * - * @example - * - * // 默认下划线分割 - * fromCamel('a'); // 'a' - * fromCamel('A'); // 'a' - * fromCamel('Test'); // 'test' - * fromCamel('TEST'); // 'test' - * fromCamel('testCamel'); // 'test_camel' - * fromCamel('TestCamelString'); // 'test_camel_string' - * fromCamel('TestCamelSTring'); // 'test_camel_string' - * - * // 自定义分割字符 - * fromCamel('TestCamelSTring', '-'); // 'test-camel-string' - * - * // 转大写 - * fromCamel('TestCamelSTring', '-', true); // 'TEST-CAMEL-STRING' - * - * @param {string} value - * @param [delimiter='_'] 默认'_' - * @param [toUpperCase=false] // 为true时 转为全大写的格式 - */ -export function fromCamel(value: string, delimiter = '_', toUpperCase = false) { - const res = value.replace(/([A-Z]+)/g, (_p1, p2, index) => { - return (index > 0 ? delimiter : '') + p2.toLowerCase(); - }); - return toUpperCase ? res.toUpperCase() : res; -} - -/** - * 其他转驼峰 - * - * @example - * - * expect(toCamel('A')).toBe('a'); - * // 转大驼峰 - * toCamel('A', undefined, true); // 'A' - * - * toCamel('a'); // 'a' - * // 转大驼峰 - * toCamel('a', undefined, true); // 'A' - * - * toCamel('1'); // '1' - * - * toCamel('ab'); // 'ab' - * // 转大驼峰 - * toCamel('ab', undefined, true); // 'Ab' - * - * // 默认选项 - * toCamel('aa_bb'); // 'aaBb' - * toCamel('test_camel_string'); // 'testCamelString' - * toCamel('test__camel_string'); // 'testCamelString' - * - * // 默认分隔符,转大驼峰 - * toCamel('test_camel_string', undefined, true); // 'TestCamelString' - * - * // 正则匹配分隔符 - * toCamel('test-camel_string', /[-_]/); // 'testCamelString' - * - * // edge - * toCamel('', ''); // '' - * - * @param {string} value - * @param {string | RegExp} delimiter - * @param {boolean} toUpperCamelCase - */ -export function toCamel< - S extends string, - D extends string | RegExp = '_', - U extends boolean = false, ->( - value: S, - delimiter: D = '_' as D, - toUpperCamelCase: U = false as U, -): D extends string - ? U extends true - ? Capitalize> - : ToCamelCase - : string { - if (!value.length) return value as any; - const reg = typeof delimiter === 'string' ? new RegExp(delimiter + '+') : (delimiter as RegExp); - const join = value.split(reg).map((i) => capitalize(i) as string); - - if (!toUpperCamelCase && join.length) { - join[0] = (join[0] as string).toLowerCase(); - } - return join.join('') as any; -} - -/** - * 获取字符串实际长度 - * - * String.prototype.length获取的是utf-16的长度 - * - * @example - * - * const str = '😂👱👬👨‍👩‍👧👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👧👩‍👧‍👧; // 8个表情,包含组合表情 - * console.log(str.length); // 49 - * console.log(getStringLen(str)); // 8 - * - * const str2 = '🙎🏿'; // 黑皮肤表情 - * console.log(str2.length); // 4 - * console.log(getStringLen(str2)); // 1 - * - * @param value 要获取长度的字符串 - * @returns 字符串实际长度 - */ -export function getStringLen(value: string): number { - /* - // https://www.zhihu.com/question/38324041 - // underscore.js toArray - // const reg = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; - - // 参考 https://juejin.cn/post/6941276804472635405 - // '😂1👱1👬1👨‍👩‍👧1👨‍👩‍👧‍👦23'.split('') - // 8205 是通过 [...'👨‍👩‍👧‍👦123123123'].forEach((v) => console.log(v.codePointAt(0))); 获取的 - // const emojiDelimiter = String.fromCodePoint(8205); // emoji分隔符:该字符看上去很像空格 - const emojiDelimiter = '\u200D'; // (8205).toString(16) - const symbol = '[\ud800-\udbff][\udc00-\udfff]'; - - // 👱🏼‍👱🏿‍皮肤颜色 参考 https://zhuanlan.zhihu.com/p/328516890 - const skinColor = '\ud83c[\udffc-\udfff]'; - - return ( - value - // 先匹配组合表情符号 - .replace(new RegExp(`${symbol}(${emojiDelimiter}${symbol})+`, 'g'), '_') - // 再匹配有皮肤的表情符号 - .replace(new RegExp(`${symbol}${skinColor}`, 'g'), '_') - // 然后匹配普通表情符号 - .replace(new RegExp(symbol, 'g'), '_').length - ); - */ - - // 使用内置对象Intl.Segmenter按字形分割字符串 - const segmenter = new Intl.Segmenter('fr', { granularity: 'grapheme' }); - return Array.from(segmenter.segment(value)).length; -} - -/** - * 字符串遮掩部分或全部 - * - * 可选传start、end - * - * @example - * - * // 省略参数 - * hideString('helloworld'); // '**********' - * // 上面👆省略的约等于下面👇的参数 - * hideString('helloworld', { start: 0, replacement: '*' }); // '**********' - * - * // start等于end时,不做替换 - * hideString('helloworld', { start: 0, end: 0 }); // 'helloworld' - * hideString('helloworld', { start: 5, end: 5 }); // 'helloworld' - * - * // 下面3种结果一样 - * hideString('helloworld', { start: 1, end: -1 }); // 'h********d' - * hideString('helloworld', { start: 1, end: 9 }); // 'h********d' - * hideString('helloworld', { start: -9, end: 9 }); // 'h********d' - * - * // start、end可逆 - * hideString('helloworld', { start: -1, end: 1 }); // 'h********d' - * hideString('helloworld', { start: 9, end: 1 }); // 'h********d' - * - * // 支持表情 - * hideString('👨‍👨‍👧‍👦helloworld👨‍👨‍👧‍👦', { start: 1, end: -1 }); // '👨‍👨‍👧‍👦**********👨‍👨‍👧‍👦' - * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: 1, end: -1 }); // '👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦' - * - * // 替换字符不对应实际字符数量 - * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: -12, end: -1, replacementLen: 1 }); // '👨‍👨‍👧‍👦*👨‍👨‍👧‍👦' - * - * @param origin 原字符串 - * @param [options={}] 选项 - * @param [options.replacement='*'] 替换的字符串,默认为'*' - * @param [options.start=0] 替换起始位置 - * @param [options.end] 替换结束位置 默认为原字符串长度 - * @param [options.replacementLen] 替换字符不对应实际字符数量 - */ -export function hideString( - origin: string, - options?: { replacement?: string; start?: number; end?: number; replacementLen?: number }, -): string; -/** - * 字符串遮掩部分或全部 - * - * 可选传start、len - * - * @example - * - * // 省略参数 - * hideString('helloworld'); // '**********' - * // 上面👆省略的约等于下面👇的参数 - * hideString('helloworld', { start: 0, len: 10 }); // '**********' - * - * // len为0时,不做替换 - * hideString('helloworld', { start: 0, len: 0 }); // 'helloworld' - * - * // 只传len约等于start为0 - * hideString('helloworld', { len: 9 }); // '*********d' - * hideString('helloworld', { start: 0, len: 9 }); // '*********d' - * - * // 下面两种结果一样 - * hideString('helloworld', { start: 1, len: 8 }); // 'h********d' - * hideString('helloworld', { start: -9, len: 8 }); // 'h********d' - * - * // 支持表情 - * hideString('👨‍👨‍👧‍👦helloworld👨‍👨‍👧‍👦', { start: 1, len: 10 }); // '👨‍👨‍👧‍👦**********👨‍👨‍👧‍👦' - * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: 1, len: 11 }); // '👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦' - * - * // 替换字符不对应实际字符数量 - * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: 1, len: 11, replacementLen: 1 }); // '👨‍👨‍👧‍👦*👨‍👨‍👧‍👦' - * - * @param origin 原字符串 - * @param [options={}] 选项 - * @param [options.replacement='*'] 替换的字符串,默认为'*' - * @param [options.start=0] 替换起始位置 - * @param [options.len] 替换文字长度 默认为原字符串长度 - * @param [options.replacementLen] 替换字符不对应实际字符数量 - */ -export function hideString( - origin: string, - options?: { replacement?: string; start?: number; len?: number; replacementLen?: number }, -): string; -/** - * 字符串遮掩部分或全部 - * - * 可选传len、end - * - * @example - * - * // 省略参数 - * hideString('helloworld'); // '**********' - * // 上面👆省略的约等于下面👇的参数 - * hideString('helloworld', { len: 10, end: 10, replacement: '*' }); // '**********' - * - * // len为0时,不做替换 - * hideString('helloworld', { len: 0, end: 10 }); // 'helloworld' - * - * // 下面2种结果一样 - * hideString('helloworld', { len: 8, end: -1 }); // 'h********d' - * hideString('helloworld', { len: 8, end: 9 }); // 'h********d' - * - * // 支持表情 - * hideString('👨‍👨‍👧‍👦helloworld👨‍👨‍👧‍👦', { len: 10, end: -1 }); // '👨‍👨‍👧‍👦**********👨‍👨‍👧‍👦' - * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { len: 11, end: -1 }); // '👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦' - * - * // 替换字符不对应实际字符数量 - * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { len: 11, end: -1, replacementLen: 1 }); // '👨‍👨‍👧‍👦*👨‍👨‍👧‍👦' - * - * @param origin 原字符串 - * @param [options={}] 选项 - * @param [options.replacement='*'] 替换的字符串,默认为'*' - * @param [options.len] 默认为原字符串长度 - * @param [options.end] 替换结束位置 默认为原字符串长度 - * @param [options.replacementLen] 替换字符不对应实际字符数量 - */ -export function hideString( - origin: string, - options?: { replacement?: string; end?: number; len?: number; replacementLen?: number }, -): string; -export function hideString( - origin: string, - { - replacement = '*', - replacementLen = -1, - start, - end, - len, - }: { - replacement?: string; - replacementLen?: number; - start?: number; - end?: number; - len?: number; - } = {}, -): string { - const segmenter = new Intl.Segmenter('fr', { granularity: 'grapheme' }); - const wordList = Array.from(segmenter.segment(origin)); - const wordListLen = wordList.length; - - // start、end的优先级比len高; - const range = [start ?? 0, end ?? wordListLen] as [number, number]; - - if (range[0] < 0) range[0] += wordListLen; - if ((end as number) < 0) range[1] += wordListLen; - - // 有len无start、end的时候,start优先级比end高 - if (len !== undefined) { - if (start === undefined && end !== undefined) range[0] = range[1] - len; - else if (end === undefined) range[1] = range[0] + len; - } - - // 也可以不判断直接sort,但是可能以后不太好理解为什么要sort - if (range[1] < range[0]) range.sort(); - - const _before = wordList.slice(0, range[0]); - const _after = wordList.slice(range[1]); - - const [before, after] = [_before, _after].map((item) => - item.reduce((prev, cur) => prev + cur.segment, ''), - ); - const center = replacement.repeat( - replacementLen !== -1 ? replacementLen : wordListLen - _before.length - _after.length, - ); - - return before + center + after; -} - -/** - * 跟 vue 的条件 className 语法类似 - * - * @example - * - * ```ts - * // string - * getClassNames('a', 'b'); // 'a b' - * - * // object - * getClassNames({ a: true, b: false, c: true }); // 'a c' - * getClassNames({ a: true, b: ' ', c: '' }); // 'a b' - * getClassNames({ a: true, b: 1, c: 0 }); // 'a b' - * - * // string & object - * getClassNames('a', 'b', { a: true, b: false, c: true }); // 'a b c' - * - * // clean multi space - * getClassNames(' ', ' ', { a: true, b: false, c: true }); // 'a c' - * ``` - * - * @param classes 支持字符串和对象类型 - */ -export function getClassNames(...classes: Array>): string { - const classNames: Record = {}; - - const handleObjClasses = (obj: Record): void => { - forEachObj(obj, (v, k): void => { - if (v) classNames[k] = true; - }); - }; - - classes.forEach((item) => - typeof item === 'string' ? (classNames[item] = true) : handleObjClasses(item), - ); - - return Object.keys(classNames).join(' ').trim().replace(/\s+/g, ' '); -} diff --git a/src/string/capitalize.ts b/src/string/capitalize.ts new file mode 100644 index 00000000..06942a19 --- /dev/null +++ b/src/string/capitalize.ts @@ -0,0 +1,19 @@ +/** + * 首字母大写 + * + * @example + * + * capitalize('A'); // 'A' + * capitalize('1'); // '1' + * capitalize('ab'); // 'Ab' + * capitalize('Ab'); // 'Ab' + * capitalize('aa'); // 'Aa' + * capitalize('AAA')); // 'Aaa'; + * capitalize(''); // '' + * + */ +export function capitalize(value: S): Capitalize { + if (!value.length) return value as any; + const first = value[0] as string; + return `${first.toUpperCase()}${value.substring(1).toLowerCase()}` as any; +} diff --git a/src/string/cases/__tests__/splitByCases.test.ts b/src/string/cases/__tests__/splitByCases.test.ts new file mode 100644 index 00000000..dc8a5767 --- /dev/null +++ b/src/string/cases/__tests__/splitByCases.test.ts @@ -0,0 +1,35 @@ +import { splitByCases } from '../splitByCases'; + +test('splitByCases', () => { + const reg = /[\s!-/:-@[-`{-~]+|(? v.toLowerCase()) + .join('-'); +} diff --git a/src/string/cases/pascalCase.ts b/src/string/cases/pascalCase.ts new file mode 100644 index 00000000..808d7270 --- /dev/null +++ b/src/string/cases/pascalCase.ts @@ -0,0 +1,21 @@ +import { splitByCases } from './splitByCases'; +import { capitalize } from '../capitalize'; + +/** + * 其他变量命名风格转大驼峰 + * + * @example + * + * pascalCase('helloWorld'); // 'HelloWorld' + * pascalCase('hello-World'); // 'HelloWorld' + * pascalCase('hello world'); // 'HelloWorld' + * pascalCase('Hello world'); // 'HelloWorld' + * pascalCase('Hello___world'); // 'HelloWorld' + * + */ +export function pascalCase(value: string): string { + if (!value) return value; + return splitByCases(value) + .map((w) => capitalize(w)) + .join(''); +} diff --git a/src/string/cases/snakeCase.ts b/src/string/cases/snakeCase.ts new file mode 100644 index 00000000..2f598b4c --- /dev/null +++ b/src/string/cases/snakeCase.ts @@ -0,0 +1,23 @@ +import { splitByCases } from './splitByCases'; + +/** + * 其他变量命名风格转蛇形 + * + * 跟kebabCase除了分隔符不同,其余基本一样 + * + * @example + * + * kebabCase('aBBcde-fFF__g h'); // 'a_bbcde_f_ff_g_h' + * kebabCase('APPStyle'); 'appstyle' + * kebabCase('APP_Style'); 'app_style' + * kebabCase('abc0Abc0'); // 'abc0_abc0' + * kebabCase('AUV'); // 'auv' + * kebabCase(' Auv'); // 'auv' + * + */ +export function snakeCase(value: string): string { + if (!value) return value; + return splitByCases(value) + .map((w) => w.toLowerCase()) + .join('_'); +} diff --git a/src/string/cases/splitByCases.ts b/src/string/cases/splitByCases.ts new file mode 100644 index 00000000..3bb2d2ba --- /dev/null +++ b/src/string/cases/splitByCases.ts @@ -0,0 +1,57 @@ +import { isASCIIPunctuationSymbol } from '../../data-type'; +import { inRange } from '../../array'; + +/** + * 把各种变量风格的字符串分割成字符串数组 + * + * @example + * + * splitByCases('helloWorld'); // ['hello', 'World'] + * splitByCases('hello-World'); // ['hello', 'World'] + * splitByCases('HelloWorld'); // ['Hello', 'World'] + * splitByCases(' _-hello-_ World_=- '); // ['hello', 'World'] + */ +export function splitByCases(value: string): string[] { + // 后面一大堆代码其实就相当于这一行正则,但是该正则使用了'前瞻后顾',在safari上不兼容,所以还是手动实现 + /** + * 变量命名法通用切割正则 + * + * ascii标点字符定义见该页面 + * @see {@link https://www.kerryr.net/pioneers/ascii3.htm} + */ + // return value.split(/[\s!-/:-@[-`{-~]+|(? inRange(char.charCodeAt(0), upRange); + + for (let i = 0, _separator = '', prevIsUpperCase = false; i < len; i++) { + const char = value[i] as string; + + if (isUpperCase(char)) { + // 连起来的大写字母只能有一个分隔符 + if (!prevIsUpperCase) _separator = separator; + prevIsUpperCase = true; + } else { + prevIsUpperCase = false; + if (char === ' ' || isASCIIPunctuationSymbol(char)) { + _separator = separator; + continue; + } + } + + if (_separator.length && word.length) { + result.push(word); + word = ''; + } + _separator = ''; + word += char; + } + word.length && result.push(word); + + return result; +} diff --git a/src/string/formatNumber.ts b/src/string/formatNumber.ts new file mode 100644 index 00000000..38408627 --- /dev/null +++ b/src/string/formatNumber.ts @@ -0,0 +1,39 @@ +import type { TupleM2N } from '@tool-pack/types'; + +/** + * 数字千位分隔 + * + * Number.prototype.toLocaleString 也能转成千位分隔数字字符串 + * + * @example + * + * // 小数位不转换 + * formatNumber(123456789); // '123,456,789' + * formatNumber(123); // '123' + * formatNumber(5763423); // '5,763,423' + * formatNumber(123123.1111); // '123,123.1111' + * + * // 小数位转换 + * formatNumber(123.11, true); // '123.11' + * formatNumber(123123.1111, true); // '123,123.111,1' + * formatNumber(12312311.111111, true); // '12,312,311.111,111' + * formatNumber(12312311.111111); // '12,312,311.111111' + * formatNumber(12312311.111111, true, ' '); // '12 312 311.111 111' + * + * @param num + * @param [isFormatDecimalPlaces=false] 是否格式化小数位 + * @param [delimiter = ","] + */ +export function formatNumber( + num: string | number, + isFormatDecimalPlaces = false, + delimiter = ',', +): string { + // 123123.1111 => 123,123.1,111 + // return String(num).replace(/\B(?=(?:\d{3})+(?!\d))/g, delimiter); + const split = String(num).split('.') as TupleM2N; + split[0] = split[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, delimiter); + if (split.length === 1 || !isFormatDecimalPlaces) return split.join('.'); + split[1] = split[1].replace(/(\d{3})/g, `$1${delimiter}`); + return split.join('.').replace(new RegExp(`${delimiter}$`), ''); +} diff --git a/src/string/getClassNames.ts b/src/string/getClassNames.ts new file mode 100644 index 00000000..310a38da --- /dev/null +++ b/src/string/getClassNames.ts @@ -0,0 +1,43 @@ +import { forEachObj } from '../object'; + +/** + * 跟 vue 的条件 className 语法类似 + * + * @example + * + * ```ts + * // string | undefined | null + * getClassNames('a', 'b'); // 'a b' + * getClassNames('a', 'b', undefined); // 'a b' + * getClassNames('a', 'b', null); // 'a b' + * + * // object + * getClassNames({ a: true, b: false, c: true }); // 'a c' + * getClassNames({ a: true, b: ' ', c: '' }); // 'a b' + * getClassNames({ a: true, b: 1, c: 0 }); // 'a b' + * + * // string & object + * getClassNames('a', 'b', { a: true, b: false, c: true }); // 'a c' + * + * // clean multi space + * getClassNames(' ', ' ', { a: true, b: false, c: true }); // 'a c' + * ``` + * + * @param classes 支持字符串和对象类型 + */ +export function getClassNames( + ...classes: Array | undefined | string | null> +): string { + const classNames: Record = {}; + const handleObjClasses = (obj: Record): void => { + forEachObj(obj, (v, k): void => { + if (v) classNames[k] = true; + else delete classNames[k]; + }); + }; + classes.forEach( + (item) => + item && (typeof item === 'string' ? (classNames[item] = true) : handleObjClasses(item)), + ); + return Object.keys(classNames).join(' ').trim().replace(/\s+/g, ' '); +} diff --git a/src/string/getStringLen.ts b/src/string/getStringLen.ts new file mode 100644 index 00000000..d32d3bc5 --- /dev/null +++ b/src/string/getStringLen.ts @@ -0,0 +1,48 @@ +/** + * 获取字符串实际长度 + * + * String.prototype.length获取的是utf-16的长度 + * + * @example + * + * const str = '😂👱👬👨‍👩‍👧👨‍👩‍👧‍👦👨‍👩‍👧‍👦👨‍👧👩‍👧‍👧; // 8个表情,包含组合表情 + * console.log(str.length); // 49 + * console.log(getStringLen(str)); // 8 + * + * const str2 = '🙎🏿'; // 黑皮肤表情 + * console.log(str2.length); // 4 + * console.log(getStringLen(str2)); // 1 + * + * @param value 要获取长度的字符串 + * @returns 字符串实际长度 + */ +export function getStringLen(value: string): number { + /* + // https://www.zhihu.com/question/38324041 + // underscore.js toArray + // const reg = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; + // 参考 https://juejin.cn/post/6941276804472635405 + // '😂1👱1👬1👨‍👩‍👧1👨‍👩‍👧‍👦23'.split('') + // 8205 是通过 [...'👨‍👩‍👧‍👦123123123'].forEach((v) => console.log(v.codePointAt(0))); 获取的 + // const emojiDelimiter = String.fromCodePoint(8205); // emoji分隔符:该字符看上去很像空格 + const emojiDelimiter = '\u200D'; // (8205).toString(16) + const symbol = '[\ud800-\udbff][\udc00-\udfff]'; + // 👱🏼‍👱🏿‍皮肤颜色 参考 https://zhuanlan.zhihu.com/p/328516890 + const skinColor = '\ud83c[\udffc-\udfff]'; + return ( + value + // 先匹配组合表情符号 + .replace(new RegExp(`${symbol}(${emojiDelimiter}${symbol})+`, 'g'), '_') + // 再匹配有皮肤的表情符号 + .replace(new RegExp(`${symbol}${skinColor}`, 'g'), '_') + // 然后匹配普通表情符号 + .replace(new RegExp(symbol, 'g'), '_').length + ); + */ + + // 使用内置对象Intl.Segmenter按字形分割字符串 + const segmenter = new Intl.Segmenter('fr', { + granularity: 'grapheme', + }); + return Array.from(segmenter.segment(value)).length; +} diff --git a/src/string/hideString.ts b/src/string/hideString.ts new file mode 100644 index 00000000..f7217c96 --- /dev/null +++ b/src/string/hideString.ts @@ -0,0 +1,181 @@ +/** + * 字符串遮掩部分或全部 + * + * 可选传start、end + * + * @example + * + * // 省略参数 + * hideString('helloworld'); // '**********' + * // 上面👆省略的约等于下面👇的参数 + * hideString('helloworld', { start: 0, replacement: '*' }); // '**********' + * + * // start等于end时,不做替换 + * hideString('helloworld', { start: 0, end: 0 }); // 'helloworld' + * hideString('helloworld', { start: 5, end: 5 }); // 'helloworld' + * + * // 下面3种结果一样 + * hideString('helloworld', { start: 1, end: -1 }); // 'h********d' + * hideString('helloworld', { start: 1, end: 9 }); // 'h********d' + * hideString('helloworld', { start: -9, end: 9 }); // 'h********d' + * + * // start、end可逆 + * hideString('helloworld', { start: -1, end: 1 }); // 'h********d' + * hideString('helloworld', { start: 9, end: 1 }); // 'h********d' + * + * // 支持表情 + * hideString('👨‍👨‍👧‍👦helloworld👨‍👨‍👧‍👦', { start: 1, end: -1 }); // '👨‍👨‍👧‍👦**********👨‍👨‍👧‍👦' + * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: 1, end: -1 }); // '👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦' + * + * // 替换字符不对应实际字符数量 + * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: -12, end: -1, replacementLen: 1 }); // '👨‍👨‍👧‍👦*👨‍👨‍👧‍👦' + * + * @param origin 原字符串 + * @param [options={}] 选项 + * @param [options.replacement='*'] 替换的字符串,默认为'*' + * @param [options.start=0] 替换起始位置 + * @param [options.end] 替换结束位置 默认为原字符串长度 + * @param [options.replacementLen] 替换字符不对应实际字符数量 + */ +export function hideString( + origin: string, + options?: { + replacementLen?: number; + replacement?: string; + start?: number; + end?: number; + }, +): string; +/** + * 字符串遮掩部分或全部 + * + * 可选传start、len + * + * @example + * + * // 省略参数 + * hideString('helloworld'); // '**********' + * // 上面👆省略的约等于下面👇的参数 + * hideString('helloworld', { start: 0, len: 10 }); // '**********' + * + * // len为0时,不做替换 + * hideString('helloworld', { start: 0, len: 0 }); // 'helloworld' + * + * // 只传len约等于start为0 + * hideString('helloworld', { len: 9 }); // '*********d' + * hideString('helloworld', { start: 0, len: 9 }); // '*********d' + * + * // 下面两种结果一样 + * hideString('helloworld', { start: 1, len: 8 }); // 'h********d' + * hideString('helloworld', { start: -9, len: 8 }); // 'h********d' + * + * // 支持表情 + * hideString('👨‍👨‍👧‍👦helloworld👨‍👨‍👧‍👦', { start: 1, len: 10 }); // '👨‍👨‍👧‍👦**********👨‍👨‍👧‍👦' + * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: 1, len: 11 }); // '👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦' + * + * // 替换字符不对应实际字符数量 + * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { start: 1, len: 11, replacementLen: 1 }); // '👨‍👨‍👧‍👦*👨‍👨‍👧‍👦' + * + * @param origin 原字符串 + * @param [options={}] 选项 + * @param [options.replacement='*'] 替换的字符串,默认为'*' + * @param [options.start=0] 替换起始位置 + * @param [options.len] 替换文字长度 默认为原字符串长度 + * @param [options.replacementLen] 替换字符不对应实际字符数量 + */ +export function hideString( + origin: string, + options?: { + replacementLen?: number; + replacement?: string; + start?: number; + len?: number; + }, +): string; +/** + * 字符串遮掩部分或全部 + * + * 可选传len、end + * + * @example + * + * // 省略参数 + * hideString('helloworld'); // '**********' + * // 上面👆省略的约等于下面👇的参数 + * hideString('helloworld', { len: 10, end: 10, replacement: '*' }); // '**********' + * + * // len为0时,不做替换 + * hideString('helloworld', { len: 0, end: 10 }); // 'helloworld' + * + * // 下面2种结果一样 + * hideString('helloworld', { len: 8, end: -1 }); // 'h********d' + * hideString('helloworld', { len: 8, end: 9 }); // 'h********d' + * + * // 支持表情 + * hideString('👨‍👨‍👧‍👦helloworld👨‍👨‍👧‍👦', { len: 10, end: -1 }); // '👨‍👨‍👧‍👦**********👨‍👨‍👧‍👦' + * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { len: 11, end: -1 }); // '👨‍👨‍👧‍👦***********👨‍👨‍👧‍👦' + * + * // 替换字符不对应实际字符数量 + * hideString('👨‍👨‍👧‍👦hello👨‍👨‍👧world👨‍👨‍👧‍👦', { len: 11, end: -1, replacementLen: 1 }); // '👨‍👨‍👧‍👦*👨‍👨‍👧‍👦' + * + * @param origin 原字符串 + * @param [options={}] 选项 + * @param [options.replacement='*'] 替换的字符串,默认为'*' + * @param [options.len] 默认为原字符串长度 + * @param [options.end] 替换结束位置 默认为原字符串长度 + * @param [options.replacementLen] 替换字符不对应实际字符数量 + */ +export function hideString( + origin: string, + options?: { + replacementLen?: number; + replacement?: string; + end?: number; + len?: number; + }, +): string; +export function hideString( + origin: string, + { + replacementLen = -1, + replacement = '*', + start, + end, + len, + }: { + replacementLen?: number; + replacement?: string; + start?: number; + end?: number; + len?: number; + } = {}, +): string { + const segmenter = new Intl.Segmenter('fr', { + granularity: 'grapheme', + }); + const wordList = Array.from(segmenter.segment(origin)); + const wordListLen = wordList.length; + + // start、end的优先级比len高; + const range = [start ?? 0, end ?? wordListLen] as [number, number]; + if (range[0] < 0) range[0] += wordListLen; + if ((end as number) < 0) range[1] += wordListLen; + + // 有len无start、end的时候,start优先级比end高 + if (len !== undefined) { + if (start === undefined && end !== undefined) range[0] = range[1] - len; + else if (end === undefined) range[1] = range[0] + len; + } + + // 也可以不判断直接sort,但是可能以后不太好理解为什么要sort + if (range[1] < range[0]) range.sort(); + const _before = wordList.slice(0, range[0]); + const _after = wordList.slice(range[1]); + const [before, after] = [_before, _after].map((item) => + item.reduce((prev, cur) => prev + cur.segment, ''), + ); + const center = replacement.repeat( + replacementLen !== -1 ? replacementLen : wordListLen - _before.length - _after.length, + ); + return before + center + after; +} diff --git a/src/string/index.ts b/src/string/index.ts new file mode 100644 index 00000000..e439c68b --- /dev/null +++ b/src/string/index.ts @@ -0,0 +1,9 @@ +export * from './formatNumber'; +export * from './strTemplate'; +export * from './removeStrByNum'; +export * from './smartRepeat'; +export * from './capitalize'; +export * from './getStringLen'; +export * from './hideString'; +export * from './getClassNames'; +export * from './cases'; diff --git a/src/string/removeStrByNum.ts b/src/string/removeStrByNum.ts new file mode 100644 index 00000000..8e8d1bf9 --- /dev/null +++ b/src/string/removeStrByNum.ts @@ -0,0 +1,17 @@ +/** + * 从字符串中删除指定字符串(from)中重复的第n(num)个字符串(str) + * + * @example + * + * removeStrByNum('123/456/78', 2, '/'); // '123/45678' + * removeStrByNum('123,456,,78', 2, ','); // '123,456,78' + * removeStrByNum('hello thank you i m fine', 4, ' '); // 'hello thank you im fine' + * + * @param from 原字符串 + * @param num 要移除的字符串出现的第几次 + * @param removeStr 要查找并移除的字符串 + */ +export function removeStrByNum(from: string, num: number, removeStr: string): string { + let times = 1; + return String(from).replace(new RegExp(removeStr, 'g'), (v) => (times++ === num ? '' : v)); +} diff --git a/src/string/smartRepeat.ts b/src/string/smartRepeat.ts new file mode 100644 index 00000000..1571f388 --- /dev/null +++ b/src/string/smartRepeat.ts @@ -0,0 +1,50 @@ +/** + * 根据模板创建出字符串 + * + * 除了面试题暂时找不到应用场景 + * + * @example + * + * ```ts + * // 基础用法 + * smartRepeat('2[a]'); // 'aa' + * smartRepeat('1[a]'); // 'a' + * + * // 无效数量 + * smartRepeat('[a]'); // '[a]' + * + * // 嵌套 + * smartRepeat('2[2[a]2[b]]'); // 'aabbaabb' + * smartRepeat('2[2[a]2[b]2[c]]'); // 'aabbccaabbcc' + * smartRepeat('2[2[a]2[bc]]'); // 'aabcbcaabcbc' + * smartRepeat('2[2[a]77]'); // 'aa77aa77' + * smartRepeat('2[1[1]2[2]3[2[5]2[6]]]'); // '122556655665566122556655665566' + * smartRepeat('2[1[a]3[b]2[3[c]4[d]]]'); // 'abbbcccddddcccddddabbbcccddddcccdddd' + * smartRepeat('2[1[1]3[b]2[1[1]4[d]]]'); // '1bbb1dddd1dddd1bbb1dddd1dddd' + * + * // 多余的]当普通字符处理 + * smartRepeat('2[2]]'); // '22]' + * + * // `[${string}]`前面非数字则保持原样 + * smartRepeat('2[b][2]'); // 'bb[2]' + * // `[${string}]`前面是数字则补上前面的数字 + * smartRepeat('2[2][2]'); // '2222222222222222222222' + * smartRepeat('2[2][2]').length; // 22 + * + * ``` + */ +export function smartRepeat(format: string): string { + let exec; + const re = /(\d+)\[([^[\]]+)](?!\d+\[)/; + while ((exec = re.exec(format))) { + const [, count, repeatValue] = exec; + // 第一种方式 + format = format.replace(re, (repeatValue as string).repeat(Number(count))); + // 第二种方式 + // const start = format.substring(0, exec.index); + // const end = format.substring(exec.index + exec[0].length); + // format = start + strRepeat(repeatValue, count) + end; + } + + return format; +} diff --git a/src/string/strTemplate.ts b/src/string/strTemplate.ts new file mode 100644 index 00000000..63c66dbe --- /dev/null +++ b/src/string/strTemplate.ts @@ -0,0 +1,48 @@ +import type { StrTemplate } from '@tool-pack/types'; + +/** + * 模仿c语言的模板字符串 + * + * 目前只支持%s,给不能用``模板字符串的环境使用,像一些es5环境也可以用来事先准备好模板用于替换 + * + * @overload 都是字符串的话ts提示会直接拼接好字符串 + * + * @example + * + * strTemplate('1%s3', '2'); // '123' + * strTemplate('hell%s worl%s', 'o', 'd'); // 'hello world' + * strTemplate('hell%s worl%s'); // 'hell worl' + * + */ +export function strTemplate( + str: T, + ...params: S +): StrTemplate; +/** + * 模仿c语言的模板字符串 + * + * 目前只支持%s,给不能用``模板字符串的环境使用,像一些es5环境也可以用来事先准备好模板用于替换 + * + * @overload 这样的ts提示不准确,%s会变为类型而不是字面值 + * + * @example + * + * ```ts + * strTemplate('1%s%s86', 0, '0') // return: 10086; // type alias: `1${number}${string}86` + * ``` + * + */ +export function strTemplate( + str: T, + ...params: S +): StrTemplate; +export function strTemplate(str: string, ...params: any[]) { + /* + // es5; typescript不需要str, ...params参数` + var args = Array.prototype.slice.call(arguments, 0); + if (!args.length) return ""; + var str = args[0]; + var params = args.slice(1); + */ + return str.replace(/%s/g, () => (params.length ? params.shift() : '')); +} diff --git a/src/time/createTimeCountUp.ts b/src/time/createTimeCountUp.ts index d1008643..44140e8b 100644 --- a/src/time/createTimeCountUp.ts +++ b/src/time/createTimeCountUp.ts @@ -23,14 +23,14 @@ * */ export function createTimeCountUp(): { - (): number; pause(): void; play(): void; + (): number; } { const startTime = Date.now(); const pause = { - total: 0, startTime: 0, + total: 0, }; function closure(this: any) { const endTime = pause.startTime ? pause.startTime : Date.now(); @@ -40,6 +40,7 @@ export function createTimeCountUp(): { pause.startTime = Date.now(); }; closure.play = function () { + if (pause.startTime === 0) return; pause.total += Date.now() - pause.startTime; pause.startTime = 0; }; diff --git a/src/time/dateAdd.ts b/src/time/dateAdd.ts new file mode 100644 index 00000000..2d7ac07c --- /dev/null +++ b/src/time/dateAdd.ts @@ -0,0 +1,84 @@ +import { isObject } from '../data-type'; +import { forEachObj } from '../object'; + +type AddType = + | 'milliseconds' + | 'minutes' + | 'seconds' + | 'month' + | 'hours' + | 'date' + | 'year' + | 'week'; + +/** + * @example + * + * // 2023-12-16 + * const date = new Date(2023, 11, 16); + * + * // 第二个参数为 number,添加单项 + * formatDate(dateAdd(date, 1, 'year')); // '2024-12-16 00:00:00' + * formatDate(dateAdd(date, -1, 'year')); // '2022-12-16 00:00:00' + * formatDate(dateAdd(date, 1, 'month')); // '2024-01-16 00:00:00' + * formatDate(dateAdd(date, -1, 'month')); // '2023-11-16 00:00:00' + * formatDate(dateAdd(date, 1, 'week')); // '2023-12-23 00:00:00' + * formatDate(dateAdd(date, -1, 'week')); // '2023-12-09 00:00:00' + * formatDate(dateAdd(date, 1, 'date')); // '2023-12-17 00:00:00' + * formatDate(dateAdd(date, -1, 'date')); // '2023-12-15 00:00:00' + * // type 默认为 'date' + * formatDate(dateAdd(date, 1)); // '2023-12-17 00:00:00' + * formatDate(dateAdd(date, 1, 'hours')); // '2023-12-16 01:00:00' + * formatDate(dateAdd(date, -1, 'hours')); // '2023-12-15 23:00:00' + * formatDate(dateAdd(date, 1, 'minutes')); // '2023-12-16 00:01:00' + * formatDate(dateAdd(date, -1, 'minutes')); // '2023-12-15 23:59:00' + * formatDate(dateAdd(date, 1, 'seconds')); // '2023-12-16 00:00:01' + * formatDate(dateAdd(date, -1, 'seconds')); // '2023-12-15 23:59:59' + * formatDate(dateAdd(date, 1000, 'milliseconds')); // '2023-12-16 00:00:01' + * formatDate(dateAdd(date, -1000, 'milliseconds')); // '2023-12-15 23:59:59' + * + * // 第二个参数为 object,添加多项 + * formatDate(dateAdd(date, { year: 1 })); // '2024-12-16 00:00:00' + * const add = { + * year: 1, + * month: 1, + * week: 1, + * date: 1, + * hours: -1, + * minutes: 1, + * seconds: 1, + * milliseconds: -1000, + * }; + * formatDate(dateAdd(date, add)); // '2025-01-23 23:01:00' + * + */ +export function dateAdd(date: Date, addValue: number, type?: AddType): Date; +export function dateAdd(date: Date, add: Partial>): Date; +export function dateAdd( + date: Date, + add: Partial> | number, + type: AddType = 'date', +): Date { + const result = new Date(date); + + const map: Record void> = { + milliseconds: (addValue) => result.setMilliseconds(result.getMilliseconds() + addValue), + minutes: (addValue) => result.setMinutes(result.getMinutes() + addValue), + seconds: (addValue) => result.setSeconds(result.getSeconds() + addValue), + year: (addValue) => result.setFullYear(result.getFullYear() + addValue), + week: (addValue) => result.setDate(result.getDate() + addValue * 7), + month: (addValue) => result.setMonth(result.getMonth() + addValue), + hours: (addValue) => result.setHours(result.getHours() + addValue), + date: (addValue) => result.setDate(result.getDate() + addValue), + }; + + if (isObject(add)) { + forEachObj(add, (v, k) => { + map[k]?.(v as number); + }); + } else { + map[type]?.(add); + } + + return result; +} diff --git a/src/time/dateDiff.ts b/src/time/dateDiff.ts index 3968d5ec..3e5562db 100644 --- a/src/time/dateDiff.ts +++ b/src/time/dateDiff.ts @@ -24,10 +24,6 @@ export function dateDiff(start: Date, end: Date, format = 'y年d天hh时mm分ss const obj: { [k: string]: number; } = { - 'S+': targetTime % 1000, - 's+': seconds % 60, - 'm+': ~~(seconds / 60) % 60, - 'h+': ~~(seconds / (60 * 60)) % 24, 'd+': (function (): number { const day = ~~(seconds / (60 * 60 * 24)); // 如果要显示年,则把天余年,否则全部显示天 @@ -36,6 +32,10 @@ export function dateDiff(start: Date, end: Date, format = 'y年d天hh时mm分ss })(), // "M+": 0, 'y+': ~~(seconds / (60 * 60 * 24 * 365)), + 'h+': ~~(seconds / (60 * 60)) % 24, + 'm+': ~~(seconds / 60) % 60, + 'S+': targetTime % 1000, + 's+': seconds % 60, }; for (const k in obj) { const reg = new RegExp('(' + k + ')'); diff --git a/src/time/formatDate.ts b/src/time/formatDate.ts index d0d81a32..6e9ad055 100644 --- a/src/time/formatDate.ts +++ b/src/time/formatDate.ts @@ -59,32 +59,23 @@ export function formatDate( date: Date, formular = 'yyyy-MM-dd hh:mm:ss', options?: { - seasonNames?: string[]; seasonRanges?: number[][]; + seasonNames?: string[]; weekNames?: string[]; }, ) { const opt = { - weekNames: ['日', '一', '二', '三', '四', '五', '六'], - seasonNames: ['春', '夏', '秋', '冬'], seasonRanges: [ [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 1, 2], ], + weekNames: ['日', '一', '二', '三', '四', '五', '六'], + seasonNames: ['春', '夏', '秋', '冬'], ...options, }; const o: Record = { - 'M+': () => date.getMonth() + 1, - //月份 - 'd+': () => date.getDate(), - //日 - 'h+': () => date.getHours(), - //小时 - 'm+': () => date.getMinutes(), - //分 - 's+': () => date.getSeconds(), //秒 q: () => { //季度 @@ -94,9 +85,18 @@ export function formatDate( const qIndex = opt.seasonRanges.findIndex((range) => range.includes(month)); return opt.seasonNames[qIndex]; }, - 'S+': () => date.getMilliseconds(), //毫秒 w: () => opt.weekNames[date.getDay()], //周 + 'S+': () => date.getMilliseconds(), + 'M+': () => date.getMonth() + 1, + //小时 + 'm+': () => date.getMinutes(), + //分 + 's+': () => date.getSeconds(), + //日 + 'h+': () => date.getHours(), + //月份 + 'd+': () => date.getDate(), }; if (/(y+)/.test(formular)) { diff --git a/src/time/msToDateStr.ts b/src/time/formatMilliseconds.ts similarity index 65% rename from src/time/msToDateStr.ts rename to src/time/formatMilliseconds.ts index d467ff3c..8524de86 100644 --- a/src/time/msToDateStr.ts +++ b/src/time/formatMilliseconds.ts @@ -1,26 +1,26 @@ /** - * 把毫秒值转为天数 + * 格式化毫秒值 * * @example * - * msToDateStr(1000, 'd天hh时'); // '0天00时' - * msToDateStr(1000); // '0天00时00分01秒' - * msToDateStr(60 * 1000); // '0天00时01分00秒' - * msToDateStr(60 * 60 * 1000); // '0天01时00分00秒' - * msToDateStr(60 * 60 * 24 * 1000); // '1天00时00分00秒' + * formatMilliseconds(1000, 'd天hh时'); // '0天00时' + * formatMilliseconds(1000); // '0天00时00分01秒' + * formatMilliseconds(60 * 1000); // '0天00时01分00秒' + * formatMilliseconds(60 * 60 * 1000); // '0天01时00分00秒' + * formatMilliseconds(60 * 60 * 24 * 1000); // '1天00时00分00秒' * * @param ms 毫秒值 * @param [format=d天hh时mm分ss秒] - 格式化模板,默认'd天hh时mm分ss秒' */ -export function msToDateStr(ms: number, format = 'd天hh时mm分ss秒') { +export function formatMilliseconds(ms: number, format = 'd天hh时mm分ss秒') { let result = format; - const seconds = ms / 1000; + const seconds = ~~(ms / 1000); const obj: { [k: string]: number; } = { - 's+': seconds % 60, - 'm+': ~~(seconds / 60) % 60, 'h+': ~~(seconds / (60 * 60)) % 24, + 'm+': ~~(seconds / 60) % 60, + 's+': seconds % 60, // 'd+': ~~(seconds / (60 * 60 * 24)) }; // 有多少天就显示多少天,但不会补0 diff --git a/src/time/getEndOfMonth.ts b/src/time/getEndOfMonth.ts index 1a9c9fbb..7ec5e13c 100644 --- a/src/time/getEndOfMonth.ts +++ b/src/time/getEndOfMonth.ts @@ -17,9 +17,12 @@ * getEndOfMonth(new Date('2021-12')).getDate(); // 31 * getEndOfMonth(new Date('2020-2')).getDate(); // 29 * + * getEndOfMonth(new Date('2021-3'), -1).getDate(); // 28 + * getEndOfMonth(new Date('2021-2'), 1).getDate(); // 31 + * + * @param monthDate 日期 + * @param monthOffset 月份偏移量 1 代表下一个月,-1 代表上一个月 */ -export function getEndOfMonth(monthDate: Date): Date { - const lastDate = new Date(monthDate.getFullYear(), monthDate.getMonth() + 1, monthDate.getDate()); - lastDate.setDate(0); - return lastDate; +export function getEndOfMonth(monthDate: Date, monthOffset = 0): Date { + return new Date(monthDate.getFullYear(), monthDate.getMonth() + 1 + monthOffset, 0); } diff --git a/src/time/getEndOfWeek.ts b/src/time/getEndOfWeek.ts new file mode 100644 index 00000000..8501b406 --- /dev/null +++ b/src/time/getEndOfWeek.ts @@ -0,0 +1,34 @@ +import { getStartOfWeek } from './getStartOfWeek'; +import { dateAdd } from './dateAdd'; + +/** + * 获取某日所在星期结束的date + * + * @example + * + * const getEnd = (date: string, options?: Parameters[1]) => formatDate(getEndOfWeek(new Date(date), options)); + * + * // 星期一为星期第一天 + * getEnd('2023/04/19', { firstDay: 1 }); // '2023-04-23 00:00:00' + * getEnd('2023/04/20', { firstDay: 1 }); // '2023-04-23 00:00:00' + * getEnd('2023/04/16', { firstDay: 1 }); // '2023-04-16 00:00:00' + * getEnd('2023/04/10', { firstDay: 1 }); // '2023-04-16 00:00:00' + * + * // 星期天为星期第一天 + * getEnd('2023/04/19'); // '2023-04-22 00:00:00' + * getEnd('2023/04/16'); // '2023-04-22 00:00:00' + * getEnd('2023/04/09'); // '2023-04-15 00:00:00' + * getEnd('2023/04/10'); // '2023-04-15 00:00:00' + * + * @see getStartOfWeek + * + * @param date + * @param [firstDay=0] 每个星期的开始,可选0-7.默认0周日 + * @param [weekOffset=0] 星期的偏移量,当值为 1 时是下个星期,为-1 时是上个星期以此类推.默认为 0 + */ +export function getEndOfWeek( + date: Date, + { weekOffset = 0, firstDay = 0 }: Parameters[1] = {}, +): Date { + return dateAdd(getStartOfWeek(date, { weekOffset: weekOffset + 1, firstDay }), -1, 'date'); +} diff --git a/src/time/getMilliseconds.ts b/src/time/getMilliseconds.ts index 942149ee..8444cd4e 100644 --- a/src/time/getMilliseconds.ts +++ b/src/time/getMilliseconds.ts @@ -23,15 +23,15 @@ * @param [seconds=0] */ export function getMilliseconds({ - days = 0, - hours = 0, minutes = 0, seconds = 0, + hours = 0, + days = 0, }: { - days?: number; - hours?: number; minutes?: number; seconds?: number; + hours?: number; + days?: number; } = {}): number { const second = 1000; const minute = second * 60; diff --git a/src/time/getMonthTheNthWeekday.ts b/src/time/getMonthTheNthWeekday.ts index 85fb7725..a2cbc71f 100644 --- a/src/time/getMonthTheNthWeekday.ts +++ b/src/time/getMonthTheNthWeekday.ts @@ -1,5 +1,5 @@ -import { inRange } from '../array'; import { getEndOfMonth } from './getEndOfMonth'; +import { inRange } from '../array'; /** * 获取指定某年月份(month)第n(nth)个星期几(weekday)的Date diff --git a/src/time/getStartOfMonth.ts b/src/time/getStartOfMonth.ts new file mode 100644 index 00000000..0f79568a --- /dev/null +++ b/src/time/getStartOfMonth.ts @@ -0,0 +1,16 @@ +/** + * 获取某日所属月的 1 号 + * + * @example + * + * const getStart = (date: string, offset = 0) => formatDate(getStartOfMonth(parseFormattedDate(date), offset)); + * getStart('2023-01-11 19:25:00'); // '2023-01-01 00:00:00' + * getStart('2023-10-01 12:25:00'); // '2023-10-01 00:00:00' + * getStart('2023-12-30 02:25:00'); // '2023-12-01 00:00:00' + * // 月份偏移 + * getStart('2023-12-30 02:25:00', 1); // '2024-01-01 00:00:00' + * getStart('2023-12-30 02:25:00', -1); // '2023-11-01 00:00:00' + */ +export function getStartOfMonth(date: Date, offset = 0): Date { + return new Date(date.getFullYear(), date.getMonth() + offset, 1); +} diff --git a/src/time/getStartOfNextWeek.ts b/src/time/getStartOfNextWeek.ts deleted file mode 100644 index fc8a681a..00000000 --- a/src/time/getStartOfNextWeek.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { getStartOfWeek } from './getStartOfWeek'; - -/** - * 获取某日下个星期开始的date - * - * @example - * - * ```typescript - * formatDate(getStartOfNextWeek(new Date('2023/04/19'))); // '2023-04-24 00:00:00' - * formatDate(getStartOfNextWeek(new Date('2023/04/20'))); // '2023-04-24 00:00:00' - * formatDate(getStartOfNextWeek(new Date('2023/04/16'))); // '2023-04-17 00:00:00' - * formatDate(getStartOfNextWeek(new Date('2023/04/10'))); // '2023-04-17 00:00:00' - * - * formatDate(getStartOfNextWeek(new Date('2023/04/19'), 'SunDay')); // '2023-04-23 00:00:00' - * formatDate(getStartOfNextWeek(new Date('2023/04/16'), 'SunDay')); // '2023-04-23 00:00:00' - * formatDate(getStartOfNextWeek(new Date('2023/04/09'), 'SunDay')); // '2023-04-16 00:00:00' - * formatDate(getStartOfNextWeek(new Date('2023/04/10'), 'SunDay')); // '2023-04-16 00:00:00' - * ``` - * - * @param date - * @param [weekBegin='monday'] 每个星期开始,可选'SunDay'|'MonDay' 周一 周日,默认周一 - */ -export function getStartOfNextWeek(date: Date, weekBegin: 'SunDay' | 'MonDay' = 'MonDay'): Date { - const d = getStartOfWeek(date, weekBegin); - d.setDate(d.getDate() + 7); - return d; -} diff --git a/src/time/getStartOfWeek.ts b/src/time/getStartOfWeek.ts index 93328290..7ccd4ecb 100644 --- a/src/time/getStartOfWeek.ts +++ b/src/time/getStartOfWeek.ts @@ -1,28 +1,46 @@ import { getStartOfDate } from './getStartOfDate'; +import type { WEEK_DAYS } from './time.type'; +import { dateAdd } from './dateAdd'; /** * 获取某日所在星期开始的date * * @example * - * ```typescript - * formatDate(getStartOfWeek(new Date('2023/04/19'))); // '2023-04-17 00:00:00' - * formatDate(getStartOfWeek(new Date('2023/04/20'))); // '2023-04-17 00:00:00' - * formatDate(getStartOfWeek(new Date('2023/04/16'))); // '2023-04-10 00:00:00' - * formatDate(getStartOfWeek(new Date('2023/04/10'))); // '2023-04-10 00:00:00' + * const getStart = (date: string, options?: Parameters[1]) => formatDate(getStartOfWeek(new Date(date), options)); * - * formatDate(getStartOfWeek(new Date('2023/04/19'), 'SunDay')); // '2023-04-16 00:00:00' - * formatDate(getStartOfWeek(new Date('2023/04/16'), 'SunDay')); // '2023-04-16 00:00:00' - * formatDate(getStartOfWeek(new Date('2023/04/09'), 'SunDay')); // '2023-04-09 00:00:00' - * formatDate(getStartOfWeek(new Date('2023/04/10'), 'SunDay')); // '2023-04-09 00:00:00' - * ``` + * // ----- 当前星期 ----- + * // firstDay 为星期一 + * getStart('2023/04/19', { firstDay: 1 }); // '2023-04-17 00:00:00' + * // firstDay 为星期日 + * getStart('2023/04/19', { firstDay: 0 }); // '2023-04-16 00:00:00' + * // firstDay 为星期三 + * getStart('2023/04/16', { firstDay: 3 }); // '2023-04-12 00:00:00' * - * @param date - * @param [weekBegin='monday'] 每个星期开始,可选'SunDay'|'MonDay' 周一 周日,默认周一 + * // ----- 上个星期 ----- + * // firstDay 为星期一 + * getStart('2023/04/19', { firstDay: 1, weekOffset: -1 }); // '2023-04-10 00:00:00' + * // firstDay 为星期日 + * getStart('2023/04/19', { firstDay: 0, weekOffset: -1 }); // '2023-04-09 00:00:00' + * + * // ----- 下个星期 ----- + * // firstDay 为星期一 + * getStart('2023/04/19', { firstDay: 1, weekOffset: 1 }); // '2023-04-24 00:00:00' + * // firstDay 为星期日 + * getStart('2023/04/19', { firstDay: 0, weekOffset: 1 }); // '2023-04-23 00:00:00' + * + * + * @param date 日期 + * @param [firstDay=0] 每个星期的开始,可选0-7.默认0周日 + * @param [weekOffset=0] 星期的偏移量,当值为 1 时是下个星期,为-1 时是上个星期以此类推.默认为 0 */ -export function getStartOfWeek(date: Date, weekBegin: 'SunDay' | 'MonDay' = 'MonDay'): Date { - const d = new Date(date); - const [begin, offset] = weekBegin === 'MonDay' ? [7, -1] : [0, 0]; - d.setDate(d.getDate() - ((d.getDay() || begin) + offset)); - return getStartOfDate(d); +export function getStartOfWeek( + date: Date, + { weekOffset = 0, firstDay = 0 }: { firstDay?: WEEK_DAYS; weekOffset?: number } = {}, +): Date { + const _date = dateAdd(date, weekOffset, 'week'); + const day = _date.getDay(); + const offset = day >= firstDay ? day - firstDay : day + (7 - firstDay); + _date.setDate(_date.getDate() - offset); + return getStartOfDate(_date); } diff --git a/src/time/getTimePeriodConst.ts b/src/time/getTimePeriodConst.ts index 8c296f4c..6b5a7c1f 100644 --- a/src/time/getTimePeriodConst.ts +++ b/src/time/getTimePeriodConst.ts @@ -27,12 +27,12 @@ export const getTimePeriodConst = (function () { millisecond, second, minute, + season, + month, hour, - day, week, - month, - season, year, + day, } as const; return function () { return timeConst; diff --git a/src/time/howLongAgo.ts b/src/time/howLongAgo.ts index 56469641..f6aba381 100644 --- a/src/time/howLongAgo.ts +++ b/src/time/howLongAgo.ts @@ -99,32 +99,32 @@ import { formatDate } from './formatDate'; export function howLongAgo( date: Date, { - now = new Date(), defaultFormat = 'yyyy-MM-dd hh:mm:ss', + now = new Date(), def = '${time}', templates, filter, }: { - defaultFormat?: string; - def?: string; - filter?: (result: string, diff: number) => string; - now?: Date; templates?: Partial< Record, 'millisecond'> | 'now', string> >; + filter?: (result: string, diff: number) => string; + defaultFormat?: string; + def?: string; + now?: Date; } = {}, ): string { const searchValue = '${ago}'; const _templates: Required = { - now: '刚刚', - year: `${searchValue}年前`, + minute: `${searchValue}分钟前`, season: `${searchValue}季前`, + second: `${searchValue}秒前`, month: `${searchValue}月前`, + hour: `${searchValue}小时前`, + year: `${searchValue}年前`, week: `${searchValue}周前`, day: `${searchValue}天前`, - hour: `${searchValue}小时前`, - minute: `${searchValue}分钟前`, - second: `${searchValue}秒前`, + now: '刚刚', ...templates, }; const timePeriodConst = getTimePeriodConst(); diff --git a/src/time/inSameWeek.ts b/src/time/inSameWeek.ts index ce961c10..9c206f22 100644 --- a/src/time/inSameWeek.ts +++ b/src/time/inSameWeek.ts @@ -35,12 +35,12 @@ * @param options.now 日期 默认为当天 */ export function inSameWeek({ - date, weekStart = 'Mon', now = new Date(), + date, }: { - date: Date; weekStart?: 'Mon' | 'Sun'; + date: Date; now?: Date; }): boolean { const timeStamp = date.getTime(); diff --git a/src/time/index.ts b/src/time/index.ts index ca38ad66..108484f0 100644 --- a/src/time/index.ts +++ b/src/time/index.ts @@ -1,4 +1,4 @@ -export * from './msToDateStr'; +export * from './formatMilliseconds'; export * from './formatDate'; export * from './strToDate'; export * from './dateDiff'; @@ -15,4 +15,10 @@ export * from './howLongAgo'; export * from './getEndOfMonth'; export * from './getStartOfDate'; export * from './getStartOfWeek'; -export * from './getStartOfNextWeek'; +export * from './getEndOfWeek'; +export * from './dateAdd'; +export * from './time.type'; +export * from './parseFormattedDate'; +export * from './getStartOfMonth'; +export * from './isNextMonth'; +export * from './isSameDate'; diff --git a/src/time/isNextMonth.ts b/src/time/isNextMonth.ts new file mode 100644 index 00000000..973d3529 --- /dev/null +++ b/src/time/isNextMonth.ts @@ -0,0 +1,21 @@ +import { getStartOfMonth } from './getStartOfMonth'; + +/** + * 判断是否是下个月 + * + * @example + * + * const isNext = (date: string, base: string) => isNextMonth(parseFormattedDate(date), parseFormattedDate(base)); + * + * isNext('2024-02', '2024-01'); // true + * isNext('2024-01', '2023-12'); // true + * isNext('2024-03', '2024-02'); // true + * isNext('2024-01', '2024-12'); // false + * + * @param date 要判断的日期 + * @param relative 相对日期;默认为当前时间; 与 date 互换过来就是判断是否是上个月 + */ +export function isNextMonth(date: Date, relative = new Date()): boolean { + const d = getStartOfMonth(date, -1); + return relative.getFullYear() === d.getFullYear() && d.getMonth() === relative.getMonth(); +} diff --git a/src/time/isSameDate.ts b/src/time/isSameDate.ts new file mode 100644 index 00000000..0f0915ad --- /dev/null +++ b/src/time/isSameDate.ts @@ -0,0 +1,24 @@ +/** + * 判断两个日期是否是同一天 + * + * 当两个日期的年月日一致时为同一天 + * + * @example + * + * const isSame = (date1: string, date2?: string) => isSameDate(parseFormattedDate(date1), date2 ? parseFormattedDate(date2) : undefined); + * + * isSame('2024-01-17', '2024-01-17'); // true + * isSame('2024-01-17 00:00:00', '2024-01-17 12:00:00'); // true + * isSame('2024-01-17', '2024-02-17'); // false + * isSame('2024-01-17', '2023-12-17'); // false + * isSame('2024-01-17'); // false + * + */ +export function isSameDate(date1: Date, date2?: Date): boolean { + if (!date2) return false; + return ( + date1.getDate() === date2.getDate() && + date1.getMonth() === date2.getMonth() && + date1.getFullYear() === date2.getFullYear() + ); +} diff --git a/src/time/parseFormattedDate.ts b/src/time/parseFormattedDate.ts new file mode 100644 index 00000000..9fdf3f6a --- /dev/null +++ b/src/time/parseFormattedDate.ts @@ -0,0 +1,56 @@ +/** + * 解析格式化后的日期字符串 + * + * @example + * + * const parse = (...args: Parameters): string => formatDate(parseFormattedDate(...args)); + * + * parse('2019-12-12 10:10:10'); // '2019-12-12 10:10:10' + * parse('2019-12-12'); // '2019-12-12 00:00:00' + * parse('2019年12月12日', 'yyyy年MM月dd日'); // '2019-12-12 00:00:00' + * + * // 注意日期一定要跟格式一一对应,否则会出现以下不符合规范的日期 + * parse('12月12日', 'yyyy年MM月dd日'); // '0120-12-01 00:00:00' + * + * parse('2023-12'); // '2023-12-01 00:00:00' + * + * @param date 日期字符串 + * @param formular 格式 + */ +export function parseFormattedDate( + date: string, + formular: string = 'yyyy-MM-dd hh:mm:ss:SSS', +): Date { + const len = formular.length; + const obj: Partial> = {}; + + for (let i = 0; i < len; i++) { + const f = formular[i] as keyof typeof LegalCharacter | undefined; + const d = date[i]; + + if (!f || !d) continue; + if (!LegalCharacter[f] || !/\d/.test(d)) continue; + + obj[f] = (obj[f] || '') + (d || ''); + } + + return new Date( + Number(obj.y || '0'), + Number(obj.M || '0') - 1, + Number(obj.d || '1'), + Number(obj.h || '0'), + Number(obj.m || '0'), + Number(obj.s || '0'), + Number(obj.S || '0'), + ); +} + +const LegalCharacter = { + y: true, + M: true, + d: true, + h: true, + m: true, + s: true, + S: true, +}; diff --git a/src/time/strToDate.ts b/src/time/strToDate.ts index 669259d0..157dad79 100644 --- a/src/time/strToDate.ts +++ b/src/time/strToDate.ts @@ -32,12 +32,12 @@ */ export function strToDate( date: - | `${number}-${number}-${number}` - | `${number}-${number}-${number} ${number}:${number}` | `${number}-${number}-${number} ${number}:${number}:${number}` - | `${number}/${number}/${number}` + | `${number}/${number}/${number} ${number}:${number}:${number}` + | `${number}-${number}-${number} ${number}:${number}` | `${number}/${number}/${number} ${number}:${number}` - | `${number}/${number}/${number} ${number}:${number}:${number}`, + | `${number}-${number}-${number}` + | `${number}/${number}/${number}`, ): Date | null { // 检测非数字、非/、非:、非- if (!date || /[^/\d: -]/.test(date)) return null; // 去除不符合规范的字符串 diff --git a/src/time/time.type.ts b/src/time/time.type.ts new file mode 100644 index 00000000..0875f02d --- /dev/null +++ b/src/time/time.type.ts @@ -0,0 +1,2 @@ +export const WeekDays = [0, 1, 2, 3, 4, 5, 6] as const; +export type WEEK_DAYS = (typeof WeekDays)[number]; diff --git a/src/url/model.ts b/src/url/UrlModel.ts similarity index 96% rename from src/url/model.ts rename to src/url/UrlModel.ts index 28856346..116b5b88 100644 --- a/src/url/model.ts +++ b/src/url/UrlModel.ts @@ -1,5 +1,5 @@ +import { stringifyUrlQuery } from './common'; import * as P from './parse'; -import { stringifyUrlQuery } from './url'; /** * 解析url @@ -8,13 +8,13 @@ import { stringifyUrlQuery } from './url'; * @Description: */ export class UrlModel { - protocol = ''; + query: Partial<{ [key: string]: string[] | string }> = {}; port: number | string = ''; + protocol = ''; host = ''; path = ''; href = ''; hash = ''; - query: Partial<{ [key: string]: string[] | string }> = {}; // queryStr: string = ""; @@ -34,10 +34,6 @@ export class UrlModel { toString(template = '{protocol}{host}{port}{pathname}{params}{hash}') { const match = { - '{protocol}': () => (this.protocol ? `${this.protocol}://` : ''), - '{host}': () => this.host || '', - '{port}': () => (this.port ? `:${this.port}` : ''), - '{pathname}': () => this.path || '', '{params}': () => { const query = stringifyUrlQuery(this.query); if (query) { @@ -45,6 +41,10 @@ export class UrlModel { } return ''; }, + '{protocol}': () => (this.protocol ? `${this.protocol}://` : ''), + '{port}': () => (this.port ? `:${this.port}` : ''), + '{pathname}': () => this.path || '', + '{host}': () => this.host || '', '{hash}': () => this.hash || '', }; for (const k in match) { diff --git a/src/url/common/index.ts b/src/url/common/index.ts new file mode 100644 index 00000000..d3066ebb --- /dev/null +++ b/src/url/common/index.ts @@ -0,0 +1,4 @@ +export * from './stringifyUrlQuery'; +export * from './updateUrlQuery'; +export * from './setUrlQuery'; +export * from './isUrl'; diff --git a/src/url/common/isUrl.ts b/src/url/common/isUrl.ts new file mode 100644 index 00000000..5f10c5c6 --- /dev/null +++ b/src/url/common/isUrl.ts @@ -0,0 +1,37 @@ +import { UrlRegExp } from '../regs'; + +/** + * 判断字符串是否是url + * + * @example + * + * isUrl('https://www.test.com/Openapi/api_detail?id=15'); // true + * + * // 不能识别普通网址的端口号 + * isUrl('http://www.baidu.com:112332/index.php/admin/MonitorResultManager/monitorData'); // false + * isUrl('http://www.baidu.com/index.php/admin/MonitorResultManager/monitorData'); // true + * + * // 可以识别localhost的端口号 + * isUrl('http://localhost:1122/index.php/admin/MonitorResultManager/monitorData'); // true + * + * // 端口号范围在2位数到5位数 + * isUrl('http://localhost:111222/index.php/admin/MonitorResultManager/monitorData'); // false + * isUrl('http://localhost:2/index.php/admin/MonitorResultManager/monitorData'); // false + * + * isUrl('www.baidu.com/index.php/admin/MonitorResultManager/monitorData'); // false + * + * // 能识别encodeURIComponent转换过的数据 + * isUrl('http://www.baidu.com/index.php/admin/MonitorResultManager/monitorData?a%5B%5D=123&a%5B%5D=on&b%5B0%5D=on'); // true + * + * // 识别hash + * isUrl('http://www.baidu.com/index.php/?a%5B%5D=123&a%5B%5D=on&b%5B0%5D=on#api-parameter'); // true + * + * // 识别[] + * isUrl('http://www.baidu.com/index.php/?a=1123&b[0]=1&b[1]=2&b[2]=3'); // true + * isUrl('file://E:/wechatCache'); // false + * + * @param url + */ +export function isUrl(url: string): boolean { + return UrlRegExp.test(url); +} diff --git a/src/url/common/setUrlQuery.ts b/src/url/common/setUrlQuery.ts new file mode 100644 index 00000000..de61d5d1 --- /dev/null +++ b/src/url/common/setUrlQuery.ts @@ -0,0 +1,31 @@ +import { UrlModel } from '../UrlModel'; + +/** + * 设置url参数,可新增或删除参数 + * + * @example + * + * let url = 'https://www.test.com/Openapi/api_detail?id=15#api-parameter'; + * url = setUrlQuery({ id: '100' }, url); + * // update + * url; // 'https://www.test.com/Openapi/api_detail?id=100#api-parameter' + * // add + * setUrlQuery({ pid: '15' }, url); // 'https://www.test.com/Openapi/api_detail?id=100&pid=15#api-parameter' + * // delete + * setUrlQuery({ pid: undefined }, url); // 'https://www.test.com/Openapi/api_detail?id=100#api-parameter' + * setUrlQuery({ id: undefined }, url); // 'https://www.test.com/Openapi/api_detail#api-parameter' + * setUrlQuery({ pid: '15' }); // 'http://localhost/?pid=15' + * + * @param param + * @param url + */ +export function setUrlQuery( + param: { + [k: string]: any; + }, + url = location.href, +): string { + const model = new UrlModel(url); + Object.assign(model.query, param); + return model.toString(); +} diff --git a/src/url/common/stringifyUrlQuery.ts b/src/url/common/stringifyUrlQuery.ts new file mode 100644 index 00000000..45c65b1a --- /dev/null +++ b/src/url/common/stringifyUrlQuery.ts @@ -0,0 +1,28 @@ +import { forEachObj, reduceObj } from '../../object'; + +/** + * 把对象转成url query + * + * @example + * + * u.stringifyUrlQuery({ a: 1, b: 2, c: [3, 33], d: { f: '5', g: '6' } }); // 'a=1&b=2&c[0]=3&c[1]=33&d[f]=5&d[g]=6' + * + */ +export function stringifyUrlQuery(query: { [k: string]: any }): string { + return reduceObj( + query, + (initValue, v, k) => { + if (v === undefined) return initValue; + if (typeof v === 'object') { + forEachObj(v, (val, key) => { + if (val === undefined) return; + initValue.push(`${k}[${key as string}]=${encodeURIComponent(val)}`); + }); + } else { + initValue.push(`${k}=${encodeURIComponent(v)}`); + } + return initValue; + }, + [] as string[], + ).join('&'); +} diff --git a/src/url/common/updateUrlQuery.ts b/src/url/common/updateUrlQuery.ts new file mode 100644 index 00000000..9b90f536 --- /dev/null +++ b/src/url/common/updateUrlQuery.ts @@ -0,0 +1,33 @@ +import { forEachObj } from '../../object'; + +/** + * 只能修改url已存在的参数,不能新增或删除参数 + * + * @example + * + * let url = 'https://www.test.com/Openapi/api_detail?id=15#api-parameter'; + * url = updateUrlQuery({ id: '100' }, url); + * url; // url = 'https://www.test.com/Openapi/api_detail?id=100#api-parameter' + * updateUrlQuery({ pid: '15' }, url); // equals url + * updateUrlQuery({ pid: '15' }); // 'http://localhost/' + * + * @param param + * @param [url=location.href] + * @param [encode=true] + */ +export function updateUrlQuery( + param: { + [k: string]: any; + }, + url = location.href, + encode = true, +): string { + forEachObj(param, (value, name) => { + const re = new RegExp('(?:\\?|#|&)' + name + '=([^&#]*)(?:$|&|#)', 'i'); + if (re.test(url)) { + const s = encode ? encodeURIComponent(value) : value; + url = url.replace(`${name}=${RegExp.$1}`, `${name}=${s}`); + } + }); + return url; +} diff --git a/src/url/index.ts b/src/url/index.ts index 181bcd84..5d008b94 100644 --- a/src/url/index.ts +++ b/src/url/index.ts @@ -1,3 +1,4 @@ export * from './parse'; -export * from './url'; -export * from './model'; +export * from './common'; +export * from './UrlModel'; +export * from './regs'; diff --git a/src/url/parse.ts b/src/url/parse.ts deleted file mode 100644 index 9716403b..00000000 --- a/src/url/parse.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { revertObjFromPath } from '../object'; - -// url规则文档:https://datatracker.ietf.org/doc/html/rfc3986 - -const protocolReg = /^(\w+):\/\//; - -/** - * 解析url protocol - * - * @example - * - * u.parseUrlProtocol('file:///E:/wechatCache'); // 'file' - * u.parseUrlProtocol('https://www.baidu.com/index'); // 'https' - * u.parseUrlProtocol('http://www.baidu.com/index'); // 'http' - * u.parseUrlProtocol('/index.php'); // '' - * u.parseUrlProtocol(); // 'http' - * - * @param {string} [url = location.href] - */ -export function parseUrlProtocol(url: string = location.href): string { - const reg = new RegExp(protocolReg); - let schema = ''; - if (reg.test(url)) { - schema = RegExp.$1; - } - return schema; -} - -export const hostReg = /(?:\w+:\/\/|\/\/)((?:[\w\-\u4e00-\u9fa5]+\.?)+\w+)/; - -/** - * 解析url host - * - * @example - * - * u.parseUrlHost('https://www.baidu.com/index'); // 'www.baidu.com' - * u.parseUrlHost('https://www.1223-tewre.com/index'); // 'www.1223-tewre.com' - * u.parseUrlHost('https://www.1223_tewre.com/index'); // 'www.1223_tewre.com' - * u.parseUrlHost('https://www.测试_tewre.com/index'); // 'www.测试_tewre.com' - * u.parseUrlHost('https://www.测试-tewre.com/index'); // 'www.测试-tewre.com' - * u.parseUrlHost('https://www.-tewre测试.com/index'); // 'www.-tewre测试.com' - * u.parseUrlHost('https://www.测试.test.com/index'); // 'www.测试.test.com' - * u.parseUrlHost('http://www.baidu.com/index'); // 'www.baidu.com' - * u.parseUrlHost('http://www.baidu.com:8080/index'); // 'www.baidu.com' - * u.parseUrlHost('www.baidu.com:8080/index'); // '' - * u.parseUrlHost('file://E:/wechatCache'); // '' - * u.parseUrlHost('/index.php'); // '' - * u.parseUrlHost(); // 'localhost' - * - * @param {string} [url = location.href] - */ -export function parseUrlHost(url: string = location.href): string { - const exec = new RegExp(hostReg).exec(url); - return exec ? (exec[1] as string) : ''; -} - -/** - * 解析url port - * - * @example - * - * u.parseUrlPort('/'); // '' - * u.parseUrlPort('https://www.测试.test.com:8080'); // '8080' - * u.parseUrlPort('://localhost:3000'); // '3000' - * u.parseUrlPort(); // '' - * - * @param {string} [url = location.href] - */ -export function parseUrlPort(url: string = location.href): string { - url = url.split('?')[0] as string; - if (/:(\d+)/.test(url)) { - return RegExp.$1; - } - return ''; -} - -/** - * 解析url path - * - * @example - * - * u.parseUrlPath('https://www.baidu.com/index'); // '/index' - * u.parseUrlPath('https://www.1223-tewre.com/index'); // '/index' - * u.parseUrlPath('https://www.测试.test.com/对方是否'); // '/对方是否' - * u.parseUrlPath('https://www.测试.test.com/index?test=123'); // '/index' - * u.parseUrlPath('https://www.测试.test.com/index/test#test'); // '/index/test' - * u.parseUrlPath('https://www.测试.test.com:8080/index/test#test'); // '/index/test' - * u.parseUrlPath('file:///E:/wechatCache'); // '/E:/wechatCache' - * u.parseUrlPath('/index.php'); // '/index.php' - * u.parseUrlPath(); // '/' - * - * @param {string} [url = location.href] - */ -export function parseUrlPath(url: string = location.href): string { - // 去掉query、hash - url = url.split(/[?#]/)[0] as string; - // 去掉schema - return url.replace(new RegExp(`(${hostReg.source}(?::\\d+)?)|${protocolReg.source}`), ''); -} - -/** - * 解析url hash - * - * @example - * - * u.parseUrlHash('/index.php#index/admin'); // '#index/admin' - * u.parseUrlHash('/index.php/#/index/admin#test'); // '#/index/admin#test' - * u.parseUrlHash('/index.php'); // '' - * u.parseUrlHash(); // '' - * - * @param {string} [url = location.href] - */ -export function parseUrlHash(url: string = location.href): string { - const index = url.indexOf('#'); - if (index < 0) return ''; - return url.substring(index); -} - -/** - * 获取hash中的param - * - * @example - * - * getUrlHashParam("a", "test.com/index?a=param/#/test?a=hash") // "hash" - * getUrlHashParam("a", "test.com/index?a=param") // "" - * - * @param name - * @param {string} [url = location.href] - * @param decode 是否decode - */ -export function parseUrlHashQuery(name: string, url = location.href, decode = true): string { - return parseUrlQuery(name, parseUrlHash(url), decode); -} -/** - * 解析url单个query参数 - * - * 来源于网页调起qq 只获取url参数的话可以使用这个 - * @tips 该函数有局限性,只能获取一般的参数,不能获取数组 - * - * @example - * - * parseUrlQuery('id', 'https://www.test.com/Openapi/api_detail?id=15#api-parameter'); // '15' - * - * @param name query名 - * @param [url=location.href] - * @param [decode=true] 是否decode,默认true - */ -export function parseUrlQuery( - name: string, - url = location.href /* node也有 */, - decode = true, -): string { - // 原代码hash也会获取 - // const re = new RegExp("(?:\\?|#|&)" + name + "=([^&]*)(?:$|&|#)", "i"), - // 修改后不会获取到hash - const re = new RegExp('(?:\\?|#|&)' + name + '=([^&#]*)(?:$|&|#)', 'i'); - const m = re.exec(url); - if (m === null) return ''; - const result = m[1] as string; - return decode ? decodeURIComponent(result) : result; -} -/** - * 解析url query对象 - * - * @example - * - * getUrlQueryObj('?a=1&a=2&a=3'); // { a: ['1', '2', '3'] } - * getUrlQueryObj('?a[]=1&a[]=2&a[]=3'); // { a: ['1', '2', '3'] } - * getUrlQueryObj('?a%5B%5D=1&a%5B%5D=2&a%5B%5D=3'); // { a: ['1', '2', '3'] } - * getUrlQueryObj('?a=1&a[]=2&a%5B%5D=3'); // { a: ['1', '2', '3'] } - * getUrlQueryObj('?a=1&a[1]=2'); // { a: ['1', '2'] } - * getUrlQueryObj('?a=1&a[1]=2&a[2]=3'); // { a: ['1', '2', '3'] } - * getUrlQueryObj('a=1&a[1]=2&a[2]=3'); // { a: ['1', '2', '3'] } - * - * @param {string} [url = location.href] - */ -export function parseUrlQueryObj(url: string = location.href): { - [key: string]: string | string[]; -} { - const params = url.match(/[^&#?/]+=[^&#?/]+/g); - - if (!params) return {}; - - return revertObjFromPath(params) as any; -} diff --git a/src/url/parse/index.ts b/src/url/parse/index.ts new file mode 100644 index 00000000..eb1a3340 --- /dev/null +++ b/src/url/parse/index.ts @@ -0,0 +1,8 @@ +export * from './parseUrlProtocol'; +export * from './parseUrlHost'; +export * from './parseUrlPort'; +export * from './parseUrlPath'; +export * from './parseUrlHash'; +export * from './parseUrlHashQuery'; +export * from './parseUrlQuery'; +export * from './parseUrlQueryObj'; diff --git a/src/url/parse/parseUrlHash.ts b/src/url/parse/parseUrlHash.ts new file mode 100644 index 00000000..f7c663ba --- /dev/null +++ b/src/url/parse/parseUrlHash.ts @@ -0,0 +1,17 @@ +/** + * 解析url hash + * + * @example + * + * u.parseUrlHash('/index.php#index/admin'); // '#index/admin' + * u.parseUrlHash('/index.php/#/index/admin#test'); // '#/index/admin#test' + * u.parseUrlHash('/index.php'); // '' + * u.parseUrlHash(); // '' + * + * @param {string} [url = location.href] + */ +export function parseUrlHash(url: string = location.href): string { + const index = url.indexOf('#'); + if (index < 0) return ''; + return url.substring(index); +} diff --git a/src/url/parse/parseUrlHashQuery.ts b/src/url/parse/parseUrlHashQuery.ts new file mode 100644 index 00000000..8448d1ea --- /dev/null +++ b/src/url/parse/parseUrlHashQuery.ts @@ -0,0 +1,18 @@ +import { parseUrlQuery } from './parseUrlQuery'; +import { parseUrlHash } from './parseUrlHash'; + +/** + * 获取hash中的param + * + * @example + * + * getUrlHashParam("a", "test.com/index?a=param/#/test?a=hash") // "hash" + * getUrlHashParam("a", "test.com/index?a=param") // "" + * + * @param name + * @param {string} [url = location.href] + * @param decode 是否decode + */ +export function parseUrlHashQuery(name: string, url = location.href, decode = true): string { + return parseUrlQuery(name, parseUrlHash(url), decode); +} diff --git a/src/url/parse/parseUrlHost.ts b/src/url/parse/parseUrlHost.ts new file mode 100644 index 00000000..f4b5f8d0 --- /dev/null +++ b/src/url/parse/parseUrlHost.ts @@ -0,0 +1,27 @@ +import { UrlHostReg } from '../regs'; + +/** + * 解析url host + * + * @example + * + * u.parseUrlHost('https://www.baidu.com/index'); // 'www.baidu.com' + * u.parseUrlHost('https://www.1223-tewre.com/index'); // 'www.1223-tewre.com' + * u.parseUrlHost('https://www.1223_tewre.com/index'); // 'www.1223_tewre.com' + * u.parseUrlHost('https://www.测试_tewre.com/index'); // 'www.测试_tewre.com' + * u.parseUrlHost('https://www.测试-tewre.com/index'); // 'www.测试-tewre.com' + * u.parseUrlHost('https://www.-tewre测试.com/index'); // 'www.-tewre测试.com' + * u.parseUrlHost('https://www.测试.test.com/index'); // 'www.测试.test.com' + * u.parseUrlHost('http://www.baidu.com/index'); // 'www.baidu.com' + * u.parseUrlHost('http://www.baidu.com:8080/index'); // 'www.baidu.com' + * u.parseUrlHost('www.baidu.com:8080/index'); // '' + * u.parseUrlHost('file://E:/wechatCache'); // '' + * u.parseUrlHost('/index.php'); // '' + * u.parseUrlHost(); // 'localhost' + * + * @param {string} [url = location.href] + */ +export function parseUrlHost(url: string = location.href): string { + const exec = new RegExp(UrlHostReg).exec(url); + return exec ? (exec[1] as string) : ''; +} diff --git a/src/url/parse/parseUrlPath.ts b/src/url/parse/parseUrlPath.ts new file mode 100644 index 00000000..a361500b --- /dev/null +++ b/src/url/parse/parseUrlPath.ts @@ -0,0 +1,25 @@ +import { UrlProtocolReg, UrlHostReg } from '../regs'; + +/** + * 解析url path + * + * @example + * + * u.parseUrlPath('https://www.baidu.com/index'); // '/index' + * u.parseUrlPath('https://www.1223-tewre.com/index'); // '/index' + * u.parseUrlPath('https://www.测试.test.com/对方是否'); // '/对方是否' + * u.parseUrlPath('https://www.测试.test.com/index?test=123'); // '/index' + * u.parseUrlPath('https://www.测试.test.com/index/test#test'); // '/index/test' + * u.parseUrlPath('https://www.测试.test.com:8080/index/test#test'); // '/index/test' + * u.parseUrlPath('file:///E:/wechatCache'); // '/E:/wechatCache' + * u.parseUrlPath('/index.php'); // '/index.php' + * u.parseUrlPath(); // '/' + * + * @param {string} [url = location.href] + */ +export function parseUrlPath(url: string = location.href): string { + // 去掉query、hash + url = url.split(/[?#]/)[0] as string; + // 去掉schema + return url.replace(new RegExp(`(${UrlHostReg.source}(?::\\d+)?)|${UrlProtocolReg.source}`), ''); +} diff --git a/src/url/parse/parseUrlPort.ts b/src/url/parse/parseUrlPort.ts new file mode 100644 index 00000000..0178dee5 --- /dev/null +++ b/src/url/parse/parseUrlPort.ts @@ -0,0 +1,19 @@ +/** + * 解析url port + * + * @example + * + * u.parseUrlPort('/'); // '' + * u.parseUrlPort('https://www.测试.test.com:8080'); // '8080' + * u.parseUrlPort('://localhost:3000'); // '3000' + * u.parseUrlPort(); // '' + * + * @param {string} [url = location.href] + */ +export function parseUrlPort(url: string = location.href): string { + url = url.split('?')[0] as string; + if (/:(\d+)/.test(url)) { + return RegExp.$1; + } + return ''; +} diff --git a/src/url/parse/parseUrlProtocol.ts b/src/url/parse/parseUrlProtocol.ts new file mode 100644 index 00000000..29379a32 --- /dev/null +++ b/src/url/parse/parseUrlProtocol.ts @@ -0,0 +1,23 @@ +import { UrlProtocolReg } from '../regs'; + +/** + * 解析url protocol + * + * @example + * + * u.parseUrlProtocol('file:///E:/wechatCache'); // 'file' + * u.parseUrlProtocol('https://www.baidu.com/index'); // 'https' + * u.parseUrlProtocol('http://www.baidu.com/index'); // 'http' + * u.parseUrlProtocol('/index.php'); // '' + * u.parseUrlProtocol(); // 'http' + * + * @param {string} [url = location.href] + */ +export function parseUrlProtocol(url: string = location.href): string { + const reg = new RegExp(UrlProtocolReg); + let schema = ''; + if (reg.test(url)) { + schema = RegExp.$1; + } + return schema; +} diff --git a/src/url/parse/parseUrlQuery.ts b/src/url/parse/parseUrlQuery.ts new file mode 100644 index 00000000..9b897be7 --- /dev/null +++ b/src/url/parse/parseUrlQuery.ts @@ -0,0 +1,28 @@ +/** + * 解析url单个query参数 + * + * 来源于网页调起qq 只获取url参数的话可以使用这个 + * @tips 该函数有局限性,只能获取一般的参数,不能获取数组 + * + * @example + * + * parseUrlQuery('id', 'https://www.test.com/Openapi/api_detail?id=15#api-parameter'); // '15' + * + * @param name query名 + * @param [url=location.href] + * @param [decode=true] 是否decode,默认true + */ +export function parseUrlQuery( + name: string, + url = location.href /* node也有 */, + decode = true, +): string { + // 原代码hash也会获取 + // const re = new RegExp("(?:\\?|#|&)" + name + "=([^&]*)(?:$|&|#)", "i"), + // 修改后不会获取到hash + const re = new RegExp('(?:\\?|#|&)' + name + '=([^&#]*)(?:$|&|#)', 'i'); + const m = re.exec(url); + if (m === null) return ''; + const result = m[1] as string; + return decode ? decodeURIComponent(result) : result; +} diff --git a/src/url/parse/parseUrlQueryObj.ts b/src/url/parse/parseUrlQueryObj.ts new file mode 100644 index 00000000..0b209a9f --- /dev/null +++ b/src/url/parse/parseUrlQueryObj.ts @@ -0,0 +1,24 @@ +import { revertObjFromPath } from '../../object'; + +/** + * 解析url query对象 + * + * @example + * + * getUrlQueryObj('?a=1&a=2&a=3'); // { a: ['1', '2', '3'] } + * getUrlQueryObj('?a[]=1&a[]=2&a[]=3'); // { a: ['1', '2', '3'] } + * getUrlQueryObj('?a%5B%5D=1&a%5B%5D=2&a%5B%5D=3'); // { a: ['1', '2', '3'] } + * getUrlQueryObj('?a=1&a[]=2&a%5B%5D=3'); // { a: ['1', '2', '3'] } + * getUrlQueryObj('?a=1&a[1]=2'); // { a: ['1', '2'] } + * getUrlQueryObj('?a=1&a[1]=2&a[2]=3'); // { a: ['1', '2', '3'] } + * getUrlQueryObj('a=1&a[1]=2&a[2]=3'); // { a: ['1', '2', '3'] } + * + * @param {string} [url = location.href] + */ +export function parseUrlQueryObj(url: string = location.href): { + [key: string]: string[] | string; +} { + const params = url.match(/[^&#?/]+=[^&#?/]+/g); + if (!params) return {}; + return revertObjFromPath(params) as any; +} diff --git a/src/url/regs.ts b/src/url/regs.ts new file mode 100644 index 00000000..a8eb533b --- /dev/null +++ b/src/url/regs.ts @@ -0,0 +1,10 @@ +// 参考async-validator +export const UrlRegExp = new RegExp( + '^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4])|(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*\\.[a-z\\u00a1-\\uffff]{2,})|localhost)(?::\\d{2,5})?(?:([/?#])[^\\s]*)?$', + 'i', +); + +export const UrlHostReg = /(?:\w+:\/\/|\/\/)((?:[\w\-\u4e00-\u9fa5]+\.?)+\w+)/; + +// url规则文档:https://datatracker.ietf.org/doc/html/rfc3986 +export const UrlProtocolReg = /^(\w+):\/\//; diff --git a/src/url/url.ts b/src/url/url.ts deleted file mode 100644 index 98caef6a..00000000 --- a/src/url/url.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { forEachObj, reduceObj } from '../object'; -import { UrlModel } from './model'; - -/** - * 把对象转成url query - * - * @example - * - * u.stringifyUrlQuery({ a: 1, b: 2, c: [3, 33], d: { f: '5', g: '6' } }); // 'a=1&b=2&c[0]=3&c[1]=33&d[f]=5&d[g]=6' - * - */ -export function stringifyUrlQuery(query: { [k: string]: any }): string { - return reduceObj( - query, - (initValue, v, k) => { - if (v === undefined) return initValue; - if (typeof v === 'object') { - forEachObj(v, (val, key) => { - if (val === undefined) return; - initValue.push(`${k}[${key as string}]=${encodeURIComponent(val)}`); - }); - } else { - initValue.push(`${k}=${encodeURIComponent(v)}`); - } - return initValue; - }, - [] as string[], - ).join('&'); -} - -/** - * 只能修改url已存在的参数,不能新增或删除参数 - * - * @example - * - * let url = 'https://www.test.com/Openapi/api_detail?id=15#api-parameter'; - * url = updateUrlQuery({ id: '100' }, url); - * url; // url = 'https://www.test.com/Openapi/api_detail?id=100#api-parameter' - * updateUrlQuery({ pid: '15' }, url); // equals url - * updateUrlQuery({ pid: '15' }); // 'http://localhost/' - * - * @param param - * @param [url=location.href] - * @param [encode=true] - */ -export function updateUrlQuery( - param: { [k: string]: any }, - url = location.href, - encode = true, -): string { - forEachObj(param, (value, name) => { - const re = new RegExp('(?:\\?|#|&)' + name + '=([^&#]*)(?:$|&|#)', 'i'); - if (re.test(url)) { - const s = encode ? encodeURIComponent(value) : value; - url = url.replace(`${name}=${RegExp.$1}`, `${name}=${s}`); - } - }); - return url; -} - -/** - * 设置url参数,可新增或删除参数 - * - * @example - * - * let url = 'https://www.test.com/Openapi/api_detail?id=15#api-parameter'; - * url = setUrlQuery({ id: '100' }, url); - * // update - * url; // 'https://www.test.com/Openapi/api_detail?id=100#api-parameter' - * // add - * setUrlQuery({ pid: '15' }, url); // 'https://www.test.com/Openapi/api_detail?id=100&pid=15#api-parameter' - * // delete - * setUrlQuery({ pid: undefined }, url); // 'https://www.test.com/Openapi/api_detail?id=100#api-parameter' - * setUrlQuery({ id: undefined }, url); // 'https://www.test.com/Openapi/api_detail#api-parameter' - * setUrlQuery({ pid: '15' }); // 'http://localhost/?pid=15' - * - * @param param - * @param url - */ -export function setUrlQuery(param: { [k: string]: any }, url = location.href): string { - const model = new UrlModel(url); - Object.assign(model.query, param); - return model.toString(); -} - -// 参考async-validator -export const UrlRegExp = new RegExp( - '^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4])|(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*\\.[a-z\\u00a1-\\uffff]{2,})|localhost)(?::\\d{2,5})?(?:([/?#])[^\\s]*)?$', - 'i', -); - -/** - * 判断字符串是否是url - * - * @example - * - * isUrl('https://www.test.com/Openapi/api_detail?id=15'); // true - * - * // 不能识别普通网址的端口号 - * isUrl('http://www.baidu.com:112332/index.php/admin/MonitorResultManager/monitorData'); // false - * isUrl('http://www.baidu.com/index.php/admin/MonitorResultManager/monitorData'); // true - * - * // 可以识别localhost的端口号 - * isUrl('http://localhost:1122/index.php/admin/MonitorResultManager/monitorData'); // true - * - * // 端口号范围在2位数到5位数 - * isUrl('http://localhost:111222/index.php/admin/MonitorResultManager/monitorData'); // false - * isUrl('http://localhost:2/index.php/admin/MonitorResultManager/monitorData'); // false - * - * isUrl('www.baidu.com/index.php/admin/MonitorResultManager/monitorData'); // false - * - * // 能识别encodeURIComponent转换过的数据 - * isUrl('http://www.baidu.com/index.php/admin/MonitorResultManager/monitorData?a%5B%5D=123&a%5B%5D=on&b%5B0%5D=on'); // true - * - * // 识别hash - * isUrl('http://www.baidu.com/index.php/?a%5B%5D=123&a%5B%5D=on&b%5B0%5D=on#api-parameter'); // true - * - * // 识别[] - * isUrl('http://www.baidu.com/index.php/?a=1123&b[0]=1&b[1]=2&b[2]=3'); // true - * isUrl('file://E:/wechatCache'); // false - * - * @param url - */ -export function isUrl(url: string): boolean { - return UrlRegExp.test(url); -} diff --git a/typedoc.json b/typedoc.json index 3fc703f1..0a8c27c8 100644 --- a/typedoc.json +++ b/typedoc.json @@ -1,13 +1,13 @@ { "$schema": "https://typedoc.org/schema.json", - "htmlLang": "zh-CN", + "lang": "zh", "includeVersion": true, "plugin": ["@mxssfd/typedoc-theme"], "theme": "my-theme", "customCss": "./typedoc.theme.css", "sort": ["static-first", "kind", "enum-value-ascending"], "categoryOrder": ["file"], - "out": "./docs-html", + "out": "./docs-dist", "categorizeByGroup": true, "searchCategoryBoosts": { "Component": 2, diff --git a/typedoc.theme.css b/typedoc.theme.css index 0fea7869..6bf10d90 100644 --- a/typedoc.theme.css +++ b/typedoc.theme.css @@ -1,3 +1,3 @@ -.tsd-generator { +footer { display: none; }