From 762c64f8dc91a660135904c17850ee1ed6056369 Mon Sep 17 00:00:00 2001 From: Daymon Date: Sat, 24 Aug 2024 18:05:05 -0500 Subject: [PATCH 01/14] initial upload --- .eslintrc | 40 + .gitattributes | 2 + .gitignore | 3 + .prettierrc | 7 + .vscode/extensions.json | 6 + .vscode/settings.json | 22 + LICENSE | 201 + README.md | 9 + api-extractor.json | 454 + default.project.json | 6 + dist/rlog.d.ts | 1235 ++ docs/api/index.md | 31 + docs/api/rlog.encodingtype.md | 73 + docs/api/rlog.logdata.md | 13 + docs/api/rlog.logenrichercallback.md | 19 + docs/api/rlog.logentry.md | 22 + docs/api/rlog.loglevel.md | 123 + docs/api/rlog.logmetadata.md | 17 + docs/api/rlog.logsinkcallback.md | 19 + docs/api/rlog.md | 237 + docs/api/rlog.partialrlogconfig.md | 17 + docs/api/rlog.rlog._constructor_.md | 49 + docs/api/rlog.rlog._constructor__1.md | 129 + docs/api/rlog.rlog.child.md | 136 + docs/api/rlog.rlog.childwithtag.md | 115 + docs/api/rlog.rlog.clone.md | 21 + docs/api/rlog.rlog.clone_1.md | 57 + docs/api/rlog.rlog.d.md | 69 + docs/api/rlog.rlog.debug.md | 69 + docs/api/rlog.rlog.default.md | 15 + docs/api/rlog.rlog.e.md | 69 + docs/api/rlog.rlog.error.md | 69 + docs/api/rlog.rlog.i.md | 69 + docs/api/rlog.rlog.info.md | 69 + docs/api/rlog.rlog.log.md | 85 + docs/api/rlog.rlog.md | 13 + docs/api/rlog.rlog.parent.md | 15 + docs/api/rlog.rlog.path.md | 36 + docs/api/rlog.rlog.setdefaultconfig.md | 71 + docs/api/rlog.rlog.tag.md | 17 + docs/api/rlog.rlog.v.md | 69 + docs/api/rlog.rlog.verbose.md | 69 + docs/api/rlog.rlog.w.md | 69 + docs/api/rlog.rlog.warn.md | 69 + docs/api/rlog.rlog.warning.md | 69 + docs/api/rlog.rlog.withconfig.md | 79 + docs/api/rlog.rlog.withcorrelationid.md | 70 + docs/api/rlog.rlog.withenricher.md | 100 + docs/api/rlog.rlog.withenrichers.md | 73 + docs/api/rlog.rlog.withminloglevel.md | 77 + docs/api/rlog.rlog.withparent.md | 75 + docs/api/rlog.rlog.withsink.md | 97 + docs/api/rlog.rlog.withsinks.md | 73 + docs/api/rlog.rlog.withtag.md | 74 + docs/api/rlog.rlogconfig.md | 23 + docs/api/rlog.rlogconstructorparameters.md | 22 + docs/api/rlog.serializationconfig.md | 22 + etc/rlog.api.md | 126 + include/Promise.lua | 2068 +++ include/RuntimeLib.lua | 231 + input/rlog.api.json | 2734 +++ input/rlog.api.md | 126 + package-lock.json | 2596 +++ package.json | 63 + src/common/index.ts | 178 + src/configuration/index.ts | 359 + src/context/index.ts | 1 + src/context/log-context-manager.ts | 75 + src/context/log-context.ts | 15 + src/enrichers/file-tag-enricher.ts | 9 + src/enrichers/function-tag-enricher.ts | 9 + src/enrichers/index.ts | 3 + src/enrichers/source-metadata-enricher.ts | 60 + src/index.ts | 13 + src/rlog.ts | 593 + src/serialization/index.ts | 171 + src/services.d.ts | 11 + src/sinks/index.ts | 1 + src/sinks/roblox-console-sink.ts | 60 + src/tests/matchers.ts | 120 + src/tests/rlog.spec.ts | 620 + src/util/index.ts | 7 + test.project.json | 22 + testez-companion.toml | 4 + tsconfig.json | 33 + wiki/.gitignore | 20 + wiki/.prettierrc | 7 + wiki/README.md | 46 + wiki/babel.config.js | 3 + wiki/docs/advanced/_category_.json | 8 + wiki/docs/advanced/google-cloud-logging.mdx | 13 + .../advanced/roblox-console-configuration.mdx | 302 + wiki/docs/advanced/source-metadata.mdx | 194 + wiki/docs/basics/_category_.json | 8 + wiki/docs/basics/default-instance.mdx | 269 + wiki/docs/basics/enrichers.mdx | 304 + wiki/docs/basics/log-context.mdx | 587 + wiki/docs/basics/log-entries.mdx | 145 + wiki/docs/basics/log-levels.mdx | 354 + wiki/docs/basics/serialization.mdx | 395 + wiki/docs/basics/sinks.mdx | 176 + wiki/docs/basics/tags.mdx | 61 + wiki/docs/faq.mdx | 293 + wiki/docs/fast-breakdown.mdx | 604 + wiki/docs/quick-start.mdx | 156 + wiki/docs/sidebars.ts | 45 + wiki/docusaurus.config.ts | 162 + wiki/package-lock.json | 14997 ++++++++++++++++ wiki/package.json | 52 + .../src/components/HomepageFeatures/index.tsx | 70 + .../HomepageFeatures/styles.module.css | 11 + wiki/src/css/custom.css | 104 + wiki/src/pages/index.module.css | 41 + wiki/src/pages/index.tsx | 63 + wiki/src/theme/MDXComponents.tsx | 21 + wiki/src/theme/prism-include-languages.ts | 24 + wiki/src/theme/prism-logs.js | 179 + wiki/static/.nojekyll | 0 wiki/static/img/docusaurus.png | Bin 0 -> 5142 bytes wiki/static/img/favicon.ico | Bin 0 -> 175554 bytes wiki/static/img/log-context-flow-darkmode.svg | 1 + wiki/static/img/log-context-flow.svg | 1 + wiki/static/img/logo.svg | 22 + wiki/static/img/no.png | Bin 0 -> 11148 bytes wiki/static/img/shower-rain.jpg | Bin 0 -> 17536 bytes wiki/static/img/social-card.png | Bin 0 -> 964593 bytes .../static/img/undraw_docusaurus_mountain.svg | 171 + wiki/static/img/undraw_docusaurus_react.svg | 170 + wiki/static/img/undraw_docusaurus_tree.svg | 40 + wiki/static/img/yes.png | Bin 0 -> 12196 bytes wiki/tsconfig.json | 8 + 131 files changed, 35294 insertions(+) create mode 100644 .eslintrc create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .prettierrc create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 LICENSE create mode 100644 README.md create mode 100644 api-extractor.json create mode 100644 default.project.json create mode 100644 dist/rlog.d.ts create mode 100644 docs/api/index.md create mode 100644 docs/api/rlog.encodingtype.md create mode 100644 docs/api/rlog.logdata.md create mode 100644 docs/api/rlog.logenrichercallback.md create mode 100644 docs/api/rlog.logentry.md create mode 100644 docs/api/rlog.loglevel.md create mode 100644 docs/api/rlog.logmetadata.md create mode 100644 docs/api/rlog.logsinkcallback.md create mode 100644 docs/api/rlog.md create mode 100644 docs/api/rlog.partialrlogconfig.md create mode 100644 docs/api/rlog.rlog._constructor_.md create mode 100644 docs/api/rlog.rlog._constructor__1.md create mode 100644 docs/api/rlog.rlog.child.md create mode 100644 docs/api/rlog.rlog.childwithtag.md create mode 100644 docs/api/rlog.rlog.clone.md create mode 100644 docs/api/rlog.rlog.clone_1.md create mode 100644 docs/api/rlog.rlog.d.md create mode 100644 docs/api/rlog.rlog.debug.md create mode 100644 docs/api/rlog.rlog.default.md create mode 100644 docs/api/rlog.rlog.e.md create mode 100644 docs/api/rlog.rlog.error.md create mode 100644 docs/api/rlog.rlog.i.md create mode 100644 docs/api/rlog.rlog.info.md create mode 100644 docs/api/rlog.rlog.log.md create mode 100644 docs/api/rlog.rlog.md create mode 100644 docs/api/rlog.rlog.parent.md create mode 100644 docs/api/rlog.rlog.path.md create mode 100644 docs/api/rlog.rlog.setdefaultconfig.md create mode 100644 docs/api/rlog.rlog.tag.md create mode 100644 docs/api/rlog.rlog.v.md create mode 100644 docs/api/rlog.rlog.verbose.md create mode 100644 docs/api/rlog.rlog.w.md create mode 100644 docs/api/rlog.rlog.warn.md create mode 100644 docs/api/rlog.rlog.warning.md create mode 100644 docs/api/rlog.rlog.withconfig.md create mode 100644 docs/api/rlog.rlog.withcorrelationid.md create mode 100644 docs/api/rlog.rlog.withenricher.md create mode 100644 docs/api/rlog.rlog.withenrichers.md create mode 100644 docs/api/rlog.rlog.withminloglevel.md create mode 100644 docs/api/rlog.rlog.withparent.md create mode 100644 docs/api/rlog.rlog.withsink.md create mode 100644 docs/api/rlog.rlog.withsinks.md create mode 100644 docs/api/rlog.rlog.withtag.md create mode 100644 docs/api/rlog.rlogconfig.md create mode 100644 docs/api/rlog.rlogconstructorparameters.md create mode 100644 docs/api/rlog.serializationconfig.md create mode 100644 etc/rlog.api.md create mode 100644 include/Promise.lua create mode 100644 include/RuntimeLib.lua create mode 100644 input/rlog.api.json create mode 100644 input/rlog.api.md create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/common/index.ts create mode 100644 src/configuration/index.ts create mode 100644 src/context/index.ts create mode 100644 src/context/log-context-manager.ts create mode 100644 src/context/log-context.ts create mode 100644 src/enrichers/file-tag-enricher.ts create mode 100644 src/enrichers/function-tag-enricher.ts create mode 100644 src/enrichers/index.ts create mode 100644 src/enrichers/source-metadata-enricher.ts create mode 100644 src/index.ts create mode 100644 src/rlog.ts create mode 100644 src/serialization/index.ts create mode 100644 src/services.d.ts create mode 100644 src/sinks/index.ts create mode 100644 src/sinks/roblox-console-sink.ts create mode 100644 src/tests/matchers.ts create mode 100644 src/tests/rlog.spec.ts create mode 100644 src/util/index.ts create mode 100644 test.project.json create mode 100644 testez-companion.toml create mode 100644 tsconfig.json create mode 100644 wiki/.gitignore create mode 100644 wiki/.prettierrc create mode 100644 wiki/README.md create mode 100644 wiki/babel.config.js create mode 100644 wiki/docs/advanced/_category_.json create mode 100644 wiki/docs/advanced/google-cloud-logging.mdx create mode 100644 wiki/docs/advanced/roblox-console-configuration.mdx create mode 100644 wiki/docs/advanced/source-metadata.mdx create mode 100644 wiki/docs/basics/_category_.json create mode 100644 wiki/docs/basics/default-instance.mdx create mode 100644 wiki/docs/basics/enrichers.mdx create mode 100644 wiki/docs/basics/log-context.mdx create mode 100644 wiki/docs/basics/log-entries.mdx create mode 100644 wiki/docs/basics/log-levels.mdx create mode 100644 wiki/docs/basics/serialization.mdx create mode 100644 wiki/docs/basics/sinks.mdx create mode 100644 wiki/docs/basics/tags.mdx create mode 100644 wiki/docs/faq.mdx create mode 100644 wiki/docs/fast-breakdown.mdx create mode 100644 wiki/docs/quick-start.mdx create mode 100644 wiki/docs/sidebars.ts create mode 100644 wiki/docusaurus.config.ts create mode 100644 wiki/package-lock.json create mode 100644 wiki/package.json create mode 100644 wiki/src/components/HomepageFeatures/index.tsx create mode 100644 wiki/src/components/HomepageFeatures/styles.module.css create mode 100644 wiki/src/css/custom.css create mode 100644 wiki/src/pages/index.module.css create mode 100644 wiki/src/pages/index.tsx create mode 100644 wiki/src/theme/MDXComponents.tsx create mode 100644 wiki/src/theme/prism-include-languages.ts create mode 100644 wiki/src/theme/prism-logs.js create mode 100644 wiki/static/.nojekyll create mode 100644 wiki/static/img/docusaurus.png create mode 100644 wiki/static/img/favicon.ico create mode 100644 wiki/static/img/log-context-flow-darkmode.svg create mode 100644 wiki/static/img/log-context-flow.svg create mode 100644 wiki/static/img/logo.svg create mode 100644 wiki/static/img/no.png create mode 100644 wiki/static/img/shower-rain.jpg create mode 100644 wiki/static/img/social-card.png create mode 100644 wiki/static/img/undraw_docusaurus_mountain.svg create mode 100644 wiki/static/img/undraw_docusaurus_react.svg create mode 100644 wiki/static/img/undraw_docusaurus_tree.svg create mode 100644 wiki/static/img/yes.png create mode 100644 wiki/tsconfig.json diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..4fc9e40 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,40 @@ +{ + "parser": "@typescript-eslint/parser", + "parserOptions": { + "jsx": true, + "useJSXTextNode": true, + "ecmaVersion": 2018, + "sourceType": "module", + "project": "./tsconfig.json" + }, + "ignorePatterns": ["/out"], + "plugins": ["@typescript-eslint", "roblox-ts", "prettier"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:roblox-ts/recommended", + "plugin:prettier/recommended", + "plugin:react-hooks/recommended" + ], + "rules": { + "prettier/prettier": [ + "warn", + { + "tabWidth": 2, + "endOfLine": "auto", + "useTabs": false, + "trailingComma": "es5", + "plugins": ["prettier-plugin-organize-imports"], + "overrides": [ + { + "files": ["*.jsonc", ".eslintrc", "tsconfig*.json"], + "options": { + "trailingComma": "none" + } + } + ] + } + ] + } + } + \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..5a0d5e4 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca16d80 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/node_modules +/out +*.tsbuildinfo diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..c28aaa6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 120, + "tabWidth": 4, + "trailingComma": "all", + "useTabs": true, + "proseWrap": "always" +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..c544019 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "roblox-ts.vscode-roblox-ts", + "dbaeumer.vscode-eslint" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7bfb809 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,22 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "files.eol": "\n", + "[typescript]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "editor.formatOnSave": true + }, + "[typescriptreact]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "editor.formatOnSave": true + }, + "eslint.run": "onType", + "eslint.format.enable": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "eslint.validate": [ + "typescript", + "typescriptreact" + ], + "testez-companion.timeout": 5 +} \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f49a4e1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a1505a1 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# TODO() + +- Remove deps/eslint/tsconfig settings that aren't needed +- Add copyright headers +- Stretch goal: add isX on all class types for consumers to check if they're instances of our class +- Stretch goal: future project ideas: assertions library and serialization lib + +assertions lib would be built on top of assert. So no test dependencies; could be used in non test code too +maybe some type guard inferring too? idk if that's feasible though \ No newline at end of file diff --git a/api-extractor.json b/api-extractor.json new file mode 100644 index 0000000..2d80009 --- /dev/null +++ b/api-extractor.json @@ -0,0 +1,454 @@ +/** + * Config file for API Extractor. For more info, please visit: https://api-extractor.com + */ +{ + "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", + + /** + * Optionally specifies another JSON config file that this file extends from. This provides a way for + * standard settings to be shared across multiple projects. + * + * If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains + * the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be + * resolved using NodeJS require(). + * + * SUPPORTED TOKENS: none + * DEFAULT VALUE: "" + */ + // "extends": "./shared/api-extractor-base.json" + // "extends": "my-package/include/api-extractor-base.json" + + /** + * Determines the "" token that can be used with other config file settings. The project folder + * typically contains the tsconfig.json and package.json config files, but the path is user-defined. + * + * The path is resolved relative to the folder of the config file that contains the setting. + * + * The default value for "projectFolder" is the token "", which means the folder is determined by traversing + * parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder + * that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error + * will be reported. + * + * SUPPORTED TOKENS: + * DEFAULT VALUE: "" + */ + // "projectFolder": "..", + + /** + * (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor + * analyzes the symbols exported by this module. + * + * The file extension must be ".d.ts" and not ".ts". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + */ + "mainEntryPointFilePath": "/out/index.d.ts", + + /** + * A list of NPM package names whose exports should be treated as part of this package. + * + * For example, suppose that Webpack is used to generate a distributed bundle for the project "library1", + * and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part + * of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly + * imports library2. To avoid this, we might specify: + * + * "bundledPackages": [ "library2" ], + * + * This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been + * local files for library1. + * + * The "bundledPackages" elements may specify glob patterns using minimatch syntax. To ensure deterministic + * output, globs are expanded by matching explicitly declared top-level dependencies only. For example, + * the pattern below will NOT match "@my-company/example" unless it appears in a field such as "dependencies" + * or "devDependencies" of the project's package.json file: + * + * "bundledPackages": [ "@my-company/*" ], + */ + "bundledPackages": [], + + /** + * Specifies what type of newlines API Extractor should use when writing output files. By default, the output files + * will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead. + * To use the OS's default newline kind, specify "os". + * + * DEFAULT VALUE: "crlf" + */ + // "newlineKind": "crlf", + + /** + * Specifies how API Extractor sorts members of an enum when generating the .api.json file. By default, the output + * files will be sorted alphabetically, which is "by-name". To keep the ordering in the source code, specify + * "preserve". + * + * DEFAULT VALUE: "by-name" + */ + // "enumMemberOrder": "by-name", + + /** + * Set to true when invoking API Extractor's test harness. When `testMode` is true, the `toolVersion` field in the + * .api.json file is assigned an empty string to prevent spurious diffs in output files tracked for tests. + * + * DEFAULT VALUE: "false" + */ + // "testMode": false, + + /** + * Determines how the TypeScript compiler engine will be invoked by API Extractor. + */ + "compiler": { + /** + * Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * Note: This setting will be ignored if "overrideTsconfig" is used. + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/tsconfig.json" + */ + // "tsconfigFilePath": "/tsconfig.json", + /** + * Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk. + * The object must conform to the TypeScript tsconfig schema: + * + * http://json.schemastore.org/tsconfig + * + * If omitted, then the tsconfig.json file will be read from the "projectFolder". + * + * DEFAULT VALUE: no overrideTsconfig section + */ + // "overrideTsconfig": { + // . . . + // } + /** + * This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended + * and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when + * dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses + * for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck. + * + * DEFAULT VALUE: false + */ + // "skipLibCheck": true, + }, + + /** + * Configures how the API report file (*.api.md) will be generated. + */ + "apiReport": { + /** + * (REQUIRED) Whether to generate an API report. + */ + "enabled": true + + /** + * The base filename for the API report files, to be combined with "reportFolder" or "reportTempFolder" + * to produce the full file path. The "reportFileName" should not include any path separators such as + * "\" or "/". The "reportFileName" should not include a file extension, since API Extractor will automatically + * append an appropriate file extension such as ".api.md". If the "reportVariants" setting is used, then the + * file extension includes the variant name, for example "my-report.public.api.md" or "my-report.beta.api.md". + * The "complete" variant always uses the simple extension "my-report.api.md". + * + * Previous versions of API Extractor required "reportFileName" to include the ".api.md" extension explicitly; + * for backwards compatibility, that is still accepted but will be discarded before applying the above rules. + * + * SUPPORTED TOKENS: , + * DEFAULT VALUE: "" + */ + // "reportFileName": "", + + /** + * To support different approval requirements for different API levels, multiple "variants" of the API report can + * be generated. The "reportVariants" setting specifies a list of variants to be generated. If omitted, + * by default only the "complete" variant will be generated, which includes all @internal, @alpha, @beta, + * and @public items. Other possible variants are "alpha" (@alpha + @beta + @public), "beta" (@beta + @public), + * and "public" (@public only). + * + * DEFAULT VALUE: [ "complete" ] + */ + // "reportVariants": ["public", "beta"], + + /** + * Specifies the folder where the API report file is written. The file name portion is determined by + * the "reportFileName" setting. + * + * The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy, + * e.g. for an API review. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/etc/" + */ + // "reportFolder": "/etc/", + + /** + * Specifies the folder where the temporary report file is written. The file name portion is determined by + * the "reportFileName" setting. + * + * After the temporary file is written to disk, it is compared with the file in the "reportFolder". + * If they are different, a production build will fail. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/temp/" + */ + // "reportTempFolder": "/temp/", + + /** + * Whether "forgotten exports" should be included in the API report file. Forgotten exports are declarations + * flagged with `ae-forgotten-export` warnings. See https://api-extractor.com/pages/messages/ae-forgotten-export/ to + * learn more. + * + * DEFAULT VALUE: "false" + */ + // "includeForgottenExports": false + }, + + /** + * Configures how the doc model file (*.api.json) will be generated. + */ + "docModel": { + /** + * (REQUIRED) Whether to generate a doc model file. + */ + "enabled": true + + /** + * The output path for the doc model file. The file extension should be ".api.json". + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/temp/.api.json" + */ + // "apiJsonFilePath": "/temp/.api.json", + + /** + * Whether "forgotten exports" should be included in the doc model file. Forgotten exports are declarations + * flagged with `ae-forgotten-export` warnings. See https://api-extractor.com/pages/messages/ae-forgotten-export/ to + * learn more. + * + * DEFAULT VALUE: "false" + */ + // "includeForgottenExports": false, + + /** + * The base URL where the project's source code can be viewed on a website such as GitHub or + * Azure DevOps. This URL path corresponds to the `` path on disk. + * + * This URL is concatenated with the file paths serialized to the doc model to produce URL file paths to individual API items. + * For example, if the `projectFolderUrl` is "https://github.com/microsoft/rushstack/tree/main/apps/api-extractor" and an API + * item's file path is "api/ExtractorConfig.ts", the full URL file path would be + * "https://github.com/microsoft/rushstack/tree/main/apps/api-extractor/api/ExtractorConfig.js". + * + * This setting can be omitted if you don't need source code links in your API documentation reference. + * + * SUPPORTED TOKENS: none + * DEFAULT VALUE: "" + */ + // "projectFolderUrl": "http://github.com/path/to/your/projectFolder" + }, + + /** + * Configures how the .d.ts rollup file will be generated. + */ + "dtsRollup": { + /** + * (REQUIRED) Whether to generate the .d.ts rollup file. + */ + "enabled": true + + /** + * Specifies the output path for a .d.ts rollup file to be generated without any trimming. + * This file will include all declarations that are exported by the main entry point. + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "/dist/.d.ts" + */ + // "untrimmedFilePath": "/dist/.d.ts", + + /** + * Specifies the output path for a .d.ts rollup file to be generated with trimming for an "alpha" release. + * This file will include only declarations that are marked as "@public", "@beta", or "@alpha". + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "alphaTrimmedFilePath": "/dist/-alpha.d.ts", + + /** + * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release. + * This file will include only declarations that are marked as "@public" or "@beta". + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "betaTrimmedFilePath": "/dist/-beta.d.ts", + + /** + * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release. + * This file will include only declarations that are marked as "@public". + * + * If the path is an empty string, then this file will not be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "publicTrimmedFilePath": "/dist/-public.d.ts", + + /** + * When a declaration is trimmed, by default it will be replaced by a code comment such as + * "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the + * declaration completely. + * + * DEFAULT VALUE: false + */ + // "omitTrimmingComments": true + }, + + /** + * Configures how the tsdoc-metadata.json file will be generated. + */ + "tsdocMetadata": { + /** + * Whether to generate the tsdoc-metadata.json file. + * + * DEFAULT VALUE: true + */ + // "enabled": true, + /** + * Specifies where the TSDoc metadata file should be written. + * + * The path is resolved relative to the folder of the config file that contains the setting; to change this, + * prepend a folder token such as "". + * + * The default value is "", which causes the path to be automatically inferred from the "tsdocMetadata", + * "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup + * falls back to "tsdoc-metadata.json" in the package folder. + * + * SUPPORTED TOKENS: , , + * DEFAULT VALUE: "" + */ + // "tsdocMetadataFilePath": "/dist/tsdoc-metadata.json" + }, + + /** + * Configures how API Extractor reports error and warning messages produced during analysis. + * + * There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages. + */ + "messages": { + /** + * Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing + * the input .d.ts files. + * + * TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551" + * + * DEFAULT VALUE: A single "default" entry with logLevel=warning. + */ + "compilerMessageReporting": { + /** + * Configures the default routing for messages that don't match an explicit rule in this table. + */ + "default": { + /** + * Specifies whether the message should be written to the the tool's output log. Note that + * the "addToApiReportFile" property may supersede this option. + * + * Possible values: "error", "warning", "none" + * + * Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail + * and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes + * the "--local" option), the warning is displayed but the build will not fail. + * + * DEFAULT VALUE: "warning" + */ + "logLevel": "warning" + + /** + * When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md), + * then the message will be written inside that file; otherwise, the message is instead logged according to + * the "logLevel" option. + * + * DEFAULT VALUE: false + */ + // "addToApiReportFile": false + } + + // "TS2551": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + }, + + /** + * Configures handling of messages reported by API Extractor during its analysis. + * + * API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag" + * + * DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings + */ + "extractorMessageReporting": { + "default": { + "logLevel": "warning" + // "addToApiReportFile": false + } + + // "ae-extra-release-tag": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + }, + + /** + * Configures handling of messages reported by the TSDoc parser when analyzing code comments. + * + * TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text" + * + * DEFAULT VALUE: A single "default" entry with logLevel=warning. + */ + "tsdocMessageReporting": { + "default": { + "logLevel": "warning" + // "addToApiReportFile": false + } + + // "tsdoc-link-tag-unescaped-text": { + // "logLevel": "warning", + // "addToApiReportFile": true + // }, + // + // . . . + } + } +} diff --git a/default.project.json b/default.project.json new file mode 100644 index 0000000..76e897d --- /dev/null +++ b/default.project.json @@ -0,0 +1,6 @@ +{ + "name": "rlog", + "tree": { + "$path": "out/" + } +} diff --git a/dist/rlog.d.ts b/dist/rlog.d.ts new file mode 100644 index 0000000..c6d7571 --- /dev/null +++ b/dist/rlog.d.ts @@ -0,0 +1,1235 @@ +/** + * Metadata based logging framework for ROBLOX projects. + * + * @remarks + * `rlog` exports the {@link RLog} class as the primary entry point. + * + * @packageDocumentation + */ + +/// + +/** + * Enum representing the types of encoding strategies. + * + * @public + */ +export declare enum EncodingType { + /** + * Deep encoding strategy that processes elements thoroughly. + * + * More specifically, this will ensure all data is properly encoded + * and accounted for; inspecting the individual type of each property + * in a provided object. + * + * @see {@link EncodingType.FAST} + */ + DEEP = 0, + /** + * Fast encoding strategy that focuses on speed. + * + * More specifically, this will just try to encode all data to a + * JSON string or using `tostring` if encoding to a JSON string fails. + * + * So nested types (or roblox datatypes) will not be properly encoded. + * + * Useful if you're not logging any complex data, and want to avoid + * extra runtime overhead. + * + * @see {@link EncodingType.DEEP} + */ + FAST = 1, +} + +/** + * Type representing the additional data associated with a log entry. + * + * @public + */ +export declare type LogData = Record; + +/** + * Type representing a callback function for enriching log entries, or an "enricher". + * + * Enrichers optionally mutate {@link LogEntry}s. You can add data to a {@link LogEntry}, + * edit its {@link LogEntry.metadata | metadata}, or just return it if you don't need to + * do anything. + * + * To learn more about enrichers, and how they work, see {@link RLog.withEnricher | withEnricher}. + * + * @param entry - The log entry to enrich. + * @param config - The configuration used for logging. + * + * @returns The enriched log entry. + * + * @public + */ +export declare type LogEnricherCallback = (entry: LogEntry, config: RLogConfig) => LogEntry; + +/** + * A single logging event. + * + * Each message has its own instance of this, with relevant data + * attached. + * + * @public + */ +export declare type LogEntry = { + /** The log level of the entry. */ + level: LogLevel; + /** The message associated with the log entry. */ + message: string; + /** Additional data associated with the log entry. */ + data: LogData; + /** Metadata associated with the log entry. */ + metadata: LogMetadata; +}; + +/** + * Enum representing the various log levels, or "importance" of a {@link LogEntry}. + * + * @public + */ +export declare enum LogLevel { + /** + * The lowest level of logging. + * + * Verbose messages are those that are not usually useful + * unless you need to see deep step-by-step processes in your + * application. + */ + VERBOSE = 0, + /** + * The second lowest level of logging. + * + * Generally used for messages that you don't necessarily + * need to see at runtime, but they're useful when you need + * to find out why something is happening. + */ + DEBUG = 1, + /** + * The baseline level of logging. + * + * Useful for messages that signify an event or interaction. + * Usually occur only once or twice in a control flow, and are used + * less for debugging, and more for seeing what's going on in your application. + */ + INFO = 2, + /** + * Not as bad as an {@link LogLevel.ERROR | ERROR}, but something that you should be looked at. + * + * Useful for situations where something isn't necessarily breaking, but it's behaving + * in a way that isn't desired. + */ + WARNING = 3, + /** + * The highest level of logging. + * + * Used to indicate issues or exceptions that broke the application, and need to be fixed. + */ + ERROR = 4, +} + +/** + * Metadata associated with a log entry. + * + * @public + */ +export declare type LogMetadata = { + /** The timestamp of the log entry in epoch milliseconds. */ + timestamp: number; + /** Optional correlation ID for tracing logs. */ + correlation_id?: string; + /** Optional tag for categorizing the log entry. */ + tag?: string; +}; + +/** + * Type representing a callback function for consuming log entries, or a "sink". + * + * Sinks optionally consume {@link LogEntry}s. If you return `true`, + * then the log will be stopped, and no further sinks will be called. The {@link LogEntry} will + * also not be logged to the console. + * + * To learn more about sinks, and how they work, see {@link RLog.withSink | withSink}. + * + * @param entry - The log entry to handle. + * @param config - The configuration used for logging. + * + * @returns A boolean indicating whether the log was consumed, or void. + * + * @public + */ +export declare type LogSinkCallback = (entry: LogEntry, config: RLogConfig) => boolean | void; + +/** + * Version of {@link RLogConfig} that allows all data to be absent. + * + * @public + */ +export declare type PartialRLogConfig = Partial> & { + readonly serialization?: Partial; +}; + +/** + * Class for faciliating Roblox Logging. + * + * You can also use {@link rlog} or {@link rLog}- for style purposes. + * + * @public + */ +export declare class RLog { + private config; + private readonly name; + private readonly sourceFile; + private readonly sourceFunction; + private readonly sinks; + private readonly enrichers; + private readonly correlation_id; + /** + * The tag of this {@link RLog} instance. + * + * Tags are used for filtering logs. + * + * See {@link RLog.withTag | withTag} for more details. + */ + readonly tag: string | undefined; + /** + * The parent {@link RLog} of this instance. + * + * See {@link RLog.child | child} for more details on parent and child instances. + */ + readonly parent: RLog | undefined; + /** + * The full path of this {@link RLog}. + * + * A {@link RLog} path is a concatenation of names (tags) of all + * its parent instances, with the root being `DEFAULT`. + * + * In other words, its the hierarchy of the instance. + * + * Instances without a tag are referred to as anonymous instances, and as such + * are labeled as ``. + * + * @example + * ``` + * const main = new RLog().withTag("main"); + * const secondary = main.childWithTag("secondary"); + * const anonymous = secondary.child(); + * + * print(main.path); + * print(secondary.path); + * print(anonymous.path); + * // > DEFAULT.main + * // > DEFAULT.main.secondary + * // > DEFAULT.main.secondary. + * ``` + */ + readonly path: string; + /** + * The default or "global" {@link RLog} instance. + * + * All loggers inherit from this, so it's a convenient way for + * attaching global sinks or enrichers. + */ + static readonly default: RLog; + /** + * Constructs a new {@link RLog} instance. + * + * Uses the provided table in place of the argument names. + */ + constructor({ config, tag, parent, sinks, enrichers, correlation_id }: RLogConstructorParameters); + /** + * Constructs a new {@link RLog} instance. + * + * @param config - Configuration settings to use for this logger instance. + * @param tag - Optional tag for this logger instance. + * @param parent - Optional parent logger instance. + * @param sinks - Optional array of sink callbacks. + * @param enrichers - Optional array of enricher callbacks. + * @param correlation_id - Optional correlation ID. + */ + constructor( + config?: PartialRLogConfig, + tag?: string, + parent?: RLog, + sinks?: LogSinkCallback[], + enrichers?: LogEnricherCallback[], + correlation_id?: string + ); + /** + * Sets the config for the {@link RLog.default | default} instance. + * + * Since all {@link RLog} instances inherit their config from the default instance, + * this is a convenient way to provide default configuration settings. + * + * _Note that this will **not** change the config for instances already created._ + * + * @param config - The {@link RLogConfig} to use. + * + * @example + * ```ts + * RLog.SetDefaultConfig({ { serialization: { encodeFunctions: true } } }); + * + * // Inherits the `encodeFunctions` setting automatically + * const logger = new RLog({ serialization: { encodeRobloxTypes: false } }); + * + * logger.i("Player died", { player: player, location: player.Position, revive: () => {} }); + * // > [INFO]: Player died + * // > { "data": { "player": 1338, "location": "", "revive": "" } } + * ``` + */ + static SetDefaultConfig(config: PartialRLogConfig): void; + /** + * Creates a new {@link RLog} instance with all the same settings and properties. + * + * Everything is deep copied, so any mutations to the original will safely not replicate. + * + * @returns A duplicate of this {@link RLog} instance. + */ + clone(): RLog; + /** + * Creates a new {@link RLog} instance with all the same settings and properties. + * + * The provided {@link RLogConstructorParameters | parameters} will be merged with + * the existing parameters on this instance. + * + * Everything is deep copied, so any mutations to the original will safely not replicate. + * + * @returns A duplicate of this {@link RLog} instance. + */ + clone({ config, tag, parent, sinks, enrichers, correlation_id }: RLogConstructorParameters): RLog; + /** + * Logs a message with a specified log level. + * + * @param level - The log level. + * @param message - The log message. + * @param data - Optional data to log. Will be encoded according to this logger's {@link RLogConfig | config}. + * + * @see {@link RLog.verbose | verbose}, {@link RLog.debug | debug}, {@link RLog.info | info}, {@link RLog.warning | warning}, {@link RLog.error | error} + */ + log(level: LogLevel, message: string, data?: LogData): void; + /** + * Logs a verbose message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.v | v} + */ + verbose(message: string, data?: LogData): void; + /** + * Shorthand version of {@link RLog.verbose | verbose}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + v(message: string, data?: LogData): void; + /** + * Logs a debug message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.d | d} + */ + debug(message: string, data?: LogData): void; + /** + * Shorthand version of {@link RLog.debug | debug}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + d(message: string, data?: LogData): void; + /** + * Logs an informational message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.i | i} + */ + info(message: string, data?: LogData): void; + /** + * Shorthand version of {@link RLog.info | info}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + i(message: string, data?: LogData): void; + /** + * Logs a warning message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.w | w}, {@link RLog.warn | warn} + */ + warning(message: string, data?: LogData): void; + /** + * Shorthand version of {@link RLog.warning | warning}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + warn(message: string, data?: LogData): void; + /** + * Shorthand version of {@link RLog.warning | warning}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + w(message: string, data?: LogData): void; + /** + * Logs an error message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.e | e} + */ + error(message: string, data?: LogData): void; + /** + * Shorthand version of {@link RLog.error | error}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + e(message: string, data?: LogData): void; + /** + * Returns a new {@link RLog} with the config merged with the existing config. + * + * You can use this to toggle certain features on {@link RLog.child | child} instances, or + * conditionally apply certain configurations. + * + * @param config - Configuration settings to apply to the new instance. + * + * @returns The new {@link RLog} instance + * + * @example + * ```ts + * let logger = new RLog({ minLogLevel: LogLevel.DEBUG }); + * + * const data = { position: new Vector2(5, 10) }; + * + * logger.v("Hello verbose!", data); + * logger.d("Hello debug!", data); + * // > [DEBUG]: Hello debug! + * // > { data: { position: { X: 5, Y: 10 } } } + * + * // Inherits the minLogLevel + * logger = logger.withConfig({ serialization: { encodeRobloxTypes: false } }); + + * logger.v("Hello verbose!", data); + * logger.d("Hello debug!", data); + * // > [DEBUG]: Hello debug! + * // > { data: { position: "" } } + * ``` + */ + withConfig(config: PartialRLogConfig): RLog; + /** + * Returns a new {@link RLog} with the parent set to the provided `parent`. + * + * You can use this to switch the parents of {@link RLog.child | child} instances, or whatever + * else you fancy. + * + * @param parent - The new parent to use on the new instance. + * + * @returns The new {@link RLog} instance + * + * @example + * ```ts + * const mainLogger = new RLog(settings, "Main"); + * const secondaryLogger = new RLog(settings, "Secondary"); + * + * print(mainLogger.path); + * print(secondaryLogger.path); + * // > DEFAULT.Main + * // > DEFAULT.Secondary + * + * const newSecondary = secondaryLogger.withParent(mainLogger); + * + * print(newSecondary.path); + * // > DEFAULT.Main.Secondary + * ``` + */ + withParent(parent: RLog | undefined): RLog; + /** + * Returns a new {@link RLog} with the minLogLevel set to `minLogLevel`. + * + * Messages below the minimum level will be ignored. + * + * You can also set this in the {@link RLogConfig | config}, this method is purely + * provided as a means for easier changing. + * + * @param minLevel - The {@link LogLevel} to allow logs for. + * + * @returns The new {@link RLog} instance + * + * @example + * ```ts + * let logger = new RLog(); + * + * logger.v("Hello verbose!"); + * logger.d("Hello debug!"); + * // > [VERBOSE]: Hello verbose! + * // > [DEBUG]: Hello debug! + * + * logger = logger.withMinLogLevel(LogLevel.DEBUG); + + * logger.v("Hello verbose!"); + * logger.d("Hello debug!"); + * // > [DEBUG]: Hello debug! + * ``` + */ + withMinLogLevel(minLevel: LogLevel): RLog; + /** + * Returns a new {@link RLog} with the tag set to `tag`. + * + * Tags are appended to log messages when present, for easier filtering. + * + * Usually, they're used at the class level to keep track of all logs + * facilitated by a single class + * + * @param tag - The new tag to use. + * + * @returns The new {@link RLog} instance. + * + * @example + * ```ts + * let logger = new RLog(); + * + * logger.d("Hello world!"); + * // > [DEBUG]: "Hello world!" + * + * logger = logger.withTag("main"); + * + * logger.d("Hello world!"); + * // > [DEBUG]: main -> "Hello world!" + * ``` + */ + withTag(tag: string): RLog; + /** + * Returns a new {@link RLog} with the correlation_id set to `correlation_id`. + * + * Correlation IDs are appended to log messages when present, for further tracking + * beyond {@link RLog.withTag | tags}. Especially useful when tracking control flows across + * services or files. + * + * To learn more about Correlation IDs, see {@link RLog.child | child}. + * + * @param correlation_id - The new correlation_id to use. + * + * @returns The new {@link RLog} instance. + * + * @example + * ```ts + * const logger = new RLog().withCorrelationId("12345"); + * + * logger.d("Hello world!"); + * // > [DEBUG]: "Hello world!" + * // > { correlation_id: "12345" } + * ``` + */ + withCorrelationId(correlation_id: string): RLog; + /** + * Creates a new {@link RLog} instance with the given `sink` added. + * + * Sinks are callbacks that take in a {@link LogEntry} and return a boolean + * indicating if the entry was "consumed". + * + * If an entry is "consumed", that means it should not be processed any more. + * + * This is especially useful if you want to log your events to an external + * server, but not the local console. + * + * In the case of multiple sinks, they are called in the order they are added. + * + * Furthermore, child sinks are called before {@link RLog.child | parent} sinks. + * + * _Note that the {@link LogEntry} you receive will already be enriched._ + * + * @param sink - The sink callback. + * @param minLevel - The minimum {@link LogLevel} for the sink. The sink will not be + * called for logs that are below this. Defaults to {@link LogLevel.VERBOSE}. + * + * @returns The new {@link RLog} instance. + * + * @example + * ```ts + * function MyCustomSink(entry: LogEntry, config: RLogConfig): boolean { + * // ... log to external server + * return true; // consume the message, meaning don't pass it along + * } + * + * const logger = new RLog().withSink(MyCustomSink); + * + * logger.v("Hello verbose"); // no output to the console, since it was consumed. + * ``` + */ + withSink(sink: LogSinkCallback, minLevel?: LogLevel): RLog; + /** + * Creates a new {@link RLog} instance with all of the given `sinks` added. + * + * Version of {@link RLog.withSink | withSink} that allows you to provide multiple sinks at once. + * + * @param sinks - Array of sink callbacks. + * @param minLevel - The minimum {@link LogLevel} for the sinks. The sinks will not be + * called for logs that are below this. Defaults to {@link LogLevel.VERBOSE}. + * + * @returns The new {@link RLog} instance. + */ + withSinks(sinks: ReadonlyArray, minLevel?: LogLevel): RLog; + /** + * Creates a new {@link RLog} instance with the given `enricher` added. + * + * Enrichers are callbacks that may or may not add data to + * (or mutate directly) a {@link LogEntry}. + * + * In the case of multiple enrichers, they are called in the order they are added. + * + * Furthermore, child enrichers are called before {@link RLog.child | parent} enrichers. + * + * _Note that enrichers are called before sinks._ + * + * @param enricher - The enricher callback. + * @param minLevel - The minimum {@link LogLevel} for the enricher. The enricher will not be + * called for logs that are below this. Defaults to {@link LogLevel.VERBOSE}. + * + * @returns The new {@link RLog} instance. + * + * @example + * ```ts + * function MyCustomEnricher(entry: LogEntry, config: RLogConfig): LogEntry { + * // attach the local player's user id if we're running in a LocalScript + * if(RunService.IsClient()) { + * entry.data["player"] = Players.LocalPlayer.UserId; + * } + * + * // return the modified entry + * return entry; + * } + * + * const logger = new RLog().withEnricher(MyCustomEnricher); + * + * logger.v("Hello verbose"); + * // > [VERBOSE]: Hello Verbose + * // > { "data": { "player": 1333 } } + * ``` + */ + withEnricher(enricher: LogEnricherCallback, minLevel?: LogLevel): RLog; + /** + * Creates a new {@link RLog} instance with all of the given `enrichers` added. + * + * Version of {@link RLog.withEnricher | withEnricher} that allows you to provide multiple enrichers at once. + * + * @param enrichers - Array of enricher callbacks. + * @param minLevel - The minimum {@link LogLevel} for the enrichers. The enrichers will not be + * called for logs that are below this. Defaults to {@link LogLevel.VERBOSE}. + * + * @returns The new {@link RLog} instance. + */ + withEnrichers(enrichers: ReadonlyArray, minLevel?: LogLevel): RLog; + /** + * Creates a child logger with an optional correlation ID. + * + * There are two components at play here: correlation ids, and child loggers. + * + * #### Correlation IDs + * + * Correlation IDs are a way to keep track of logging events that occur + * in a single "flow" or "logical process". For example, you could create a + * child logger for a function: + * + * ```ts + * function buyPet(player: Player, pet: PetId) { + * const logger = rLog.default.child(); + * logger.v("Player is purchasing a pet", { player: player, pet: pet }); + * + * // ... buy pet + * + * logger.d("Player pet bought"); + * } + * + * buyPet(Players.LocalPlayer, "1"); + * // > [VERBOSE]: Player is purchasing a pet + * // > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } + * // > + * // > [DEBUG]: Player pet bought + * // > { "correlation_id": "adss8fd_1318za_112" } + * ``` + * + * Correlation IDs can be used to track the flow of a function call. This is especially useful + * in client to server remote calls, where you want each call to be associated with its own logs. + * + * This also helps in preventing the need to re-log data, as you can filter for the correlation id to + * find the relevant data. + * + * #### Child Loggers + * + * The relationship between a parent and child logger comes with two benefits: + * + * ##### Shared Correlation IDs + * + * The child logger will (by default) inherit the correlation id of the parent. + * + * If you provide your own `correlation_id`, it will override the child's. + * + * If you don't provide one, and the parent doesn't have one, a new will be generated. + * + * Although, this behavior can be disabled with the {@link RLogConfig | autoGenerateCorrelation} setting. + * + * + * ##### Shared Sinks and Enrichers + * + * A child logger has its own sinks and enrichers, meaning you can attach sinks and + * enrichers to only the child logger without affecting the parent. + * + * But after a child logger has called its own enrichers (if any), it will then call + * the parent's. + * + * It will repeat this process with sinks. + * + * ##### Usage + * + * Child loggers are especially useful when tracking the control flow across + * multiple functions: + * + * ``` + * import { PurchaseHandler } from "./purchaseHandler"; + * + * const Logger = new rLog(settings, "Actions"); + * + * function buyPet(player: Player, pet: PetId) { + * const logger = Logger.child(); + * logger.v("Player is purchasing a pet", { player: player, pet: pet }); + * + * PurchaseHandler.processPet(logger, player, pet); + * + * logger.d("Player pet bought"); + * } + * + * buyPet(Players.LocalPlayer, "1"); + * // > [VERBOSE]: Actions -> Player is purchasing a pet + * // > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } + * // > + * // > [VERBOSE]: PurchaseHandler -> Processing a pet purchase + * // > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } + * // > + * // > [DEBUG]: PurchaseHandler -> Pet purchase processed + * // > { "correlation_id": "adss8fd_1318za_112" } + * // > + * // > [DEBUG]: Actions -> Player pet bought + * // > { "correlation_id": "adss8fd_1318za_112" } + * ``` + * + * @param correlation_id - Optional Correlation ID for tracking. + * Defaults to the current `correlation_id`, if any. + * + * @returns The new {@link RLog} instance. + * + * @see {@link RLog.childWithTag | childWithTag} + */ + child(correlation_id?: string | undefined): RLog; + /** + * Creates a child logger with a specific tag and optional correlation ID. + * + * Alternative version of {@link RLog.child | child} that allows you to specify a unique `tag` for + * the child instance. + * + * _Note that child loggers do not inherit their parent's tag unless you call this method._ + * + * @param tag - The tag for the child logger. Defaults to the calling instance's `tag`, if any. + * @param correlation_id - Optional correlation ID. Defaults to the calling instance's `correlation_id`, if any. + * + * @returns The new {@link RLog} instance. + * + * @example + * ```ts + * const Logger = new rLog(settings); + * + * function processPurchase(parent: RLog, player: Player, pet: PetId) { + * const logger = parent.childWithTag("processPurchase") + * + * logger.v("Processing a pet purchase", { player: player, pet: pet }); + * + * // ... + * + * logger.d("Pet purchase processed") + * } + * + * function buyPet(parent: RLog, player: Player, pet: PetId) { + * const logger = parent.childWithTag("buyPet"); + * + * logger.v("Player is purchasing a pet", { player: player, pet: pet }); + * + * processPurchase(logger, player, pet); + * + * logger.d("Player pet bought"); + * } + * + * buyPet(Logger, Players.LocalPlayer, "1"); + * // > [VERBOSE]: buyPet -> Player is purchasing a pet + * // > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } + * // > + * // > [VERBOSE]: processPurchase -> Processing a pet purchase + * // > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } + * // > + * // > [DEBUG]: processPurchase -> Pet purchase processed + * // > { "correlation_id": "adss8fd_1318za_112" } + * // > + * // > [DEBUG]: buyPet -> Player pet bought + * // > { "correlation_id": "adss8fd_1318za_112" } + * ``` + */ + childWithTag(tag?: string | undefined, correlation_id?: string | undefined): RLog; + /** + * Constructs the full path of this `instance`. + * + * @param instance - The lowest level child to search upwards from. + * @returns The full path of the provided instance. + * + * @see {@link RLog.path | path} + * + + * @internal + */ + private static ComputePath; + /** + * Finds the nearest script that is not us that called this function. + * + * @returns The script path and the function name (if any). + * + * @see {@link RLogConfig.functionTags | functionTags}, {@link RLogConfig.fileTags | fileTags} + * + + * + * @internal + */ + private static FindCaller; + /** + * @returns A table of the parameters of this instance as a {@link RLogConstructorParameters}. + * + * @internal + */ + private extractConstructor; + /** + * Handles logging to all registered sinks. + * + * In a separate function so children can call parent sinks. + * + * @param entry - The log entry to sink. + * @returns True if the log entry was handled ("consumed") by a sink, otherwise false. + * + * @internal + */ + private sink; + /** + * Enriches a log entry using all registered enrichers. + * + * In a separate function so children can call parent enrichers. + * + * @param entry - The log entry to enrich. + * @returns The enriched log entry. + * + * @internal + */ + private enrich; + /** + * Constructs the log message string based on the log entry. + * + * @param entry - The log entry to format. + * @returns The formatted log message string. + * + * @internal + */ + private constructLogMessage; + /** + * Generates a new correlation ID if auto-generation is enabled. + * + * @returns The generated correlation ID, or undefined if auto-generation is disabled. + * + * @internal + */ + private generateCorrelationId; +} + +/** + * Mapping to {@link RLog} + * + * @public + */ +export declare const rLog: typeof RLog; + +/** + * Mapping to {@link RLog} + * + * @public + */ +export declare const rlog: typeof RLog; + +/** + * Configuration settings for {@link RLog}. + * + * @public + */ +export declare type RLogConfig = { + /** + * Sets the minimum {@link LogLevel} for data to be logged. + * + * Messages below the minimum level will be ignored. + * + * @example + * ```ts + * let logger = new RLog(); + * + * logger.v("Hello verbose!"); + * logger.d("Hello debug!"); + * // > [VERBOSE]: Hello verbose! + * // > [DEBUG]: Hello debug! + * + * logger = logger.withMinLogLevel(LogLevel.DEBUG); + + * logger.v("Hello verbose!"); + * logger.d("Hello debug!"); + * // > [DEBUG]: Hello debug! + * ``` + */ + readonly minLogLevel: LogLevel; + /** + * Use function names for tags when not present. + * + * With this setting on, when you create a logger without providing a tag, + * the name of the function it was called from will be used instead. + * + * When used alongside {@link RLogConfig.fileTags | fileTags}, a file name will only be used + * if there isn't a valid function name; which can occur in anonymous functions. + * + * @defaultValue `false` + * + * @example + * ```ts + * function GivePlayerMoney() { + * const logger = new RLog({ functionTags: true }); + * logger.i("Money given to player"); + * } + * + * GivePlayerMoney(); + * // > [DEBUG] GivePlayerMoney -> Money given to player + * ``` + */ + readonly functionTags: boolean; + /** + * Use file names for tags when not present. + * + * With this setting on, when you create a logger without providing a tag, + * the name of the file will be used instead. + * + * When used alongside {@link RLogConfig.functionTags | functionTags}, a file name will only be used + * if there isn't a valid function name; which can occur in anonymous functions. + * + * @defaultValue `false` + * + * @example + * ```ts + * // in file ServerScriptStorage/TS/main + * const logger = new RLog({ fileTags: true }); + * + * logger.i("Hello world!"); + * // > [DEBUG] ServerScriptStorage.TS.main -> Hello world! + * ``` + */ + readonly fileTags: boolean; + /** Settings to use when encoding {@link LogEntry.data | data} in logs. */ + readonly serialization: SerializationConfig; + /** + * Whether to automatically generate Correlation IDs for {@link LogMetadata | metadata}. + * + * By itself, disabling this doesn't do anything; as + * {@link RLogConfig.autoGenerateCorrelation | autoGenerateCorrelation} will override it. + * + * For more information on how Correlation IDs work, see {@link RLog.child}. + * + * @defaultValue `true` + * + * @see {@link RLogConfig.correlationGenerator | correlationGenerator} + * + * @example + * ```ts + * const logger = new RLog({ autoGenerateCorrelation: false, autoGenerateChildCorrelation: true }); + * + * const child = logger.child(); + * child.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "correlation_id": "1322412_dsra_daeqwf_daa", "data": { "player": 1338 } } + * ``` + */ + readonly autoGenerateChildCorrelation: boolean; + /** + * Whether to automatically generate Correlation IDs for {@link LogMetadata | metadata}. + * + * When disabled, Correlation IDs will not be generated for new {@link RLog} + * instances. + * + * When enabled, every new {@link RLog} instance will have its own Correlation ID generated + * (unless you manually provide one). + * + * Disabling this may be desireable if you only want to have Correlation IDs for child instances + * that you create in control flows. + * + * Alternatively, if you only want Correlation IDs to be present when you manually provide them, + * you will need to also disable {@link RLogConfig.autoGenerateChildCorrelation | autoGenerateChildCorrelation}. + * + * @defaultValue `true` + * + * @see {@link RLogConfig.correlationGenerator | correlationGenerator} + * + * @example + * ```ts + * const logger = new RLog({ autoGenerateCorrelation: true }); + * + * logger.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "correlation_id": "1322412_dsra_daeqwf_daa", "data": { "player": 1338 } } + * ``` + */ + readonly autoGenerateCorrelation: boolean; + /** + * Optional function to generate correlation IDs. + * + * By default, Correlation IDs are generated via a combination of + * {@link https://create.roblox.com/docs/en-us/reference/engine/classes/HttpService#GenerateGUID | HttpService.GenerateGUID } + * and the current time- to avoid conflicts. + * + * If you specify your own function, it will be called anytime a + * new Correlation ID is requested. + * + * Especially useful if you want to create Correlation IDs to match + * ids in your external database. + * + * @example + * ```ts + * function generateCorrelationID(): string { + * return "1"; + * } + * + * const logger = new RLog({ correlationGenerator: generateCorrelationID }); + * + * const child = logger.child(); + * child.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "correlation_id": "1", "data": { "player": 1338 } } + * ``` + */ + readonly correlationGenerator?: () => string; +}; + +/** + * Table version of the constructor parameters for {@link RLog}. + * + * @public + */ +export declare type RLogConstructorParameters = { + config?: PartialRLogConfig; + tag?: string; + parent?: RLog; + sinks?: LogSinkCallback[]; + enrichers?: LogEnricherCallback[]; + correlation_id?: string; +}; + +/** + * Configuration settings for serialization. + * + * @see {@link RLogConfig} + * + * @public + */ +export declare type SerializationConfig = { + /** + * The minimum {@link LogLevel} for serialization to occur. + * + * If a {@link LogEntry} has a level lower than this, then its + * data will be discarded. + * + * Useful for when you don't want to log data in production for + * {@link RLog.info | info} calls, but you do want to log data for {@link RLog.error | error} calls. + * + * @defaultValue {@link LogLevel.VERBOSE} + * + * @example + * ``` + * const logger = new RLog({ serialization: { minLogLevel: LogLevel.WARNING } }); + * + * logger.i("Player died", { player: player, location: player.Position }); + * logger.e("Player error", { player: player }); + * // > [INFO]: Player died + * // > + * // > [ERROR]: Player left + * // > { "data": { "player": 1338 } } + * ``` + */ + readonly minLogLevel: LogLevel; + /** + * Whether to encode Roblox-specific types. + * + * When this setting is disabled, all roblox-specific types will + * instead just be represented as `""`. + * + * @defaultValue `true` + * + * @example + * ```ts + * logger.i("Player died", { player: player, location: player.Position }); + * // > [INFO]: Player died + * // > { "data": { "player": 1338, "location": "" } } + * ``` + */ + readonly encodeRobloxTypes: boolean; + /** + * Whether to encode Roblox-specific types. + * + * When this setting is disabled, all function types will + * be represented as `""`. Otherwise, they'll be excluded + * from the outputted JSON. + * + * @defaultValue `false` + * + * @example + * ```ts + * class PlayerClass { + * constructor(public name: string) {}; + * public eatFood() { + * // ... + * } + * } + * + * const player = new PlayerClass("daymon"); + * + * let logger = new RLog({ serialization: { encodeFunctions: true } }); + * + * logger.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "data": { "player": { "name": "daymon", "eatFood": "" } } } + * + * logger = new RLog({ serialization: { encodeFunctions: false } }); + * + * logger.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "data": { "player": { "name": "daymon" } } } + * ``` + */ + readonly encodeFunctions: boolean; + /** + * Whether to perform deep encoding on tables. + * + * When disabled, tables will not be recursively encoded. Which may cause you + * to miss out on certain data types being properly translated (eg; roblox data types). + * + * This will occur even if you have {@link SerializationConfig.encodeRobloxTypes | encodeRobloxTypes} + * enabled. + * + * But if you have deeply nested data types, or are wanting to save on performance, + * this may be desirable. + * + * @defaultValue `true` + * + * @example + * ``` + * const event = { + * source: { + * position: new Vector2(1, 1), + * distance: 100 + * }, + * target: new Vector2(2, 2), + * }; + * + * let logger = new RLog({ serialization: { deepEncodeTables: true } }); + * logger.i("Gun was fired", event); + * // > [INFO]: Gun was fired + * // > { "data": { "source": { "position": { "X": 1, "Y": 1}, "distance": 100 }, "target": { "X": 2, "Y": 2} } } + * + * logger = new RLog({ serialization: { deepEncodeTables: false } }); + * logger.i("Gun was fired", event); + * // > [INFO]: Gun was fired + * // > { "data": { "source": { "position": null, "distance": 100 }, "target": { "X": 2, "Y": 2} } } + * ``` + */ + readonly deepEncodeTables: boolean; + /** + * The encoding strategy to use. + * + * The encoding strategy specifies how data is encoded. + * + * To learn the specifics about each type, see {@link EncodingType}. + * + * Having an `encodeType` of {@link EncodingType.FAST | FAST} functions very similiarly to + * having {@link SerializationConfig.deepEncodeTables | deepEncodeTables} disabled. The difference + * is that with {@link EncodingType.DEEP | DEEP}, even with {@link SerializationConfig.deepEncodeTables | deepEncodeTables} + * disabled, it will still try to call {@link SerializationConfig.encodeMethod | encodeMethod} or `tostring`. + * before giving up. + * + * You also won't get roblox data types encoded at the first level with {@link EncodingType.FAST | FAST}. + * + * @defaultValue {@link EncodingType.DEEP | DEEP} + * + * @example + * ``` + * const event = { + * source: { + * position: new Vector2(1, 1), + * distance: 100 + * }, + * target: new Vector2(2, 2), + * }; + * + * let logger = new RLog({ serialization: { encodeType: EncodingType.DEEP } }); + * logger.i("Gun was fired", event); + * // > [INFO]: Gun was fired + * // > { "data": { "source": { "position": { "X": 1, "Y": 1}, "distance": 100 }, "target": { "X": 2, "Y": 2} } } + * + * logger = new RLog({ serialization: { encodeType: EncodingType.FAST } }); + * logger.i("Gun was fired", event); + * // > [INFO]: Gun was fired + * // > { "data": { "source": { "position": null, "distance": 100 }, "target": null } } + * ``` + */ + readonly encodeType: EncodingType; + /** + * The method name to use for custom serialization. + * + * When encoding an object, the encoder will first check if the object has + * a method with this name. If it does, it will call that method instead of + * trying to manually encode it. + * + * @defaultValue `__tostring` + * + * @example + * ```ts + * class PlayerClass { + * constructor(public name: string) {}; + * + * public encode() { + * return { name: this.name }; + * } + * } + * + * const player = new PlayerClass("daymon"); + * + * let logger = new RLog(); + * + * logger.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "data": { "player": "PlayerClass" } } + * + * logger = new RLog({ serialization: { encodeMethod: "encode" } }); + * + * logger.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "data": { "player": { "name": "daymon" } } } + * ``` + */ + readonly encodeMethod: string; +}; + +export {}; diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 0000000..e3c47a1 --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,31 @@ + + +[Home](./index.md) + +## API Reference + +## Packages + + + +
+ +Package + + + + +Description + + +
+ +[@rbxts/rlog](./rlog.md) + + + + +Metadata based logging framework for ROBLOX projects. + + +
diff --git a/docs/api/rlog.encodingtype.md b/docs/api/rlog.encodingtype.md new file mode 100644 index 0000000..9adf8ca --- /dev/null +++ b/docs/api/rlog.encodingtype.md @@ -0,0 +1,73 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [EncodingType](./rlog.encodingtype.md) + +## EncodingType enum + +Enum representing the types of encoding strategies. + +**Signature:** + +```typescript +export declare enum EncodingType +``` + +## Enumeration Members + + + + +
+ +Member + + + + +Value + + + + +Description + + +
+ +DEEP + + + + +`0` + + + + +Deep encoding strategy that processes elements thoroughly. + +More specifically, this will ensure all data is properly encoded and accounted for; inspecting the individual type of each property in a provided object. + + +
+ +FAST + + + + +`1` + + + + +Fast encoding strategy that focuses on speed. + +More specifically, this will just try to encode all data to a JSON string or using `tostring` if encoding to a JSON string fails. + +So nested types (or roblox datatypes) will not be properly encoded. + +Useful if you're not logging any complex data, and want to avoid extra runtime overhead. + + +
diff --git a/docs/api/rlog.logdata.md b/docs/api/rlog.logdata.md new file mode 100644 index 0000000..41b574a --- /dev/null +++ b/docs/api/rlog.logdata.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [LogData](./rlog.logdata.md) + +## LogData type + +Type representing the additional data associated with a log entry. + +**Signature:** + +```typescript +export type LogData = Record; +``` diff --git a/docs/api/rlog.logenrichercallback.md b/docs/api/rlog.logenrichercallback.md new file mode 100644 index 0000000..46764e7 --- /dev/null +++ b/docs/api/rlog.logenrichercallback.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [LogEnricherCallback](./rlog.logenrichercallback.md) + +## LogEnricherCallback type + +Type representing a callback function for enriching log entries, or an "enricher". + +Enrichers optionally mutate [LogEntry](./rlog.logentry.md)s. You can add data to a [LogEntry](./rlog.logentry.md), edit its , or just return it if you don't need to do anything. + +To learn more about enrichers, and how they work, see [withEnricher](./rlog.rlog.withenricher.md). + +**Signature:** + +```typescript +export type LogEnricherCallback = (entry: LogEntry, config: RLogConfig) => LogEntry; +``` +**References:** [LogEntry](./rlog.logentry.md), [RLogConfig](./rlog.rlogconfig.md) + diff --git a/docs/api/rlog.logentry.md b/docs/api/rlog.logentry.md new file mode 100644 index 0000000..bc74bf1 --- /dev/null +++ b/docs/api/rlog.logentry.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [LogEntry](./rlog.logentry.md) + +## LogEntry type + +A single logging event. + +Each message has its own instance of this, with relevant data attached. + +**Signature:** + +```typescript +export type LogEntry = { + level: LogLevel; + message: string; + data: LogData; + metadata: LogMetadata; +}; +``` +**References:** [LogLevel](./rlog.loglevel.md), [LogData](./rlog.logdata.md), [LogMetadata](./rlog.logmetadata.md) + diff --git a/docs/api/rlog.loglevel.md b/docs/api/rlog.loglevel.md new file mode 100644 index 0000000..109661e --- /dev/null +++ b/docs/api/rlog.loglevel.md @@ -0,0 +1,123 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [LogLevel](./rlog.loglevel.md) + +## LogLevel enum + +Enum representing the various log levels, or "importance" of a [LogEntry](./rlog.logentry.md). + +**Signature:** + +```typescript +export declare enum LogLevel +``` + +## Enumeration Members + + + + + + + +
+ +Member + + + + +Value + + + + +Description + + +
+ +DEBUG + + + + +`1` + + + + +The second lowest level of logging. + +Generally used for messages that you don't necessarily need to see at runtime, but they're useful when you need to find out why something is happening. + + +
+ +ERROR + + + + +`4` + + + + +The highest level of logging. + +Used to indicate issues or exceptions that broke the application, and need to be fixed. + + +
+ +INFO + + + + +`2` + + + + +The baseline level of logging. + +Useful for messages that signify an event or interaction. Usually occur only once or twice in a control flow, and are used less for debugging, and more for seeing what's going on in your application. + + +
+ +VERBOSE + + + + +`0` + + + + +The lowest level of logging. + +Verbose messages are those that are not usually useful unless you need to see deep step-by-step processes in your application. + + +
+ +WARNING + + + + +`3` + + + + +Not as bad as an [ERROR](./rlog.loglevel.md), but something that you should be looked at. + +Useful for situations where something isn't necessarily breaking, but it's behaving in a way that isn't desired. + + +
diff --git a/docs/api/rlog.logmetadata.md b/docs/api/rlog.logmetadata.md new file mode 100644 index 0000000..346101d --- /dev/null +++ b/docs/api/rlog.logmetadata.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [LogMetadata](./rlog.logmetadata.md) + +## LogMetadata type + +Metadata associated with a log entry. + +**Signature:** + +```typescript +export type LogMetadata = { + timestamp: number; + correlation_id?: string; + tag?: string; +}; +``` diff --git a/docs/api/rlog.logsinkcallback.md b/docs/api/rlog.logsinkcallback.md new file mode 100644 index 0000000..b280d9b --- /dev/null +++ b/docs/api/rlog.logsinkcallback.md @@ -0,0 +1,19 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [LogSinkCallback](./rlog.logsinkcallback.md) + +## LogSinkCallback type + +Type representing a callback function for consuming log entries, or a "sink". + +Sinks optionally consume [LogEntry](./rlog.logentry.md)s. If you return `true`, then the log will be stopped, and no further sinks will be called. The [LogEntry](./rlog.logentry.md) will also not be logged to the console. + +To learn more about sinks, and how they work, see [withSink](./rlog.rlog.withsink.md). + +**Signature:** + +```typescript +export type LogSinkCallback = (entry: LogEntry, config: RLogConfig) => boolean | void; +``` +**References:** [LogEntry](./rlog.logentry.md), [RLogConfig](./rlog.rlogconfig.md) + diff --git a/docs/api/rlog.md b/docs/api/rlog.md new file mode 100644 index 0000000..520ed08 --- /dev/null +++ b/docs/api/rlog.md @@ -0,0 +1,237 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) + +## rlog package + +Metadata based logging framework for ROBLOX projects. + +## Remarks + +`rlog` exports the [RLog](./rlog.rlog.md) class as the primary entry point. + +## Classes + + + +
+ +Class + + + + +Description + + +
+ +[RLog](./rlog.rlog.md) + + + + +Class for faciliating Roblox Logging. + +You can also use [rlog](./rlog.rlog.md) or [rLog](./rlog.rlog.md)- for style purposes. + + +
+ +## Enumerations + + + + +
+ +Enumeration + + + + +Description + + +
+ +[EncodingType](./rlog.encodingtype.md) + + + + +Enum representing the types of encoding strategies. + + +
+ +[LogLevel](./rlog.loglevel.md) + + + + +Enum representing the various log levels, or "importance" of a [LogEntry](./rlog.logentry.md). + + +
+ +## Variables + + + + +
+ +Variable + + + + +Description + + +
+ +[rlog](./rlog.rlog.md) + + + + +Mapping to [RLog](./rlog.rlog.md) + + +
+ +[rLog](./rlog.rlog.md) + + + + +Mapping to [RLog](./rlog.rlog.md) + + +
+ +## Type Aliases + + + + + + + + + + + +
+ +Type Alias + + + + +Description + + +
+ +[LogData](./rlog.logdata.md) + + + + +Type representing the additional data associated with a log entry. + + +
+ +[LogEnricherCallback](./rlog.logenrichercallback.md) + + + + +Type representing a callback function for enriching log entries, or an "enricher". + +Enrichers optionally mutate [LogEntry](./rlog.logentry.md)s. You can add data to a [LogEntry](./rlog.logentry.md), edit its , or just return it if you don't need to do anything. + +To learn more about enrichers, and how they work, see [withEnricher](./rlog.rlog.withenricher.md). + + +
+ +[LogEntry](./rlog.logentry.md) + + + + +A single logging event. + +Each message has its own instance of this, with relevant data attached. + + +
+ +[LogMetadata](./rlog.logmetadata.md) + + + + +Metadata associated with a log entry. + + +
+ +[LogSinkCallback](./rlog.logsinkcallback.md) + + + + +Type representing a callback function for consuming log entries, or a "sink". + +Sinks optionally consume [LogEntry](./rlog.logentry.md)s. If you return `true`, then the log will be stopped, and no further sinks will be called. The [LogEntry](./rlog.logentry.md) will also not be logged to the console. + +To learn more about sinks, and how they work, see [withSink](./rlog.rlog.withsink.md). + + +
+ +[PartialRLogConfig](./rlog.partialrlogconfig.md) + + + + +Version of [RLogConfig](./rlog.rlogconfig.md) that allows all data to be absent. + + +
+ +[RLogConfig](./rlog.rlogconfig.md) + + + + +Configuration settings for [RLog](./rlog.rlog.md). + + +
+ +[RLogConstructorParameters](./rlog.rlogconstructorparameters.md) + + + + +Table version of the constructor parameters for [RLog](./rlog.rlog.md). + + +
+ +[SerializationConfig](./rlog.serializationconfig.md) + + + + +Configuration settings for serialization. + + +
diff --git a/docs/api/rlog.partialrlogconfig.md b/docs/api/rlog.partialrlogconfig.md new file mode 100644 index 0000000..23970e4 --- /dev/null +++ b/docs/api/rlog.partialrlogconfig.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [PartialRLogConfig](./rlog.partialrlogconfig.md) + +## PartialRLogConfig type + +Version of [RLogConfig](./rlog.rlogconfig.md) that allows all data to be absent. + +**Signature:** + +```typescript +export type PartialRLogConfig = Partial> & { + readonly serialization?: Partial; +}; +``` +**References:** [RLogConfig](./rlog.rlogconfig.md), [SerializationConfig](./rlog.serializationconfig.md) + diff --git a/docs/api/rlog.rlog._constructor_.md b/docs/api/rlog.rlog._constructor_.md new file mode 100644 index 0000000..28876f1 --- /dev/null +++ b/docs/api/rlog.rlog._constructor_.md @@ -0,0 +1,49 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [(constructor)](./rlog.rlog._constructor_.md) + +## RLog.(constructor) + +Constructs a new [RLog](./rlog.rlog.md) instance. + +Uses the provided table in place of the argument names. + +**Signature:** + +```typescript +constructor({ config, tag, parent, sinks, enrichers, correlation_id }: RLogConstructorParameters); +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +{ config, tag, parent, sinks, enrichers, correlation\_id } + + + + +[RLogConstructorParameters](./rlog.rlogconstructorparameters.md) + + + + + +
diff --git a/docs/api/rlog.rlog._constructor__1.md b/docs/api/rlog.rlog._constructor__1.md new file mode 100644 index 0000000..b8136f2 --- /dev/null +++ b/docs/api/rlog.rlog._constructor__1.md @@ -0,0 +1,129 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [(constructor)](./rlog.rlog._constructor__1.md) + +## RLog.(constructor) + +Constructs a new [RLog](./rlog.rlog.md) instance. + +**Signature:** + +```typescript +constructor(config?: PartialRLogConfig, tag?: string, parent?: RLog, sinks?: LogSinkCallback[], enrichers?: LogEnricherCallback[], correlation_id?: string); +``` + +## Parameters + + + + + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +config + + + + +[PartialRLogConfig](./rlog.partialrlogconfig.md) + + + + +_(Optional)_ Configuration settings to use for this logger instance. + + +
+ +tag + + + + +string + + + + +_(Optional)_ Optional tag for this logger instance. + + +
+ +parent + + + + +[RLog](./rlog.rlog.md) + + + + +_(Optional)_ Optional parent logger instance. + + +
+ +sinks + + + + +[LogSinkCallback](./rlog.logsinkcallback.md)\[\] + + + + +_(Optional)_ Optional array of sink callbacks. + + +
+ +enrichers + + + + +[LogEnricherCallback](./rlog.logenrichercallback.md)\[\] + + + + +_(Optional)_ Optional array of enricher callbacks. + + +
+ +correlation\_id + + + + +string + + + + +_(Optional)_ Optional correlation ID. + + +
diff --git a/docs/api/rlog.rlog.child.md b/docs/api/rlog.rlog.child.md new file mode 100644 index 0000000..438e8f7 --- /dev/null +++ b/docs/api/rlog.rlog.child.md @@ -0,0 +1,136 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [child](./rlog.rlog.child.md) + +## RLog.child() method + +Creates a child logger with an optional correlation ID. + +There are two components at play here: correlation ids, and child loggers. + +\#\#\#\# Correlation IDs + +Correlation IDs are a way to keep track of logging events that occur in a single "flow" or "logical process". For example, you could create a child logger for a function: + +```ts +function buyPet(player: Player, pet: PetId) { + const logger = rLog.default.child(); + logger.v("Player is purchasing a pet", { player: player, pet: pet }); + + // ... buy pet + + logger.d("Player pet bought"); +} + +buyPet(Players.LocalPlayer, "1"); +// > [VERBOSE]: Player is purchasing a pet +// > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } +// > +// > [DEBUG]: Player pet bought +// > { "correlation_id": "adss8fd_1318za_112" } +``` +Correlation IDs can be used to track the flow of a function call. This is especially useful in client to server remote calls, where you want each call to be associated with its own logs. + +This also helps in preventing the need to re-log data, as you can filter for the correlation id to find the relevant data. + +\#\#\#\# Child Loggers + +The relationship between a parent and child logger comes with two benefits: + +\#\#\#\#\# Shared Correlation IDs + +The child logger will (by default) inherit the correlation id of the parent. + +If you provide your own `correlation_id`, it will override the child's. + +If you don't provide one, and the parent doesn't have one, a new will be generated. + +Although, this behavior can be disabled with the [autoGenerateCorrelation](./rlog.rlogconfig.md) setting. + +\#\#\#\#\# Shared Sinks and Enrichers + +A child logger has its own sinks and enrichers, meaning you can attach sinks and enrichers to only the child logger without affecting the parent. + +But after a child logger has called its own enrichers (if any), it will then call the parent's. + +It will repeat this process with sinks. + +\#\#\#\#\# Usage + +Child loggers are especially useful when tracking the control flow across multiple functions: + +``` +import { PurchaseHandler } from "./purchaseHandler"; + +const Logger = new rLog(settings, "Actions"); + +function buyPet(player: Player, pet: PetId) { + const logger = Logger.child(); + logger.v("Player is purchasing a pet", { player: player, pet: pet }); + + PurchaseHandler.processPet(logger, player, pet); + + logger.d("Player pet bought"); +} + +buyPet(Players.LocalPlayer, "1"); +// > [VERBOSE]: Actions -> Player is purchasing a pet +// > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } +// > +// > [VERBOSE]: PurchaseHandler -> Processing a pet purchase +// > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } +// > +// > [DEBUG]: PurchaseHandler -> Pet purchase processed +// > { "correlation_id": "adss8fd_1318za_112" } +// > +// > [DEBUG]: Actions -> Player pet bought +// > { "correlation_id": "adss8fd_1318za_112" } +``` + +**Signature:** + +```typescript +child(correlation_id?: string | undefined): RLog; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +correlation\_id + + + + +string \| undefined + + + + +_(Optional)_ Optional Correlation ID for tracking. Defaults to the current `correlation_id`, if any. + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance. + diff --git a/docs/api/rlog.rlog.childwithtag.md b/docs/api/rlog.rlog.childwithtag.md new file mode 100644 index 0000000..b3a4097 --- /dev/null +++ b/docs/api/rlog.rlog.childwithtag.md @@ -0,0 +1,115 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [childWithTag](./rlog.rlog.childwithtag.md) + +## RLog.childWithTag() method + +Creates a child logger with a specific tag and optional correlation ID. + +Alternative version of [child](./rlog.rlog.child.md) that allows you to specify a unique `tag` for the child instance. + +\_Note that child loggers do not inherit their parent's tag unless you call this method.\_ + +**Signature:** + +```typescript +childWithTag(tag?: string | undefined, correlation_id?: string | undefined): RLog; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +tag + + + + +string \| undefined + + + + +_(Optional)_ The tag for the child logger. Defaults to the calling instance's `tag`, if any. + + +
+ +correlation\_id + + + + +string \| undefined + + + + +_(Optional)_ Optional correlation ID. Defaults to the calling instance's `correlation_id`, if any. + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance. + +## Example + + +```ts +const Logger = new rLog(settings); + +function processPurchase(parent: RLog, player: Player, pet: PetId) { + const logger = parent.childWithTag("processPurchase") + + logger.v("Processing a pet purchase", { player: player, pet: pet }); + + // ... + + logger.d("Pet purchase processed") +} + +function buyPet(parent: RLog, player: Player, pet: PetId) { + const logger = parent.childWithTag("buyPet"); + + logger.v("Player is purchasing a pet", { player: player, pet: pet }); + + processPurchase(logger, player, pet); + + logger.d("Player pet bought"); +} + +buyPet(Logger, Players.LocalPlayer, "1"); +// > [VERBOSE]: buyPet -> Player is purchasing a pet +// > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } +// > +// > [VERBOSE]: processPurchase -> Processing a pet purchase +// > { "correlation_id": "adss8fd_1318za_112", "data": { "player": 1333, "pet": "1" } } +// > +// > [DEBUG]: processPurchase -> Pet purchase processed +// > { "correlation_id": "adss8fd_1318za_112" } +// > +// > [DEBUG]: buyPet -> Player pet bought +// > { "correlation_id": "adss8fd_1318za_112" } +``` + diff --git a/docs/api/rlog.rlog.clone.md b/docs/api/rlog.rlog.clone.md new file mode 100644 index 0000000..fa3a557 --- /dev/null +++ b/docs/api/rlog.rlog.clone.md @@ -0,0 +1,21 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [clone](./rlog.rlog.clone.md) + +## RLog.clone() method + +Creates a new [RLog](./rlog.rlog.md) instance with all the same settings and properties. + +Everything is deep copied, so any mutations to the original will safely not replicate. + +**Signature:** + +```typescript +clone(): RLog; +``` +**Returns:** + +[RLog](./rlog.rlog.md) + +A duplicate of this [RLog](./rlog.rlog.md) instance. + diff --git a/docs/api/rlog.rlog.clone_1.md b/docs/api/rlog.rlog.clone_1.md new file mode 100644 index 0000000..57414b8 --- /dev/null +++ b/docs/api/rlog.rlog.clone_1.md @@ -0,0 +1,57 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [clone](./rlog.rlog.clone_1.md) + +## RLog.clone() method + +Creates a new [RLog](./rlog.rlog.md) instance with all the same settings and properties. + +The provided [parameters](./rlog.rlogconstructorparameters.md) will be merged with the existing parameters on this instance. + +Everything is deep copied, so any mutations to the original will safely not replicate. + +**Signature:** + +```typescript +clone({ config, tag, parent, sinks, enrichers, correlation_id }: RLogConstructorParameters): RLog; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +{ config, tag, parent, sinks, enrichers, correlation\_id } + + + + +[RLogConstructorParameters](./rlog.rlogconstructorparameters.md) + + + + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +A duplicate of this [RLog](./rlog.rlog.md) instance. + diff --git a/docs/api/rlog.rlog.d.md b/docs/api/rlog.rlog.d.md new file mode 100644 index 0000000..6a62e0f --- /dev/null +++ b/docs/api/rlog.rlog.d.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [d](./rlog.rlog.d.md) + +## RLog.d() method + +Shorthand version of [debug](./rlog.rlog.debug.md). + +**Signature:** + +```typescript +d(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.debug.md b/docs/api/rlog.rlog.debug.md new file mode 100644 index 0000000..824fd50 --- /dev/null +++ b/docs/api/rlog.rlog.debug.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [debug](./rlog.rlog.debug.md) + +## RLog.debug() method + +Logs a debug message. + +**Signature:** + +```typescript +debug(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.default.md b/docs/api/rlog.rlog.default.md new file mode 100644 index 0000000..3e8500e --- /dev/null +++ b/docs/api/rlog.rlog.default.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [default](./rlog.rlog.default.md) + +## RLog.default property + +The default or "global" [RLog](./rlog.rlog.md) instance. + +All loggers inherit from this, so it's a convenient way for attaching global sinks or enrichers. + +**Signature:** + +```typescript +static readonly default: RLog; +``` diff --git a/docs/api/rlog.rlog.e.md b/docs/api/rlog.rlog.e.md new file mode 100644 index 0000000..5cc7d0f --- /dev/null +++ b/docs/api/rlog.rlog.e.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [e](./rlog.rlog.e.md) + +## RLog.e() method + +Shorthand version of [error](./rlog.rlog.error.md). + +**Signature:** + +```typescript +e(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.error.md b/docs/api/rlog.rlog.error.md new file mode 100644 index 0000000..b548efb --- /dev/null +++ b/docs/api/rlog.rlog.error.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [error](./rlog.rlog.error.md) + +## RLog.error() method + +Logs an error message. + +**Signature:** + +```typescript +error(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.i.md b/docs/api/rlog.rlog.i.md new file mode 100644 index 0000000..9fae36e --- /dev/null +++ b/docs/api/rlog.rlog.i.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [i](./rlog.rlog.i.md) + +## RLog.i() method + +Shorthand version of [info](./rlog.rlog.info.md). + +**Signature:** + +```typescript +i(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.info.md b/docs/api/rlog.rlog.info.md new file mode 100644 index 0000000..9075c68 --- /dev/null +++ b/docs/api/rlog.rlog.info.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [info](./rlog.rlog.info.md) + +## RLog.info() method + +Logs an informational message. + +**Signature:** + +```typescript +info(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.log.md b/docs/api/rlog.rlog.log.md new file mode 100644 index 0000000..2b71b6b --- /dev/null +++ b/docs/api/rlog.rlog.log.md @@ -0,0 +1,85 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [log](./rlog.rlog.log.md) + +## RLog.log() method + +Logs a message with a specified log level. + +**Signature:** + +```typescript +log(level: LogLevel, message: string, data?: LogData): void; +``` + +## Parameters + + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +level + + + + +[LogLevel](./rlog.loglevel.md) + + + + +The log level. + + +
+ +message + + + + +string + + + + +The log message. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. Will be encoded according to this logger's [config](./rlog.rlogconfig.md). + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.md b/docs/api/rlog.rlog.md new file mode 100644 index 0000000..dad0d65 --- /dev/null +++ b/docs/api/rlog.rlog.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [rLog](./rlog.rlog.md) + +## rLog variable + +Mapping to [RLog](./rlog.rlog.md) + +**Signature:** + +```typescript +rLog: typeof RLog +``` diff --git a/docs/api/rlog.rlog.parent.md b/docs/api/rlog.rlog.parent.md new file mode 100644 index 0000000..59986c7 --- /dev/null +++ b/docs/api/rlog.rlog.parent.md @@ -0,0 +1,15 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [parent](./rlog.rlog.parent.md) + +## RLog.parent property + +The parent [RLog](./rlog.rlog.md) of this instance. + +See [child](./rlog.rlog.child.md) for more details on parent and child instances. + +**Signature:** + +```typescript +readonly parent: RLog | undefined; +``` diff --git a/docs/api/rlog.rlog.path.md b/docs/api/rlog.rlog.path.md new file mode 100644 index 0000000..dda0960 --- /dev/null +++ b/docs/api/rlog.rlog.path.md @@ -0,0 +1,36 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [path](./rlog.rlog.path.md) + +## RLog.path property + +The full path of this [RLog](./rlog.rlog.md). + +A [RLog](./rlog.rlog.md) path is a concatenation of names (tags) of all its parent instances, with the root being `DEFAULT`. + +In other words, its the hierarchy of the instance. + +Instances without a tag are referred to as anonymous instances, and as such are labeled as ``. + +**Signature:** + +```typescript +readonly path: string; +``` + +## Example + + +``` +const main = new RLog().withTag("main"); +const secondary = main.childWithTag("secondary"); +const anonymous = secondary.child(); + +print(main.path); +print(secondary.path); +print(anonymous.path); +// > DEFAULT.main +// > DEFAULT.main.secondary +// > DEFAULT.main.secondary. +``` + diff --git a/docs/api/rlog.rlog.setdefaultconfig.md b/docs/api/rlog.rlog.setdefaultconfig.md new file mode 100644 index 0000000..70ee558 --- /dev/null +++ b/docs/api/rlog.rlog.setdefaultconfig.md @@ -0,0 +1,71 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [SetDefaultConfig](./rlog.rlog.setdefaultconfig.md) + +## RLog.SetDefaultConfig() method + +Sets the config for the [default](./rlog.rlog.default.md) instance. + +Since all [RLog](./rlog.rlog.md) instances inherit their config from the default instance, this is a convenient way to provide default configuration settings. + +\_Note that this will \*\*not\*\* change the config for instances already created.\_ + +**Signature:** + +```typescript +static SetDefaultConfig(config: PartialRLogConfig): void; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +config + + + + +[PartialRLogConfig](./rlog.partialrlogconfig.md) + + + + +The [RLogConfig](./rlog.rlogconfig.md) to use. + + +
+**Returns:** + +void + +## Example + + +```ts +RLog.SetDefaultConfig({ { serialization: { encodeFunctions: true } } }); + +// Inherits the `encodeFunctions` setting automatically +const logger = new RLog({ serialization: { encodeRobloxTypes: false } }); + +logger.i("Player died", { player: player, location: player.Position, revive: () => {} }); +// > [INFO]: Player died +// > { "data": { "player": 1338, "location": "", "revive": "" } } +``` + diff --git a/docs/api/rlog.rlog.tag.md b/docs/api/rlog.rlog.tag.md new file mode 100644 index 0000000..4cb41d3 --- /dev/null +++ b/docs/api/rlog.rlog.tag.md @@ -0,0 +1,17 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [tag](./rlog.rlog.tag.md) + +## RLog.tag property + +The tag of this [RLog](./rlog.rlog.md) instance. + +Tags are used for filtering logs. + +See [withTag](./rlog.rlog.withtag.md) for more details. + +**Signature:** + +```typescript +readonly tag: string | undefined; +``` diff --git a/docs/api/rlog.rlog.v.md b/docs/api/rlog.rlog.v.md new file mode 100644 index 0000000..9f6db32 --- /dev/null +++ b/docs/api/rlog.rlog.v.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [v](./rlog.rlog.v.md) + +## RLog.v() method + +Shorthand version of [verbose](./rlog.rlog.verbose.md). + +**Signature:** + +```typescript +v(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.verbose.md b/docs/api/rlog.rlog.verbose.md new file mode 100644 index 0000000..b3e3dad --- /dev/null +++ b/docs/api/rlog.rlog.verbose.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [verbose](./rlog.rlog.verbose.md) + +## RLog.verbose() method + +Logs a verbose message. + +**Signature:** + +```typescript +verbose(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.w.md b/docs/api/rlog.rlog.w.md new file mode 100644 index 0000000..9455f96 --- /dev/null +++ b/docs/api/rlog.rlog.w.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [w](./rlog.rlog.w.md) + +## RLog.w() method + +Shorthand version of [warning](./rlog.rlog.warning.md). + +**Signature:** + +```typescript +w(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.warn.md b/docs/api/rlog.rlog.warn.md new file mode 100644 index 0000000..ba8ed61 --- /dev/null +++ b/docs/api/rlog.rlog.warn.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [warn](./rlog.rlog.warn.md) + +## RLog.warn() method + +Shorthand version of [warning](./rlog.rlog.warning.md). + +**Signature:** + +```typescript +warn(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.warning.md b/docs/api/rlog.rlog.warning.md new file mode 100644 index 0000000..489c6c8 --- /dev/null +++ b/docs/api/rlog.rlog.warning.md @@ -0,0 +1,69 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [warning](./rlog.rlog.warning.md) + +## RLog.warning() method + +Logs a warning message. + +**Signature:** + +```typescript +warning(message: string, data?: LogData): void; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +message + + + + +string + + + + +The message to log. + + +
+ +data + + + + +[LogData](./rlog.logdata.md) + + + + +_(Optional)_ Optional data to log. + + +
+**Returns:** + +void + diff --git a/docs/api/rlog.rlog.withconfig.md b/docs/api/rlog.rlog.withconfig.md new file mode 100644 index 0000000..8f9ea2c --- /dev/null +++ b/docs/api/rlog.rlog.withconfig.md @@ -0,0 +1,79 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [withConfig](./rlog.rlog.withconfig.md) + +## RLog.withConfig() method + +Returns a new [RLog](./rlog.rlog.md) with the config merged with the existing config. + +You can use this to toggle certain features on [child](./rlog.rlog.child.md) instances, or conditionally apply certain configurations. + +**Signature:** + +```typescript +withConfig(config: PartialRLogConfig): RLog; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +config + + + + +[PartialRLogConfig](./rlog.partialrlogconfig.md) + + + + +Configuration settings to apply to the new instance. + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance + +## Example + + +```ts +let logger = new RLog({ minLogLevel: LogLevel.DEBUG }); + +const data = { position: new Vector2(5, 10) }; + +logger.v("Hello verbose!", data); +logger.d("Hello debug!", data); +// > [DEBUG]: Hello debug! +// > { data: { position: { X: 5, Y: 10 } } } + +// Inherits the minLogLevel +logger = logger.withConfig({ serialization: { encodeRobloxTypes: false } }); + +logger.v("Hello verbose!", data); +logger.d("Hello debug!", data); +// > [DEBUG]: Hello debug! +// > { data: { position: "" } } +``` + diff --git a/docs/api/rlog.rlog.withcorrelationid.md b/docs/api/rlog.rlog.withcorrelationid.md new file mode 100644 index 0000000..64c5fa4 --- /dev/null +++ b/docs/api/rlog.rlog.withcorrelationid.md @@ -0,0 +1,70 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [withCorrelationId](./rlog.rlog.withcorrelationid.md) + +## RLog.withCorrelationId() method + +Returns a new [RLog](./rlog.rlog.md) with the correlation\_id set to `correlation_id`. + +Correlation IDs are appended to log messages when present, for further tracking beyond [tags](./rlog.rlog.withtag.md). Especially useful when tracking control flows across services or files. + +To learn more about Correlation IDs, see [child](./rlog.rlog.child.md). + +**Signature:** + +```typescript +withCorrelationId(correlation_id: string): RLog; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +correlation\_id + + + + +string + + + + +The new correlation\_id to use. + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance. + +## Example + + +```ts +const logger = new RLog().withCorrelationId("12345"); + +logger.d("Hello world!"); +// > [DEBUG]: "Hello world!" +// > { correlation_id: "12345" } +``` + diff --git a/docs/api/rlog.rlog.withenricher.md b/docs/api/rlog.rlog.withenricher.md new file mode 100644 index 0000000..8d647b8 --- /dev/null +++ b/docs/api/rlog.rlog.withenricher.md @@ -0,0 +1,100 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [withEnricher](./rlog.rlog.withenricher.md) + +## RLog.withEnricher() method + +Creates a new [RLog](./rlog.rlog.md) instance with the given `enricher` added. + +Enrichers are callbacks that may or may not add data to (or mutate directly) a [LogEntry](./rlog.logentry.md). + +In the case of multiple enrichers, they are called in the order they are added. + +Furthermore, child enrichers are called before [parent](./rlog.rlog.child.md) enrichers. + +\_Note that enrichers are called before sinks.\_ + +**Signature:** + +```typescript +withEnricher(enricher: LogEnricherCallback, minLevel?: LogLevel): RLog; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +enricher + + + + +[LogEnricherCallback](./rlog.logenrichercallback.md) + + + + +The enricher callback. + + +
+ +minLevel + + + + +[LogLevel](./rlog.loglevel.md) + + + + +_(Optional)_ The minimum [LogLevel](./rlog.loglevel.md) for the enricher. The enricher will not be called for logs that are below this. Defaults to [LogLevel.VERBOSE](./rlog.loglevel.md). + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance. + +## Example + + +```ts +function MyCustomEnricher(entry: LogEntry, config: RLogConfig): LogEntry { + // attach the local player's user id if we're running in a LocalScript + if(RunService.IsClient()) { + entry.data["player"] = Players.LocalPlayer.UserId; + } + + // return the modified entry + return entry; +} + +const logger = new RLog().withEnricher(MyCustomEnricher); + +logger.v("Hello verbose"); +// > [VERBOSE]: Hello Verbose +// > { "data": { "player": 1333 } } +``` + diff --git a/docs/api/rlog.rlog.withenrichers.md b/docs/api/rlog.rlog.withenrichers.md new file mode 100644 index 0000000..5826266 --- /dev/null +++ b/docs/api/rlog.rlog.withenrichers.md @@ -0,0 +1,73 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [withEnrichers](./rlog.rlog.withenrichers.md) + +## RLog.withEnrichers() method + +Creates a new [RLog](./rlog.rlog.md) instance with all of the given `enrichers` added. + +Version of [withEnricher](./rlog.rlog.withenricher.md) that allows you to provide multiple enrichers at once. + +**Signature:** + +```typescript +withEnrichers(enrichers: ReadonlyArray, minLevel?: LogLevel): RLog; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +enrichers + + + + +ReadonlyArray<[LogEnricherCallback](./rlog.logenrichercallback.md)> + + + + +Array of enricher callbacks. + + +
+ +minLevel + + + + +[LogLevel](./rlog.loglevel.md) + + + + +_(Optional)_ The minimum [LogLevel](./rlog.loglevel.md) for the enrichers. The enrichers will not be called for logs that are below this. Defaults to [LogLevel.VERBOSE](./rlog.loglevel.md). + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance. + diff --git a/docs/api/rlog.rlog.withminloglevel.md b/docs/api/rlog.rlog.withminloglevel.md new file mode 100644 index 0000000..3bb9b8b --- /dev/null +++ b/docs/api/rlog.rlog.withminloglevel.md @@ -0,0 +1,77 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [withMinLogLevel](./rlog.rlog.withminloglevel.md) + +## RLog.withMinLogLevel() method + +Returns a new [RLog](./rlog.rlog.md) with the minLogLevel set to `minLogLevel`. + +Messages below the minimum level will be ignored. + +You can also set this in the [config](./rlog.rlogconfig.md), this method is purely provided as a means for easier changing. + +**Signature:** + +```typescript +withMinLogLevel(minLevel: LogLevel): RLog; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +minLevel + + + + +[LogLevel](./rlog.loglevel.md) + + + + +The [LogLevel](./rlog.loglevel.md) to allow logs for. + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance + +## Example + + +```ts +let logger = new RLog(); + +logger.v("Hello verbose!"); +logger.d("Hello debug!"); +// > [VERBOSE]: Hello verbose! +// > [DEBUG]: Hello debug! + +logger = logger.withMinLogLevel(LogLevel.DEBUG); + +logger.v("Hello verbose!"); +logger.d("Hello debug!"); +// > [DEBUG]: Hello debug! +``` + diff --git a/docs/api/rlog.rlog.withparent.md b/docs/api/rlog.rlog.withparent.md new file mode 100644 index 0000000..ef30024 --- /dev/null +++ b/docs/api/rlog.rlog.withparent.md @@ -0,0 +1,75 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [withParent](./rlog.rlog.withparent.md) + +## RLog.withParent() method + +Returns a new [RLog](./rlog.rlog.md) with the parent set to the provided `parent`. + +You can use this to switch the parents of [child](./rlog.rlog.child.md) instances, or whatever else you fancy. + +**Signature:** + +```typescript +withParent(parent: RLog | undefined): RLog; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +parent + + + + +[RLog](./rlog.rlog.md) \| undefined + + + + +The new parent to use on the new instance. + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance + +## Example + + +```ts +const mainLogger = new RLog(settings, "Main"); +const secondaryLogger = new RLog(settings, "Secondary"); + +print(mainLogger.path); +print(secondaryLogger.path); +// > DEFAULT.Main +// > DEFAULT.Secondary + +const newSecondary = secondaryLogger.withParent(mainLogger); + +print(newSecondary.path); +// > DEFAULT.Main.Secondary +``` + diff --git a/docs/api/rlog.rlog.withsink.md b/docs/api/rlog.rlog.withsink.md new file mode 100644 index 0000000..d4233fe --- /dev/null +++ b/docs/api/rlog.rlog.withsink.md @@ -0,0 +1,97 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [withSink](./rlog.rlog.withsink.md) + +## RLog.withSink() method + +Creates a new [RLog](./rlog.rlog.md) instance with the given `sink` added. + +Sinks are callbacks that take in a [LogEntry](./rlog.logentry.md) and return a boolean indicating if the entry was "consumed". + +If an entry is "consumed", that means it should not be processed any more. + +This is especially useful if you want to log your events to an external server, but not the local console. + +In the case of multiple sinks, they are called in the order they are added. + +Furthermore, child sinks are called before [parent](./rlog.rlog.child.md) sinks. + +\_Note that the [LogEntry](./rlog.logentry.md) you receive will already be enriched.\_ + +**Signature:** + +```typescript +withSink(sink: LogSinkCallback, minLevel?: LogLevel): RLog; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +sink + + + + +[LogSinkCallback](./rlog.logsinkcallback.md) + + + + +The sink callback. + + +
+ +minLevel + + + + +[LogLevel](./rlog.loglevel.md) + + + + +_(Optional)_ The minimum [LogLevel](./rlog.loglevel.md) for the sink. The sink will not be called for logs that are below this. Defaults to [LogLevel.VERBOSE](./rlog.loglevel.md). + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance. + +## Example + + +```ts +function MyCustomSink(entry: LogEntry, config: RLogConfig): boolean { + // ... log to external server + return true; // consume the message, meaning don't pass it along +} + +const logger = new RLog().withSink(MyCustomSink); + +logger.v("Hello verbose"); // no output to the console, since it was consumed. +``` + diff --git a/docs/api/rlog.rlog.withsinks.md b/docs/api/rlog.rlog.withsinks.md new file mode 100644 index 0000000..6e3633c --- /dev/null +++ b/docs/api/rlog.rlog.withsinks.md @@ -0,0 +1,73 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [withSinks](./rlog.rlog.withsinks.md) + +## RLog.withSinks() method + +Creates a new [RLog](./rlog.rlog.md) instance with all of the given `sinks` added. + +Version of [withSink](./rlog.rlog.withsink.md) that allows you to provide multiple sinks at once. + +**Signature:** + +```typescript +withSinks(sinks: ReadonlyArray, minLevel?: LogLevel): RLog; +``` + +## Parameters + + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +sinks + + + + +ReadonlyArray<[LogSinkCallback](./rlog.logsinkcallback.md)> + + + + +Array of sink callbacks. + + +
+ +minLevel + + + + +[LogLevel](./rlog.loglevel.md) + + + + +_(Optional)_ The minimum [LogLevel](./rlog.loglevel.md) for the sinks. The sinks will not be called for logs that are below this. Defaults to [LogLevel.VERBOSE](./rlog.loglevel.md). + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance. + diff --git a/docs/api/rlog.rlog.withtag.md b/docs/api/rlog.rlog.withtag.md new file mode 100644 index 0000000..b2d692f --- /dev/null +++ b/docs/api/rlog.rlog.withtag.md @@ -0,0 +1,74 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLog](./rlog.rlog.md) > [withTag](./rlog.rlog.withtag.md) + +## RLog.withTag() method + +Returns a new [RLog](./rlog.rlog.md) with the tag set to `tag`. + +Tags are appended to log messages when present, for easier filtering. + +Usually, they're used at the class level to keep track of all logs facilitated by a single class + +**Signature:** + +```typescript +withTag(tag: string): RLog; +``` + +## Parameters + + + +
+ +Parameter + + + + +Type + + + + +Description + + +
+ +tag + + + + +string + + + + +The new tag to use. + + +
+**Returns:** + +[RLog](./rlog.rlog.md) + +The new [RLog](./rlog.rlog.md) instance. + +## Example + + +```ts +let logger = new RLog(); + +logger.d("Hello world!"); +// > [DEBUG]: "Hello world!" + +logger = logger.withTag("main"); + +logger.d("Hello world!"); +// > [DEBUG]: main -> "Hello world!" +``` + diff --git a/docs/api/rlog.rlogconfig.md b/docs/api/rlog.rlogconfig.md new file mode 100644 index 0000000..47594ab --- /dev/null +++ b/docs/api/rlog.rlogconfig.md @@ -0,0 +1,23 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLogConfig](./rlog.rlogconfig.md) + +## RLogConfig type + +Configuration settings for [RLog](./rlog.rlog.md). + +**Signature:** + +```typescript +export type RLogConfig = { + readonly minLogLevel: LogLevel; + readonly functionTags: boolean; + readonly fileTags: boolean; + readonly serialization: SerializationConfig; + readonly autoGenerateChildCorrelation: boolean; + readonly autoGenerateCorrelation: boolean; + readonly correlationGenerator?: () => string; +}; +``` +**References:** [LogLevel](./rlog.loglevel.md), [SerializationConfig](./rlog.serializationconfig.md) + diff --git a/docs/api/rlog.rlogconstructorparameters.md b/docs/api/rlog.rlogconstructorparameters.md new file mode 100644 index 0000000..10b897e --- /dev/null +++ b/docs/api/rlog.rlogconstructorparameters.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [RLogConstructorParameters](./rlog.rlogconstructorparameters.md) + +## RLogConstructorParameters type + +Table version of the constructor parameters for [RLog](./rlog.rlog.md). + +**Signature:** + +```typescript +export type RLogConstructorParameters = { + config?: PartialRLogConfig; + tag?: string; + parent?: RLog; + sinks?: LogSinkCallback[]; + enrichers?: LogEnricherCallback[]; + correlation_id?: string; +}; +``` +**References:** [PartialRLogConfig](./rlog.partialrlogconfig.md), [RLog](./rlog.rlog.md), [LogSinkCallback](./rlog.logsinkcallback.md), [LogEnricherCallback](./rlog.logenrichercallback.md) + diff --git a/docs/api/rlog.serializationconfig.md b/docs/api/rlog.serializationconfig.md new file mode 100644 index 0000000..0a6f805 --- /dev/null +++ b/docs/api/rlog.serializationconfig.md @@ -0,0 +1,22 @@ + + +[Home](./index.md) > [@rbxts/rlog](./rlog.md) > [SerializationConfig](./rlog.serializationconfig.md) + +## SerializationConfig type + +Configuration settings for serialization. + +**Signature:** + +```typescript +export type SerializationConfig = { + readonly minLogLevel: LogLevel; + readonly encodeRobloxTypes: boolean; + readonly encodeFunctions: boolean; + readonly deepEncodeTables: boolean; + readonly encodeType: EncodingType; + readonly encodeMethod: string; +}; +``` +**References:** [LogLevel](./rlog.loglevel.md), [EncodingType](./rlog.encodingtype.md) + diff --git a/etc/rlog.api.md b/etc/rlog.api.md new file mode 100644 index 0000000..7f21ea9 --- /dev/null +++ b/etc/rlog.api.md @@ -0,0 +1,126 @@ +## API Report File for "@rbxts/rlog" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +/// + +// @public +export enum EncodingType { + DEEP = 0, + FAST = 1 +} + +// @public +export type LogData = Record; + +// @public +export type LogEnricherCallback = (entry: LogEntry, config: RLogConfig) => LogEntry; + +// @public +export type LogEntry = { + level: LogLevel; + message: string; + data: LogData; + metadata: LogMetadata; +}; + +// @public +export enum LogLevel { + DEBUG = 1, + ERROR = 4, + INFO = 2, + VERBOSE = 0, + WARNING = 3 +} + +// @public +export type LogMetadata = { + timestamp: number; + correlation_id?: string; + tag?: string; +}; + +// @public +export type LogSinkCallback = (entry: LogEntry, config: RLogConfig) => boolean | void; + +// @public +export type PartialRLogConfig = Partial> & { + readonly serialization?: Partial; +}; + +// @public +export class RLog { + constructor({ config, tag, parent, sinks, enrichers, correlation_id }: RLogConstructorParameters); + constructor(config?: PartialRLogConfig, tag?: string, parent?: RLog, sinks?: LogSinkCallback[], enrichers?: LogEnricherCallback[], correlation_id?: string); + child(correlation_id?: string | undefined): RLog; + childWithTag(tag?: string | undefined, correlation_id?: string | undefined): RLog; + clone(): RLog; + clone({ config, tag, parent, sinks, enrichers, correlation_id }: RLogConstructorParameters): RLog; + d(message: string, data?: LogData): void; + debug(message: string, data?: LogData): void; + static readonly default: RLog; + e(message: string, data?: LogData): void; + error(message: string, data?: LogData): void; + i(message: string, data?: LogData): void; + info(message: string, data?: LogData): void; + log(level: LogLevel, message: string, data?: LogData): void; + readonly parent: RLog | undefined; + readonly path: string; + static SetDefaultConfig(config: PartialRLogConfig): void; + readonly tag: string | undefined; + v(message: string, data?: LogData): void; + verbose(message: string, data?: LogData): void; + w(message: string, data?: LogData): void; + warn(message: string, data?: LogData): void; + warning(message: string, data?: LogData): void; + withConfig(config: PartialRLogConfig): RLog; + withCorrelationId(correlation_id: string): RLog; + withEnricher(enricher: LogEnricherCallback, minLevel?: LogLevel): RLog; + withEnrichers(enrichers: ReadonlyArray, minLevel?: LogLevel): RLog; + withMinLogLevel(minLevel: LogLevel): RLog; + withParent(parent: RLog | undefined): RLog; + withSink(sink: LogSinkCallback, minLevel?: LogLevel): RLog; + withSinks(sinks: ReadonlyArray, minLevel?: LogLevel): RLog; + withTag(tag: string): RLog; +} + +// @public +export const rLog: typeof RLog; + +// @public +export const rlog: typeof RLog; + +// @public +export type RLogConfig = { + readonly minLogLevel: LogLevel; + readonly functionTags: boolean; + readonly fileTags: boolean; + readonly serialization: SerializationConfig; + readonly autoGenerateChildCorrelation: boolean; + readonly autoGenerateCorrelation: boolean; + readonly correlationGenerator?: () => string; +}; + +// @public +export type RLogConstructorParameters = { + config?: PartialRLogConfig; + tag?: string; + parent?: RLog; + sinks?: LogSinkCallback[]; + enrichers?: LogEnricherCallback[]; + correlation_id?: string; +}; + +// @public +export type SerializationConfig = { + readonly minLogLevel: LogLevel; + readonly encodeRobloxTypes: boolean; + readonly encodeFunctions: boolean; + readonly deepEncodeTables: boolean; + readonly encodeType: EncodingType; + readonly encodeMethod: string; +}; + +``` diff --git a/include/Promise.lua b/include/Promise.lua new file mode 100644 index 0000000..97cdf37 --- /dev/null +++ b/include/Promise.lua @@ -0,0 +1,2068 @@ +--[[ + An implementation of Promises similar to Promise/A+. +]] + +local ERROR_NON_PROMISE_IN_LIST = "Non-promise value passed into %s at index %s" +local ERROR_NON_LIST = "Please pass a list of promises to %s" +local ERROR_NON_FUNCTION = "Please pass a handler function to %s!" +local MODE_KEY_METATABLE = { __mode = "k" } + +local function isCallable(value) + if type(value) == "function" then + return true + end + + if type(value) == "table" then + local metatable = getmetatable(value) + if metatable and type(rawget(metatable, "__call")) == "function" then + return true + end + end + + return false +end + +--[[ + Creates an enum dictionary with some metamethods to prevent common mistakes. +]] +local function makeEnum(enumName, members) + local enum = {} + + for _, memberName in ipairs(members) do + enum[memberName] = memberName + end + + return setmetatable(enum, { + __index = function(_, k) + error(string.format("%s is not in %s!", k, enumName), 2) + end, + __newindex = function() + error(string.format("Creating new members in %s is not allowed!", enumName), 2) + end, + }) +end + +--[=[ + An object to represent runtime errors that occur during execution. + Promises that experience an error like this will be rejected with + an instance of this object. + + @class Error +]=] +local Error +do + Error = { + Kind = makeEnum("Promise.Error.Kind", { + "ExecutionError", + "AlreadyCancelled", + "NotResolvedInTime", + "TimedOut", + }), + } + Error.__index = Error + + function Error.new(options, parent) + options = options or {} + return setmetatable({ + error = tostring(options.error) or "[This error has no error text.]", + trace = options.trace, + context = options.context, + kind = options.kind, + parent = parent, + createdTick = os.clock(), + createdTrace = debug.traceback(), + }, Error) + end + + function Error.is(anything) + if type(anything) == "table" then + local metatable = getmetatable(anything) + + if type(metatable) == "table" then + return rawget(anything, "error") ~= nil and type(rawget(metatable, "extend")) == "function" + end + end + + return false + end + + function Error.isKind(anything, kind) + assert(kind ~= nil, "Argument #2 to Promise.Error.isKind must not be nil") + + return Error.is(anything) and anything.kind == kind + end + + function Error:extend(options) + options = options or {} + + options.kind = options.kind or self.kind + + return Error.new(options, self) + end + + function Error:getErrorChain() + local runtimeErrors = { self } + + while runtimeErrors[#runtimeErrors].parent do + table.insert(runtimeErrors, runtimeErrors[#runtimeErrors].parent) + end + + return runtimeErrors + end + + function Error:__tostring() + local errorStrings = { + string.format("-- Promise.Error(%s) --", self.kind or "?"), + } + + for _, runtimeError in ipairs(self:getErrorChain()) do + table.insert( + errorStrings, + table.concat({ + runtimeError.trace or runtimeError.error, + runtimeError.context, + }, "\n") + ) + end + + return table.concat(errorStrings, "\n") + end +end + +--[[ + Packs a number of arguments into a table and returns its length. + + Used to cajole varargs without dropping sparse values. +]] +local function pack(...) + return select("#", ...), { ... } +end + +--[[ + Returns first value (success), and packs all following values. +]] +local function packResult(success, ...) + return success, select("#", ...), { ... } +end + +local function makeErrorHandler(traceback) + assert(traceback ~= nil, "traceback is nil") + + return function(err) + -- If the error object is already a table, forward it directly. + -- Should we extend the error here and add our own trace? + + if type(err) == "table" then + return err + end + + return Error.new({ + error = err, + kind = Error.Kind.ExecutionError, + trace = debug.traceback(tostring(err), 2), + context = "Promise created at:\n\n" .. traceback, + }) + end +end + +--[[ + Calls a Promise executor with error handling. +]] +local function runExecutor(traceback, callback, ...) + return packResult(xpcall(callback, makeErrorHandler(traceback), ...)) +end + +--[[ + Creates a function that invokes a callback with correct error handling and + resolution mechanisms. +]] +local function createAdvancer(traceback, callback, resolve, reject) + return function(...) + local ok, resultLength, result = runExecutor(traceback, callback, ...) + + if ok then + resolve(unpack(result, 1, resultLength)) + else + reject(result[1]) + end + end +end + +local function isEmpty(t) + return next(t) == nil +end + +--[=[ + An enum value used to represent the Promise's status. + @interface Status + @tag enum + @within Promise + .Started "Started" -- The Promise is executing, and not settled yet. + .Resolved "Resolved" -- The Promise finished successfully. + .Rejected "Rejected" -- The Promise was rejected. + .Cancelled "Cancelled" -- The Promise was cancelled before it finished. +]=] +--[=[ + @prop Status Status + @within Promise + @readonly + @tag enums + A table containing all members of the `Status` enum, e.g., `Promise.Status.Resolved`. +]=] +--[=[ + A Promise is an object that represents a value that will exist in the future, but doesn't right now. + Promises allow you to then attach callbacks that can run once the value becomes available (known as *resolving*), + or if an error has occurred (known as *rejecting*). + + @class Promise + @__index prototype +]=] +local Promise = { + Error = Error, + Status = makeEnum("Promise.Status", { "Started", "Resolved", "Rejected", "Cancelled" }), + _getTime = os.clock, + _timeEvent = game:GetService("RunService").Heartbeat, + _unhandledRejectionCallbacks = {}, +} +Promise.prototype = {} +Promise.__index = Promise.prototype + +function Promise._new(traceback, callback, parent) + if parent ~= nil and not Promise.is(parent) then + error("Argument #2 to Promise.new must be a promise or nil", 2) + end + + local self = { + -- The executor thread. + _thread = nil, + + -- Used to locate where a promise was created + _source = traceback, + + _status = Promise.Status.Started, + + -- A table containing a list of all results, whether success or failure. + -- Only valid if _status is set to something besides Started + _values = nil, + + -- Lua doesn't like sparse arrays very much, so we explicitly store the + -- length of _values to handle middle nils. + _valuesLength = -1, + + -- Tracks if this Promise has no error observers.. + _unhandledRejection = true, + + -- Queues representing functions we should invoke when we update! + _queuedResolve = {}, + _queuedReject = {}, + _queuedFinally = {}, + + -- The function to run when/if this promise is cancelled. + _cancellationHook = nil, + + -- The "parent" of this promise in a promise chain. Required for + -- cancellation propagation upstream. + _parent = parent, + + -- Consumers are Promises that have chained onto this one. + -- We track them for cancellation propagation downstream. + _consumers = setmetatable({}, MODE_KEY_METATABLE), + } + + if parent and parent._status == Promise.Status.Started then + parent._consumers[self] = true + end + + setmetatable(self, Promise) + + local function resolve(...) + self:_resolve(...) + end + + local function reject(...) + self:_reject(...) + end + + local function onCancel(cancellationHook) + if cancellationHook then + if self._status == Promise.Status.Cancelled then + cancellationHook() + else + self._cancellationHook = cancellationHook + end + end + + return self._status == Promise.Status.Cancelled + end + + self._thread = coroutine.create(function() + local ok, _, result = runExecutor(self._source, callback, resolve, reject, onCancel) + + if not ok then + reject(result[1]) + end + end) + + task.spawn(self._thread) + + return self +end + +--[=[ + Construct a new Promise that will be resolved or rejected with the given callbacks. + + If you `resolve` with a Promise, it will be chained onto. + + You can safely yield within the executor function and it will not block the creating thread. + + ```lua + local myFunction() + return Promise.new(function(resolve, reject, onCancel) + wait(1) + resolve("Hello world!") + end) + end + + myFunction():andThen(print) + ``` + + You do not need to use `pcall` within a Promise. Errors that occur during execution will be caught and turned into a rejection automatically. If `error()` is called with a table, that table will be the rejection value. Otherwise, string errors will be converted into `Promise.Error(Promise.Error.Kind.ExecutionError)` objects for tracking debug information. + + You may register an optional cancellation hook by using the `onCancel` argument: + + * This should be used to abort any ongoing operations leading up to the promise being settled. + * Call the `onCancel` function with a function callback as its only argument to set a hook which will in turn be called when/if the promise is cancelled. + * `onCancel` returns `true` if the Promise was already cancelled when you called `onCancel`. + * Calling `onCancel` with no argument will not override a previously set cancellation hook, but it will still return `true` if the Promise is currently cancelled. + * You can set the cancellation hook at any time before resolving. + * When a promise is cancelled, calls to `resolve` or `reject` will be ignored, regardless of if you set a cancellation hook or not. + + :::caution + If the Promise is cancelled, the `executor` thread is closed with `coroutine.close` after the cancellation hook is called. + + You must perform any cleanup code in the cancellation hook: any time your executor yields, it **may never resume**. + ::: + + @param executor (resolve: (...: any) -> (), reject: (...: any) -> (), onCancel: (abortHandler?: () -> ()) -> boolean) -> () + @return Promise +]=] +function Promise.new(executor) + return Promise._new(debug.traceback(nil, 2), executor) +end + +function Promise:__tostring() + return string.format("Promise(%s)", self._status) +end + +--[=[ + The same as [Promise.new](/api/Promise#new), except execution begins after the next `Heartbeat` event. + + This is a spiritual replacement for `spawn`, but it does not suffer from the same [issues](https://eryn.io/gist/3db84579866c099cdd5bb2ff37947cec) as `spawn`. + + ```lua + local function waitForChild(instance, childName, timeout) + return Promise.defer(function(resolve, reject) + local child = instance:WaitForChild(childName, timeout) + + ;(child and resolve or reject)(child) + end) + end + ``` + + @param executor (resolve: (...: any) -> (), reject: (...: any) -> (), onCancel: (abortHandler?: () -> ()) -> boolean) -> () + @return Promise +]=] +function Promise.defer(executor) + local traceback = debug.traceback(nil, 2) + local promise + promise = Promise._new(traceback, function(resolve, reject, onCancel) + local connection + connection = Promise._timeEvent:Connect(function() + connection:Disconnect() + local ok, _, result = runExecutor(traceback, executor, resolve, reject, onCancel) + + if not ok then + reject(result[1]) + end + end) + end) + + return promise +end + +-- Backwards compatibility +Promise.async = Promise.defer + +--[=[ + Creates an immediately resolved Promise with the given value. + + ```lua + -- Example using Promise.resolve to deliver cached values: + function getSomething(name) + if cache[name] then + return Promise.resolve(cache[name]) + else + return Promise.new(function(resolve, reject) + local thing = getTheThing() + cache[name] = thing + + resolve(thing) + end) + end + end + ``` + + @param ... any + @return Promise<...any> +]=] +function Promise.resolve(...) + local length, values = pack(...) + return Promise._new(debug.traceback(nil, 2), function(resolve) + resolve(unpack(values, 1, length)) + end) +end + +--[=[ + Creates an immediately rejected Promise with the given value. + + :::caution + Something needs to consume this rejection (i.e. `:catch()` it), otherwise it will emit an unhandled Promise rejection warning on the next frame. Thus, you should not create and store rejected Promises for later use. Only create them on-demand as needed. + ::: + + @param ... any + @return Promise<...any> +]=] +function Promise.reject(...) + local length, values = pack(...) + return Promise._new(debug.traceback(nil, 2), function(_, reject) + reject(unpack(values, 1, length)) + end) +end + +--[[ + Runs a non-promise-returning function as a Promise with the + given arguments. +]] +function Promise._try(traceback, callback, ...) + local valuesLength, values = pack(...) + + return Promise._new(traceback, function(resolve) + resolve(callback(unpack(values, 1, valuesLength))) + end) +end + +--[=[ + Begins a Promise chain, calling a function and returning a Promise resolving with its return value. If the function errors, the returned Promise will be rejected with the error. You can safely yield within the Promise.try callback. + + :::info + `Promise.try` is similar to [Promise.promisify](#promisify), except the callback is invoked immediately instead of returning a new function. + ::: + + ```lua + Promise.try(function() + return math.random(1, 2) == 1 and "ok" or error("Oh an error!") + end) + :andThen(function(text) + print(text) + end) + :catch(function(err) + warn("Something went wrong") + end) + ``` + + @param callback (...: T...) -> ...any + @param ... T... -- Additional arguments passed to `callback` + @return Promise +]=] +function Promise.try(callback, ...) + return Promise._try(debug.traceback(nil, 2), callback, ...) +end + +--[[ + Returns a new promise that: + * is resolved when all input promises resolve + * is rejected if ANY input promises reject +]] +function Promise._all(traceback, promises, amount) + if type(promises) ~= "table" then + error(string.format(ERROR_NON_LIST, "Promise.all"), 3) + end + + -- We need to check that each value is a promise here so that we can produce + -- a proper error rather than a rejected promise with our error. + for i, promise in pairs(promises) do + if not Promise.is(promise) then + error(string.format(ERROR_NON_PROMISE_IN_LIST, "Promise.all", tostring(i)), 3) + end + end + + -- If there are no values then return an already resolved promise. + if #promises == 0 or amount == 0 then + return Promise.resolve({}) + end + + return Promise._new(traceback, function(resolve, reject, onCancel) + -- An array to contain our resolved values from the given promises. + local resolvedValues = {} + local newPromises = {} + + -- Keep a count of resolved promises because just checking the resolved + -- values length wouldn't account for promises that resolve with nil. + local resolvedCount = 0 + local rejectedCount = 0 + local done = false + + local function cancel() + for _, promise in ipairs(newPromises) do + promise:cancel() + end + end + + -- Called when a single value is resolved and resolves if all are done. + local function resolveOne(i, ...) + if done then + return + end + + resolvedCount = resolvedCount + 1 + + if amount == nil then + resolvedValues[i] = ... + else + resolvedValues[resolvedCount] = ... + end + + if resolvedCount >= (amount or #promises) then + done = true + resolve(resolvedValues) + cancel() + end + end + + onCancel(cancel) + + -- We can assume the values inside `promises` are all promises since we + -- checked above. + for i, promise in ipairs(promises) do + newPromises[i] = promise:andThen(function(...) + resolveOne(i, ...) + end, function(...) + rejectedCount = rejectedCount + 1 + + if amount == nil or #promises - rejectedCount < amount then + cancel() + done = true + + reject(...) + end + end) + end + + if done then + cancel() + end + end) +end + +--[=[ + Accepts an array of Promises and returns a new promise that: + * is resolved after all input promises resolve. + * is rejected if *any* input promises reject. + + :::info + Only the first return value from each promise will be present in the resulting array. + ::: + + After any input Promise rejects, all other input Promises that are still pending will be cancelled if they have no other consumers. + + ```lua + local promises = { + returnsAPromise("example 1"), + returnsAPromise("example 2"), + returnsAPromise("example 3"), + } + + return Promise.all(promises) + ``` + + @param promises {Promise} + @return Promise<{T}> +]=] +function Promise.all(promises) + return Promise._all(debug.traceback(nil, 2), promises) +end + +--[=[ + Folds an array of values or promises into a single value. The array is traversed sequentially. + + The reducer function can return a promise or value directly. Each iteration receives the resolved value from the previous, and the first receives your defined initial value. + + The folding will stop at the first rejection encountered. + ```lua + local basket = {"blueberry", "melon", "pear", "melon"} + Promise.fold(basket, function(cost, fruit) + if fruit == "blueberry" then + return cost -- blueberries are free! + else + -- call a function that returns a promise with the fruit price + return fetchPrice(fruit):andThen(function(fruitCost) + return cost + fruitCost + end) + end + end, 0) + ``` + + @since v3.1.0 + @param list {T | Promise} + @param reducer (accumulator: U, value: T, index: number) -> U | Promise + @param initialValue U +]=] +function Promise.fold(list, reducer, initialValue) + assert(type(list) == "table", "Bad argument #1 to Promise.fold: must be a table") + assert(isCallable(reducer), "Bad argument #2 to Promise.fold: must be a function") + + local accumulator = Promise.resolve(initialValue) + return Promise.each(list, function(resolvedElement, i) + accumulator = accumulator:andThen(function(previousValueResolved) + return reducer(previousValueResolved, resolvedElement, i) + end) + end):andThen(function() + return accumulator + end) +end + +--[=[ + Accepts an array of Promises and returns a Promise that is resolved as soon as `count` Promises are resolved from the input array. The resolved array values are in the order that the Promises resolved in. When this Promise resolves, all other pending Promises are cancelled if they have no other consumers. + + `count` 0 results in an empty array. The resultant array will never have more than `count` elements. + + ```lua + local promises = { + returnsAPromise("example 1"), + returnsAPromise("example 2"), + returnsAPromise("example 3"), + } + + return Promise.some(promises, 2) -- Only resolves with first 2 promises to resolve + ``` + + @param promises {Promise} + @param count number + @return Promise<{T}> +]=] +function Promise.some(promises, count) + assert(type(count) == "number", "Bad argument #2 to Promise.some: must be a number") + + return Promise._all(debug.traceback(nil, 2), promises, count) +end + +--[=[ + Accepts an array of Promises and returns a Promise that is resolved as soon as *any* of the input Promises resolves. It will reject only if *all* input Promises reject. As soon as one Promises resolves, all other pending Promises are cancelled if they have no other consumers. + + Resolves directly with the value of the first resolved Promise. This is essentially [[Promise.some]] with `1` count, except the Promise resolves with the value directly instead of an array with one element. + + ```lua + local promises = { + returnsAPromise("example 1"), + returnsAPromise("example 2"), + returnsAPromise("example 3"), + } + + return Promise.any(promises) -- Resolves with first value to resolve (only rejects if all 3 rejected) + ``` + + @param promises {Promise} + @return Promise +]=] +function Promise.any(promises) + return Promise._all(debug.traceback(nil, 2), promises, 1):andThen(function(values) + return values[1] + end) +end + +--[=[ + Accepts an array of Promises and returns a new Promise that resolves with an array of in-place Statuses when all input Promises have settled. This is equivalent to mapping `promise:finally` over the array of Promises. + + ```lua + local promises = { + returnsAPromise("example 1"), + returnsAPromise("example 2"), + returnsAPromise("example 3"), + } + + return Promise.allSettled(promises) + ``` + + @param promises {Promise} + @return Promise<{Status}> +]=] +function Promise.allSettled(promises) + if type(promises) ~= "table" then + error(string.format(ERROR_NON_LIST, "Promise.allSettled"), 2) + end + + -- We need to check that each value is a promise here so that we can produce + -- a proper error rather than a rejected promise with our error. + for i, promise in pairs(promises) do + if not Promise.is(promise) then + error(string.format(ERROR_NON_PROMISE_IN_LIST, "Promise.allSettled", tostring(i)), 2) + end + end + + -- If there are no values then return an already resolved promise. + if #promises == 0 then + return Promise.resolve({}) + end + + return Promise._new(debug.traceback(nil, 2), function(resolve, _, onCancel) + -- An array to contain our resolved values from the given promises. + local fates = {} + local newPromises = {} + + -- Keep a count of resolved promises because just checking the resolved + -- values length wouldn't account for promises that resolve with nil. + local finishedCount = 0 + + -- Called when a single value is resolved and resolves if all are done. + local function resolveOne(i, ...) + finishedCount = finishedCount + 1 + + fates[i] = ... + + if finishedCount >= #promises then + resolve(fates) + end + end + + onCancel(function() + for _, promise in ipairs(newPromises) do + promise:cancel() + end + end) + + -- We can assume the values inside `promises` are all promises since we + -- checked above. + for i, promise in ipairs(promises) do + newPromises[i] = promise:finally(function(...) + resolveOne(i, ...) + end) + end + end) +end + +--[=[ + Accepts an array of Promises and returns a new promise that is resolved or rejected as soon as any Promise in the array resolves or rejects. + + :::warning + If the first Promise to settle from the array settles with a rejection, the resulting Promise from `race` will reject. + + If you instead want to tolerate rejections, and only care about at least one Promise resolving, you should use [Promise.any](#any) or [Promise.some](#some) instead. + ::: + + All other Promises that don't win the race will be cancelled if they have no other consumers. + + ```lua + local promises = { + returnsAPromise("example 1"), + returnsAPromise("example 2"), + returnsAPromise("example 3"), + } + + return Promise.race(promises) -- Only returns 1st value to resolve or reject + ``` + + @param promises {Promise} + @return Promise +]=] +function Promise.race(promises) + assert(type(promises) == "table", string.format(ERROR_NON_LIST, "Promise.race")) + + for i, promise in pairs(promises) do + assert(Promise.is(promise), string.format(ERROR_NON_PROMISE_IN_LIST, "Promise.race", tostring(i))) + end + + return Promise._new(debug.traceback(nil, 2), function(resolve, reject, onCancel) + local newPromises = {} + local finished = false + + local function cancel() + for _, promise in ipairs(newPromises) do + promise:cancel() + end + end + + local function finalize(callback) + return function(...) + cancel() + finished = true + return callback(...) + end + end + + if onCancel(finalize(reject)) then + return + end + + for i, promise in ipairs(promises) do + newPromises[i] = promise:andThen(finalize(resolve), finalize(reject)) + end + + if finished then + cancel() + end + end) +end + +--[=[ + Iterates serially over the given an array of values, calling the predicate callback on each value before continuing. + + If the predicate returns a Promise, we wait for that Promise to resolve before moving on to the next item + in the array. + + :::info + `Promise.each` is similar to `Promise.all`, except the Promises are ran in order instead of all at once. + + But because Promises are eager, by the time they are created, they're already running. Thus, we need a way to defer creation of each Promise until a later time. + + The predicate function exists as a way for us to operate on our data instead of creating a new closure for each Promise. If you would prefer, you can pass in an array of functions, and in the predicate, call the function and return its return value. + ::: + + ```lua + Promise.each({ + "foo", + "bar", + "baz", + "qux" + }, function(value, index) + return Promise.delay(1):andThen(function() + print(("%d) Got %s!"):format(index, value)) + end) + end) + + --[[ + (1 second passes) + > 1) Got foo! + (1 second passes) + > 2) Got bar! + (1 second passes) + > 3) Got baz! + (1 second passes) + > 4) Got qux! + ]] + ``` + + If the Promise a predicate returns rejects, the Promise from `Promise.each` is also rejected with the same value. + + If the array of values contains a Promise, when we get to that point in the list, we wait for the Promise to resolve before calling the predicate with the value. + + If a Promise in the array of values is already Rejected when `Promise.each` is called, `Promise.each` rejects with that value immediately (the predicate callback will never be called even once). If a Promise in the list is already Cancelled when `Promise.each` is called, `Promise.each` rejects with `Promise.Error(Promise.Error.Kind.AlreadyCancelled`). If a Promise in the array of values is Started at first, but later rejects, `Promise.each` will reject with that value and iteration will not continue once iteration encounters that value. + + Returns a Promise containing an array of the returned/resolved values from the predicate for each item in the array of values. + + If this Promise returned from `Promise.each` rejects or is cancelled for any reason, the following are true: + - Iteration will not continue. + - Any Promises within the array of values will now be cancelled if they have no other consumers. + - The Promise returned from the currently active predicate will be cancelled if it hasn't resolved yet. + + @since 3.0.0 + @param list {T | Promise} + @param predicate (value: T, index: number) -> U | Promise + @return Promise<{U}> +]=] +function Promise.each(list, predicate) + assert(type(list) == "table", string.format(ERROR_NON_LIST, "Promise.each")) + assert(isCallable(predicate), string.format(ERROR_NON_FUNCTION, "Promise.each")) + + return Promise._new(debug.traceback(nil, 2), function(resolve, reject, onCancel) + local results = {} + local promisesToCancel = {} + + local cancelled = false + + local function cancel() + for _, promiseToCancel in ipairs(promisesToCancel) do + promiseToCancel:cancel() + end + end + + onCancel(function() + cancelled = true + + cancel() + end) + + -- We need to preprocess the list of values and look for Promises. + -- If we find some, we must register our andThen calls now, so that those Promises have a consumer + -- from us registered. If we don't do this, those Promises might get cancelled by something else + -- before we get to them in the series because it's not possible to tell that we plan to use it + -- unless we indicate it here. + + local preprocessedList = {} + + for index, value in ipairs(list) do + if Promise.is(value) then + if value:getStatus() == Promise.Status.Cancelled then + cancel() + return reject(Error.new({ + error = "Promise is cancelled", + kind = Error.Kind.AlreadyCancelled, + context = string.format( + "The Promise that was part of the array at index %d passed into Promise.each was already cancelled when Promise.each began.\n\nThat Promise was created at:\n\n%s", + index, + value._source + ), + })) + elseif value:getStatus() == Promise.Status.Rejected then + cancel() + return reject(select(2, value:await())) + end + + -- Chain a new Promise from this one so we only cancel ours + local ourPromise = value:andThen(function(...) + return ... + end) + + table.insert(promisesToCancel, ourPromise) + preprocessedList[index] = ourPromise + else + preprocessedList[index] = value + end + end + + for index, value in ipairs(preprocessedList) do + if Promise.is(value) then + local success + success, value = value:await() + + if not success then + cancel() + return reject(value) + end + end + + if cancelled then + return + end + + local predicatePromise = Promise.resolve(predicate(value, index)) + + table.insert(promisesToCancel, predicatePromise) + + local success, result = predicatePromise:await() + + if not success then + cancel() + return reject(result) + end + + results[index] = result + end + + resolve(results) + end) +end + +--[=[ + Checks whether the given object is a Promise via duck typing. This only checks if the object is a table and has an `andThen` method. + + @param object any + @return boolean -- `true` if the given `object` is a Promise. +]=] +function Promise.is(object) + if type(object) ~= "table" then + return false + end + + local objectMetatable = getmetatable(object) + + if objectMetatable == Promise then + -- The Promise came from this library. + return true + elseif objectMetatable == nil then + -- No metatable, but we should still chain onto tables with andThen methods + return isCallable(object.andThen) + elseif + type(objectMetatable) == "table" + and type(rawget(objectMetatable, "__index")) == "table" + and isCallable(rawget(rawget(objectMetatable, "__index"), "andThen")) + then + -- Maybe this came from a different or older Promise library. + return true + end + + return false +end + +--[=[ + Wraps a function that yields into one that returns a Promise. + + Any errors that occur while executing the function will be turned into rejections. + + :::info + `Promise.promisify` is similar to [Promise.try](#try), except the callback is returned as a callable function instead of being invoked immediately. + ::: + + ```lua + local sleep = Promise.promisify(wait) + + sleep(1):andThen(print) + ``` + + ```lua + local isPlayerInGroup = Promise.promisify(function(player, groupId) + return player:IsInGroup(groupId) + end) + ``` + + @param callback (...: any) -> ...any + @return (...: any) -> Promise +]=] +function Promise.promisify(callback) + return function(...) + return Promise._try(debug.traceback(nil, 2), callback, ...) + end +end + +--[=[ + Returns a Promise that resolves after `seconds` seconds have passed. The Promise resolves with the actual amount of time that was waited. + + This function is **not** a wrapper around `wait`. `Promise.delay` uses a custom scheduler which provides more accurate timing. As an optimization, cancelling this Promise instantly removes the task from the scheduler. + + :::warning + Passing `NaN`, infinity, or a number less than 1/60 is equivalent to passing 1/60. + ::: + + ```lua + Promise.delay(5):andThenCall(print, "This prints after 5 seconds") + ``` + + @function delay + @within Promise + @param seconds number + @return Promise +]=] +do + -- uses a sorted doubly linked list (queue) to achieve O(1) remove operations and O(n) for insert + + -- the initial node in the linked list + local first + local connection + + function Promise.delay(seconds) + assert(type(seconds) == "number", "Bad argument #1 to Promise.delay, must be a number.") + -- If seconds is -INF, INF, NaN, or less than 1 / 60, assume seconds is 1 / 60. + -- This mirrors the behavior of wait() + if not (seconds >= 1 / 60) or seconds == math.huge then + seconds = 1 / 60 + end + + return Promise._new(debug.traceback(nil, 2), function(resolve, _, onCancel) + local startTime = Promise._getTime() + local endTime = startTime + seconds + + local node = { + resolve = resolve, + startTime = startTime, + endTime = endTime, + } + + if connection == nil then -- first is nil when connection is nil + first = node + connection = Promise._timeEvent:Connect(function() + local threadStart = Promise._getTime() + + while first ~= nil and first.endTime < threadStart do + local current = first + first = current.next + + if first == nil then + connection:Disconnect() + connection = nil + else + first.previous = nil + end + + current.resolve(Promise._getTime() - current.startTime) + end + end) + else -- first is non-nil + if first.endTime < endTime then -- if `node` should be placed after `first` + -- we will insert `node` between `current` and `next` + -- (i.e. after `current` if `next` is nil) + local current = first + local next = current.next + + while next ~= nil and next.endTime < endTime do + current = next + next = current.next + end + + -- `current` must be non-nil, but `next` could be `nil` (i.e. last item in list) + current.next = node + node.previous = current + + if next ~= nil then + node.next = next + next.previous = node + end + else + -- set `node` to `first` + node.next = first + first.previous = node + first = node + end + end + + onCancel(function() + -- remove node from queue + local next = node.next + + if first == node then + if next == nil then -- if `node` is the first and last + connection:Disconnect() + connection = nil + else -- if `node` is `first` and not the last + next.previous = nil + end + first = next + else + local previous = node.previous + -- since `node` is not `first`, then we know `previous` is non-nil + previous.next = next + + if next ~= nil then + next.previous = previous + end + end + end) + end) + end +end + +--[=[ + Returns a new Promise that resolves if the chained Promise resolves within `seconds` seconds, or rejects if execution time exceeds `seconds`. The chained Promise will be cancelled if the timeout is reached. + + Rejects with `rejectionValue` if it is non-nil. If a `rejectionValue` is not given, it will reject with a `Promise.Error(Promise.Error.Kind.TimedOut)`. This can be checked with [[Error.isKind]]. + + ```lua + getSomething():timeout(5):andThen(function(something) + -- got something and it only took at max 5 seconds + end):catch(function(e) + -- Either getting something failed or the time was exceeded. + + if Promise.Error.isKind(e, Promise.Error.Kind.TimedOut) then + warn("Operation timed out!") + else + warn("Operation encountered an error!") + end + end) + ``` + + Sugar for: + + ```lua + Promise.race({ + Promise.delay(seconds):andThen(function() + return Promise.reject( + rejectionValue == nil + and Promise.Error.new({ kind = Promise.Error.Kind.TimedOut }) + or rejectionValue + ) + end), + promise + }) + ``` + + @param seconds number + @param rejectionValue? any -- The value to reject with if the timeout is reached + @return Promise +]=] +function Promise.prototype:timeout(seconds, rejectionValue) + local traceback = debug.traceback(nil, 2) + + return Promise.race({ + Promise.delay(seconds):andThen(function() + return Promise.reject(rejectionValue == nil and Error.new({ + kind = Error.Kind.TimedOut, + error = "Timed out", + context = string.format( + "Timeout of %d seconds exceeded.\n:timeout() called at:\n\n%s", + seconds, + traceback + ), + }) or rejectionValue) + end), + self, + }) +end + +--[=[ + Returns the current Promise status. + + @return Status +]=] +function Promise.prototype:getStatus() + return self._status +end + +--[[ + Creates a new promise that receives the result of this promise. + + The given callbacks are invoked depending on that result. +]] +function Promise.prototype:_andThen(traceback, successHandler, failureHandler) + self._unhandledRejection = false + + -- If we are already cancelled, we return a cancelled Promise + if self._status == Promise.Status.Cancelled then + local promise = Promise.new(function() end) + promise:cancel() + + return promise + end + + -- Create a new promise to follow this part of the chain + return Promise._new(traceback, function(resolve, reject, onCancel) + -- Our default callbacks just pass values onto the next promise. + -- This lets success and failure cascade correctly! + + local successCallback = resolve + if successHandler then + successCallback = createAdvancer(traceback, successHandler, resolve, reject) + end + + local failureCallback = reject + if failureHandler then + failureCallback = createAdvancer(traceback, failureHandler, resolve, reject) + end + + if self._status == Promise.Status.Started then + -- If we haven't resolved yet, put ourselves into the queue + table.insert(self._queuedResolve, successCallback) + table.insert(self._queuedReject, failureCallback) + + onCancel(function() + -- These are guaranteed to exist because the cancellation handler is guaranteed to only + -- be called at most once + if self._status == Promise.Status.Started then + table.remove(self._queuedResolve, table.find(self._queuedResolve, successCallback)) + table.remove(self._queuedReject, table.find(self._queuedReject, failureCallback)) + end + end) + elseif self._status == Promise.Status.Resolved then + -- This promise has already resolved! Trigger success immediately. + successCallback(unpack(self._values, 1, self._valuesLength)) + elseif self._status == Promise.Status.Rejected then + -- This promise died a terrible death! Trigger failure immediately. + failureCallback(unpack(self._values, 1, self._valuesLength)) + end + end, self) +end + +--[=[ + Chains onto an existing Promise and returns a new Promise. + + :::warning + Within the failure handler, you should never assume that the rejection value is a string. Some rejections within the Promise library are represented by [[Error]] objects. If you want to treat it as a string for debugging, you should call `tostring` on it first. + ::: + + You can return a Promise from the success or failure handler and it will be chained onto. + + Calling `andThen` on a cancelled Promise returns a cancelled Promise. + + :::tip + If the Promise returned by `andThen` is cancelled, `successHandler` and `failureHandler` will not run. + + To run code no matter what, use [Promise:finally]. + ::: + + @param successHandler (...: any) -> ...any + @param failureHandler? (...: any) -> ...any + @return Promise<...any> +]=] +function Promise.prototype:andThen(successHandler, failureHandler) + assert(successHandler == nil or isCallable(successHandler), string.format(ERROR_NON_FUNCTION, "Promise:andThen")) + assert(failureHandler == nil or isCallable(failureHandler), string.format(ERROR_NON_FUNCTION, "Promise:andThen")) + + return self:_andThen(debug.traceback(nil, 2), successHandler, failureHandler) +end + +--[=[ + Shorthand for `Promise:andThen(nil, failureHandler)`. + + Returns a Promise that resolves if the `failureHandler` worked without encountering an additional error. + + :::warning + Within the failure handler, you should never assume that the rejection value is a string. Some rejections within the Promise library are represented by [[Error]] objects. If you want to treat it as a string for debugging, you should call `tostring` on it first. + ::: + + Calling `catch` on a cancelled Promise returns a cancelled Promise. + + :::tip + If the Promise returned by `catch` is cancelled, `failureHandler` will not run. + + To run code no matter what, use [Promise:finally]. + ::: + + @param failureHandler (...: any) -> ...any + @return Promise<...any> +]=] +function Promise.prototype:catch(failureHandler) + assert(failureHandler == nil or isCallable(failureHandler), string.format(ERROR_NON_FUNCTION, "Promise:catch")) + return self:_andThen(debug.traceback(nil, 2), nil, failureHandler) +end + +--[=[ + Similar to [Promise.andThen](#andThen), except the return value is the same as the value passed to the handler. In other words, you can insert a `:tap` into a Promise chain without affecting the value that downstream Promises receive. + + ```lua + getTheValue() + :tap(print) + :andThen(function(theValue) + print("Got", theValue, "even though print returns nil!") + end) + ``` + + If you return a Promise from the tap handler callback, its value will be discarded but `tap` will still wait until it resolves before passing the original value through. + + @param tapHandler (...: any) -> ...any + @return Promise<...any> +]=] +function Promise.prototype:tap(tapHandler) + assert(isCallable(tapHandler), string.format(ERROR_NON_FUNCTION, "Promise:tap")) + return self:_andThen(debug.traceback(nil, 2), function(...) + local callbackReturn = tapHandler(...) + + if Promise.is(callbackReturn) then + local length, values = pack(...) + return callbackReturn:andThen(function() + return unpack(values, 1, length) + end) + end + + return ... + end) +end + +--[=[ + Attaches an `andThen` handler to this Promise that calls the given callback with the predefined arguments. The resolved value is discarded. + + ```lua + promise:andThenCall(someFunction, "some", "arguments") + ``` + + This is sugar for + + ```lua + promise:andThen(function() + return someFunction("some", "arguments") + end) + ``` + + @param callback (...: any) -> any + @param ...? any -- Additional arguments which will be passed to `callback` + @return Promise +]=] +function Promise.prototype:andThenCall(callback, ...) + assert(isCallable(callback), string.format(ERROR_NON_FUNCTION, "Promise:andThenCall")) + local length, values = pack(...) + return self:_andThen(debug.traceback(nil, 2), function() + return callback(unpack(values, 1, length)) + end) +end + +--[=[ + Attaches an `andThen` handler to this Promise that discards the resolved value and returns the given value from it. + + ```lua + promise:andThenReturn("some", "values") + ``` + + This is sugar for + + ```lua + promise:andThen(function() + return "some", "values" + end) + ``` + + :::caution + Promises are eager, so if you pass a Promise to `andThenReturn`, it will begin executing before `andThenReturn` is reached in the chain. Likewise, if you pass a Promise created from [[Promise.reject]] into `andThenReturn`, it's possible that this will trigger the unhandled rejection warning. If you need to return a Promise, it's usually best practice to use [[Promise.andThen]]. + ::: + + @param ... any -- Values to return from the function + @return Promise +]=] +function Promise.prototype:andThenReturn(...) + local length, values = pack(...) + return self:_andThen(debug.traceback(nil, 2), function() + return unpack(values, 1, length) + end) +end + +--[=[ + Cancels this promise, preventing the promise from resolving or rejecting. Does not do anything if the promise is already settled. + + Cancellations will propagate upwards and downwards through chained promises. + + Promises will only be cancelled if all of their consumers are also cancelled. This is to say that if you call `andThen` twice on the same promise, and you cancel only one of the child promises, it will not cancel the parent promise until the other child promise is also cancelled. + + ```lua + promise:cancel() + ``` +]=] +function Promise.prototype:cancel() + if self._status ~= Promise.Status.Started then + return + end + + self._status = Promise.Status.Cancelled + + if self._cancellationHook then + self._cancellationHook() + end + + coroutine.close(self._thread) + + if self._parent then + self._parent:_consumerCancelled(self) + end + + for child in pairs(self._consumers) do + child:cancel() + end + + self:_finalize() +end + +--[[ + Used to decrease the number of consumers by 1, and if there are no more, + cancel this promise. +]] +function Promise.prototype:_consumerCancelled(consumer) + if self._status ~= Promise.Status.Started then + return + end + + self._consumers[consumer] = nil + + if next(self._consumers) == nil then + self:cancel() + end +end + +--[[ + Used to set a handler for when the promise resolves, rejects, or is + cancelled. +]] +function Promise.prototype:_finally(traceback, finallyHandler) + self._unhandledRejection = false + + local promise = Promise._new(traceback, function(resolve, reject, onCancel) + local handlerPromise + + onCancel(function() + -- The finally Promise is not a proper consumer of self. We don't care about the resolved value. + -- All we care about is running at the end. Therefore, if self has no other consumers, it's safe to + -- cancel. We don't need to hold out cancelling just because there's a finally handler. + self:_consumerCancelled(self) + + if handlerPromise then + handlerPromise:cancel() + end + end) + + local finallyCallback = resolve + if finallyHandler then + finallyCallback = function(...) + local callbackReturn = finallyHandler(...) + + if Promise.is(callbackReturn) then + handlerPromise = callbackReturn + + callbackReturn + :finally(function(status) + if status ~= Promise.Status.Rejected then + resolve(self) + end + end) + :catch(function(...) + reject(...) + end) + else + resolve(self) + end + end + end + + if self._status == Promise.Status.Started then + -- The promise is not settled, so queue this. + table.insert(self._queuedFinally, finallyCallback) + else + -- The promise already settled or was cancelled, run the callback now. + finallyCallback(self._status) + end + end) + + return promise +end + +--[=[ + Set a handler that will be called regardless of the promise's fate. The handler is called when the promise is + resolved, rejected, *or* cancelled. + + Returns a new Promise that: + - resolves with the same values that this Promise resolves with. + - rejects with the same values that this Promise rejects with. + - is cancelled if this Promise is cancelled. + + If the value you return from the handler is a Promise: + - We wait for the Promise to resolve, but we ultimately discard the resolved value. + - If the returned Promise rejects, the Promise returned from `finally` will reject with the rejected value from the + *returned* promise. + - If the `finally` Promise is cancelled, and you returned a Promise from the handler, we cancel that Promise too. + + Otherwise, the return value from the `finally` handler is entirely discarded. + + :::note Cancellation + As of Promise v4, `Promise:finally` does not count as a consumer of the parent Promise for cancellation purposes. + This means that if all of a Promise's consumers are cancelled and the only remaining callbacks are finally handlers, + the Promise is cancelled and the finally callbacks run then and there. + + Cancellation still propagates through the `finally` Promise though: if you cancel the `finally` Promise, it can cancel + its parent Promise if it had no other consumers. Likewise, if the parent Promise is cancelled, the `finally` Promise + will also be cancelled. + ::: + + ```lua + local thing = createSomething() + + doSomethingWith(thing) + :andThen(function() + print("It worked!") + -- do something.. + end) + :catch(function() + warn("Oh no it failed!") + end) + :finally(function() + -- either way, destroy thing + + thing:Destroy() + end) + + ``` + + @param finallyHandler (status: Status) -> ...any + @return Promise<...any> +]=] +function Promise.prototype:finally(finallyHandler) + assert(finallyHandler == nil or isCallable(finallyHandler), string.format(ERROR_NON_FUNCTION, "Promise:finally")) + return self:_finally(debug.traceback(nil, 2), finallyHandler) +end + +--[=[ + Same as `andThenCall`, except for `finally`. + + Attaches a `finally` handler to this Promise that calls the given callback with the predefined arguments. + + @param callback (...: any) -> any + @param ...? any -- Additional arguments which will be passed to `callback` + @return Promise +]=] +function Promise.prototype:finallyCall(callback, ...) + assert(isCallable(callback), string.format(ERROR_NON_FUNCTION, "Promise:finallyCall")) + local length, values = pack(...) + return self:_finally(debug.traceback(nil, 2), function() + return callback(unpack(values, 1, length)) + end) +end + +--[=[ + Attaches a `finally` handler to this Promise that discards the resolved value and returns the given value from it. + + ```lua + promise:finallyReturn("some", "values") + ``` + + This is sugar for + + ```lua + promise:finally(function() + return "some", "values" + end) + ``` + + @param ... any -- Values to return from the function + @return Promise +]=] +function Promise.prototype:finallyReturn(...) + local length, values = pack(...) + return self:_finally(debug.traceback(nil, 2), function() + return unpack(values, 1, length) + end) +end + +--[=[ + Yields the current thread until the given Promise completes. Returns the Promise's status, followed by the values that the promise resolved or rejected with. + + @yields + @return Status -- The Status representing the fate of the Promise + @return ...any -- The values the Promise resolved or rejected with. +]=] +function Promise.prototype:awaitStatus() + self._unhandledRejection = false + + if self._status == Promise.Status.Started then + local thread = coroutine.running() + + self + :finally(function() + task.spawn(thread) + end) + -- The finally promise can propagate rejections, so we attach a catch handler to prevent the unhandled + -- rejection warning from appearing + :catch( + function() end + ) + + coroutine.yield() + end + + if self._status == Promise.Status.Resolved then + return self._status, unpack(self._values, 1, self._valuesLength) + elseif self._status == Promise.Status.Rejected then + return self._status, unpack(self._values, 1, self._valuesLength) + end + + return self._status +end + +local function awaitHelper(status, ...) + return status == Promise.Status.Resolved, ... +end + +--[=[ + Yields the current thread until the given Promise completes. Returns true if the Promise resolved, followed by the values that the promise resolved or rejected with. + + :::caution + If the Promise gets cancelled, this function will return `false`, which is indistinguishable from a rejection. If you need to differentiate, you should use [[Promise.awaitStatus]] instead. + ::: + + ```lua + local worked, value = getTheValue():await() + + if worked then + print("got", value) + else + warn("it failed") + end + ``` + + @yields + @return boolean -- `true` if the Promise successfully resolved + @return ...any -- The values the Promise resolved or rejected with. +]=] +function Promise.prototype:await() + return awaitHelper(self:awaitStatus()) +end + +local function expectHelper(status, ...) + if status ~= Promise.Status.Resolved then + error((...) == nil and "Expected Promise rejected with no value." or (...), 3) + end + + return ... +end + +--[=[ + Yields the current thread until the given Promise completes. Returns the values that the promise resolved with. + + ```lua + local worked = pcall(function() + print("got", getTheValue():expect()) + end) + + if not worked then + warn("it failed") + end + ``` + + This is essentially sugar for: + + ```lua + select(2, assert(promise:await())) + ``` + + **Errors** if the Promise rejects or gets cancelled. + + @error any -- Errors with the rejection value if this Promise rejects or gets cancelled. + @yields + @return ...any -- The values the Promise resolved with. +]=] +function Promise.prototype:expect() + return expectHelper(self:awaitStatus()) +end + +-- Backwards compatibility +Promise.prototype.awaitValue = Promise.prototype.expect + +--[[ + Intended for use in tests. + + Similar to await(), but instead of yielding if the promise is unresolved, + _unwrap will throw. This indicates an assumption that a promise has + resolved. +]] +function Promise.prototype:_unwrap() + if self._status == Promise.Status.Started then + error("Promise has not resolved or rejected.", 2) + end + + local success = self._status == Promise.Status.Resolved + + return success, unpack(self._values, 1, self._valuesLength) +end + +function Promise.prototype:_resolve(...) + if self._status ~= Promise.Status.Started then + if Promise.is((...)) then + (...):_consumerCancelled(self) + end + return + end + + -- If the resolved value was a Promise, we chain onto it! + if Promise.is((...)) then + -- Without this warning, arguments sometimes mysteriously disappear + if select("#", ...) > 1 then + local message = string.format( + "When returning a Promise from andThen, extra arguments are " .. "discarded! See:\n\n%s", + self._source + ) + warn(message) + end + + local chainedPromise = ... + + local promise = chainedPromise:andThen(function(...) + self:_resolve(...) + end, function(...) + local maybeRuntimeError = chainedPromise._values[1] + + -- Backwards compatibility < v2 + if chainedPromise._error then + maybeRuntimeError = Error.new({ + error = chainedPromise._error, + kind = Error.Kind.ExecutionError, + context = "[No stack trace available as this Promise originated from an older version of the Promise library (< v2)]", + }) + end + + if Error.isKind(maybeRuntimeError, Error.Kind.ExecutionError) then + return self:_reject(maybeRuntimeError:extend({ + error = "This Promise was chained to a Promise that errored.", + trace = "", + context = string.format( + "The Promise at:\n\n%s\n...Rejected because it was chained to the following Promise, which encountered an error:\n", + self._source + ), + })) + end + + self:_reject(...) + end) + + if promise._status == Promise.Status.Cancelled then + self:cancel() + elseif promise._status == Promise.Status.Started then + -- Adopt ourselves into promise for cancellation propagation. + self._parent = promise + promise._consumers[self] = true + end + + return + end + + self._status = Promise.Status.Resolved + self._valuesLength, self._values = pack(...) + + -- We assume that these callbacks will not throw errors. + for _, callback in ipairs(self._queuedResolve) do + coroutine.wrap(callback)(...) + end + + self:_finalize() +end + +function Promise.prototype:_reject(...) + if self._status ~= Promise.Status.Started then + return + end + + self._status = Promise.Status.Rejected + self._valuesLength, self._values = pack(...) + + -- If there are any rejection handlers, call those! + if not isEmpty(self._queuedReject) then + -- We assume that these callbacks will not throw errors. + for _, callback in ipairs(self._queuedReject) do + coroutine.wrap(callback)(...) + end + else + -- At this point, no one was able to observe the error. + -- An error handler might still be attached if the error occurred + -- synchronously. We'll wait one tick, and if there are still no + -- observers, then we should put a message in the console. + + local err = tostring((...)) + + coroutine.wrap(function() + Promise._timeEvent:Wait() + + -- Someone observed the error, hooray! + if not self._unhandledRejection then + return + end + + -- Build a reasonable message + local message = string.format("Unhandled Promise rejection:\n\n%s\n\n%s", err, self._source) + + for _, callback in ipairs(Promise._unhandledRejectionCallbacks) do + task.spawn(callback, self, unpack(self._values, 1, self._valuesLength)) + end + + if Promise.TEST then + -- Don't spam output when we're running tests. + return + end + + warn(message) + end)() + end + + self:_finalize() +end + +--[[ + Calls any :finally handlers. We need this to be a separate method and + queue because we must call all of the finally callbacks upon a success, + failure, *and* cancellation. +]] +function Promise.prototype:_finalize() + for _, callback in ipairs(self._queuedFinally) do + -- Purposefully not passing values to callbacks here, as it could be the + -- resolved values, or rejected errors. If the developer needs the values, + -- they should use :andThen or :catch explicitly. + coroutine.wrap(callback)(self._status) + end + + self._queuedFinally = nil + self._queuedReject = nil + self._queuedResolve = nil + + -- Clear references to other Promises to allow gc + if not Promise.TEST then + self._parent = nil + self._consumers = nil + end + + task.defer(coroutine.close, self._thread) +end + +--[=[ + Chains a Promise from this one that is resolved if this Promise is already resolved, and rejected if it is not resolved at the time of calling `:now()`. This can be used to ensure your `andThen` handler occurs on the same frame as the root Promise execution. + + ```lua + doSomething() + :now() + :andThen(function(value) + print("Got", value, "synchronously.") + end) + ``` + + If this Promise is still running, Rejected, or Cancelled, the Promise returned from `:now()` will reject with the `rejectionValue` if passed, otherwise with a `Promise.Error(Promise.Error.Kind.NotResolvedInTime)`. This can be checked with [[Error.isKind]]. + + @param rejectionValue? any -- The value to reject with if the Promise isn't resolved + @return Promise +]=] +function Promise.prototype:now(rejectionValue) + local traceback = debug.traceback(nil, 2) + if self._status == Promise.Status.Resolved then + return self:_andThen(traceback, function(...) + return ... + end) + else + return Promise.reject(rejectionValue == nil and Error.new({ + kind = Error.Kind.NotResolvedInTime, + error = "This Promise was not resolved in time for :now()", + context = ":now() was called at:\n\n" .. traceback, + }) or rejectionValue) + end +end + +--[=[ + Repeatedly calls a Promise-returning function up to `times` number of times, until the returned Promise resolves. + + If the amount of retries is exceeded, the function will return the latest rejected Promise. + + ```lua + local function canFail(a, b, c) + return Promise.new(function(resolve, reject) + -- do something that can fail + + local failed, thing = doSomethingThatCanFail(a, b, c) + + if failed then + reject("it failed") + else + resolve(thing) + end + end) + end + + local MAX_RETRIES = 10 + local value = Promise.retry(canFail, MAX_RETRIES, "foo", "bar", "baz") -- args to send to canFail + ``` + + @since 3.0.0 + @param callback (...: P) -> Promise + @param times number + @param ...? P + @return Promise +]=] +function Promise.retry(callback, times, ...) + assert(isCallable(callback), "Parameter #1 to Promise.retry must be a function") + assert(type(times) == "number", "Parameter #2 to Promise.retry must be a number") + + local args, length = { ... }, select("#", ...) + + return Promise.resolve(callback(...)):catch(function(...) + if times > 0 then + return Promise.retry(callback, times - 1, unpack(args, 1, length)) + else + return Promise.reject(...) + end + end) +end + +--[=[ + Repeatedly calls a Promise-returning function up to `times` number of times, waiting `seconds` seconds between each + retry, until the returned Promise resolves. + + If the amount of retries is exceeded, the function will return the latest rejected Promise. + + @since v3.2.0 + @param callback (...: P) -> Promise + @param times number + @param seconds number + @param ...? P + @return Promise +]=] +function Promise.retryWithDelay(callback, times, seconds, ...) + assert(isCallable(callback), "Parameter #1 to Promise.retry must be a function") + assert(type(times) == "number", "Parameter #2 (times) to Promise.retry must be a number") + assert(type(seconds) == "number", "Parameter #3 (seconds) to Promise.retry must be a number") + + local args, length = { ... }, select("#", ...) + + return Promise.resolve(callback(...)):catch(function(...) + if times > 0 then + Promise.delay(seconds):await() + + return Promise.retryWithDelay(callback, times - 1, seconds, unpack(args, 1, length)) + else + return Promise.reject(...) + end + end) +end + +--[=[ + Converts an event into a Promise which resolves the next time the event fires. + + The optional `predicate` callback, if passed, will receive the event arguments and should return `true` or `false`, based on if this fired event should resolve the Promise or not. If `true`, the Promise resolves. If `false`, nothing happens and the predicate will be rerun the next time the event fires. + + The Promise will resolve with the event arguments. + + :::tip + This function will work given any object with a `Connect` method. This includes all Roblox events. + ::: + + ```lua + -- Creates a Promise which only resolves when `somePart` is touched + -- by a part named `"Something specific"`. + return Promise.fromEvent(somePart.Touched, function(part) + return part.Name == "Something specific" + end) + ``` + + @since 3.0.0 + @param event Event -- Any object with a `Connect` method. This includes all Roblox events. + @param predicate? (...: P) -> boolean -- A function which determines if the Promise should resolve with the given value, or wait for the next event to check again. + @return Promise

+]=] +function Promise.fromEvent(event, predicate) + predicate = predicate or function() + return true + end + + return Promise._new(debug.traceback(nil, 2), function(resolve, _, onCancel) + local connection + local shouldDisconnect = false + + local function disconnect() + connection:Disconnect() + connection = nil + end + + -- We use shouldDisconnect because if the callback given to Connect is called before + -- Connect returns, connection will still be nil. This happens with events that queue up + -- events when there's nothing connected, such as RemoteEvents + + connection = event:Connect(function(...) + local callbackValue = predicate(...) + + if callbackValue == true then + resolve(...) + + if connection then + disconnect() + else + shouldDisconnect = true + end + elseif type(callbackValue) ~= "boolean" then + error("Promise.fromEvent predicate should always return a boolean") + end + end) + + if shouldDisconnect and connection then + return disconnect() + end + + onCancel(disconnect) + end) +end + +--[=[ + Registers a callback that runs when an unhandled rejection happens. An unhandled rejection happens when a Promise + is rejected, and the rejection is not observed with `:catch`. + + The callback is called with the actual promise that rejected, followed by the rejection values. + + @since v3.2.0 + @param callback (promise: Promise, ...: any) -- A callback that runs when an unhandled rejection happens. + @return () -> () -- Function that unregisters the `callback` when called +]=] +function Promise.onUnhandledRejection(callback) + table.insert(Promise._unhandledRejectionCallbacks, callback) + + return function() + local index = table.find(Promise._unhandledRejectionCallbacks, callback) + + if index then + table.remove(Promise._unhandledRejectionCallbacks, index) + end + end +end + +return Promise diff --git a/include/RuntimeLib.lua b/include/RuntimeLib.lua new file mode 100644 index 0000000..ce51044 --- /dev/null +++ b/include/RuntimeLib.lua @@ -0,0 +1,231 @@ +local Promise = require(script.Parent.Promise) + +local RunService = game:GetService("RunService") + +local OUTPUT_PREFIX = "roblox-ts: " +local NODE_MODULES = "node_modules" +local DEFAULT_SCOPE = "@rbxts" + +local TS = {} + +TS.Promise = Promise + +local function isPlugin(context) + return RunService:IsStudio() and context:FindFirstAncestorWhichIsA("Plugin") ~= nil +end + +function TS.getModule(context, scope, moduleName) + -- legacy call signature + if moduleName == nil then + moduleName = scope + scope = DEFAULT_SCOPE + end + + -- ensure modules have fully replicated + if RunService:IsRunning() and RunService:IsClient() and not isPlugin(context) and not game:IsLoaded() then + game.Loaded:Wait() + end + + local object = context + repeat + local nodeModulesFolder = object:FindFirstChild(NODE_MODULES) + if nodeModulesFolder then + local scopeFolder = nodeModulesFolder:FindFirstChild(scope) + if scopeFolder then + local module = scopeFolder:FindFirstChild(moduleName) + if module then + return module + end + end + end + object = object.Parent + until object == nil + + error(OUTPUT_PREFIX .. "Could not find module: " .. moduleName, 2) +end + +-- This is a hash which TS.import uses as a kind of linked-list-like history of [Script who Loaded] -> Library +local currentlyLoading = {} +local registeredLibraries = {} + +function TS.import(context, module, ...) + for i = 1, select("#", ...) do + module = module:WaitForChild((select(i, ...))) + end + + if module.ClassName ~= "ModuleScript" then + error(OUTPUT_PREFIX .. "Failed to import! Expected ModuleScript, got " .. module.ClassName, 2) + end + + currentlyLoading[context] = module + + -- Check to see if a case like this occurs: + -- module -> Module1 -> Module2 -> module + + -- WHERE currentlyLoading[module] is Module1 + -- and currentlyLoading[Module1] is Module2 + -- and currentlyLoading[Module2] is module + + local currentModule = module + local depth = 0 + + while currentModule do + depth = depth + 1 + currentModule = currentlyLoading[currentModule] + + if currentModule == module then + local str = currentModule.Name -- Get the string traceback + + for _ = 1, depth do + currentModule = currentlyLoading[currentModule] + str = str .. " ⇒ " .. currentModule.Name + end + + error(OUTPUT_PREFIX .. "Failed to import! Detected a circular dependency chain: " .. str, 2) + end + end + + if not registeredLibraries[module] then + if _G[module] then + error( + OUTPUT_PREFIX + .. "Invalid module access! Do you have multiple TS runtimes trying to import this? " + .. module:GetFullName(), + 2 + ) + end + + _G[module] = TS + registeredLibraries[module] = true -- register as already loaded for subsequent calls + end + + local data = require(module) + + if currentlyLoading[context] == module then -- Thread-safe cleanup! + currentlyLoading[context] = nil + end + + return data +end + +function TS.instanceof(obj, class) + -- custom Class.instanceof() check + if type(class) == "table" and type(class.instanceof) == "function" then + return class.instanceof(obj) + end + + -- metatable check + if type(obj) == "table" then + obj = getmetatable(obj) + while obj ~= nil do + if obj == class then + return true + end + local mt = getmetatable(obj) + if mt then + obj = mt.__index + else + obj = nil + end + end + end + + return false +end + +function TS.async(callback) + return function(...) + local n = select("#", ...) + local args = { ... } + return Promise.new(function(resolve, reject) + coroutine.wrap(function() + local ok, result = pcall(callback, unpack(args, 1, n)) + if ok then + resolve(result) + else + reject(result) + end + end)() + end) + end +end + +function TS.await(promise) + if not Promise.is(promise) then + return promise + end + + local status, value = promise:awaitStatus() + if status == Promise.Status.Resolved then + return value + elseif status == Promise.Status.Rejected then + error(value, 2) + else + error("The awaited Promise was cancelled", 2) + end +end + +local SIGN = 2 ^ 31 +local COMPLEMENT = 2 ^ 32 +local function bit_sign(num) + -- Restores the sign after an unsigned conversion according to 2s complement. + if bit32.btest(num, SIGN) then + return num - COMPLEMENT + else + return num + end +end + +function TS.bit_lrsh(a, b) + return bit_sign(bit32.arshift(a, b)) +end + +TS.TRY_RETURN = 1 +TS.TRY_BREAK = 2 +TS.TRY_CONTINUE = 3 + +function TS.try(func, catch, finally) + local err, traceback + local success, exitType, returns = xpcall( + func, + function(errInner) + err = errInner + traceback = debug.traceback() + end + ) + if not success and catch then + local newExitType, newReturns = catch(err, traceback) + if newExitType then + exitType, returns = newExitType, newReturns + end + end + if finally then + local newExitType, newReturns = finally() + if newExitType then + exitType, returns = newExitType, newReturns + end + end + return exitType, returns +end + +function TS.generator(callback) + local co = coroutine.create(callback) + return { + next = function(...) + if coroutine.status(co) == "dead" then + return { done = true } + else + local success, value = coroutine.resume(co, ...) + if success == false then + error(value, 2) + end + return { + value = value, + done = coroutine.status(co) == "dead", + } + end + end, + } +end + +return TS diff --git a/input/rlog.api.json b/input/rlog.api.json new file mode 100644 index 0000000..3082556 --- /dev/null +++ b/input/rlog.api.json @@ -0,0 +1,2734 @@ +{ + "metadata": { + "toolPackage": "@microsoft/api-extractor", + "toolVersion": "7.47.5", + "schemaVersion": 1011, + "oldestForwardsCompatibleVersion": 1001, + "tsdocConfig": { + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "noStandardTags": true, + "tagDefinitions": [ + { + "tagName": "@alpha", + "syntaxKind": "modifier" + }, + { + "tagName": "@beta", + "syntaxKind": "modifier" + }, + { + "tagName": "@defaultValue", + "syntaxKind": "block" + }, + { + "tagName": "@decorator", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@deprecated", + "syntaxKind": "block" + }, + { + "tagName": "@eventProperty", + "syntaxKind": "modifier" + }, + { + "tagName": "@example", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@experimental", + "syntaxKind": "modifier" + }, + { + "tagName": "@inheritDoc", + "syntaxKind": "inline" + }, + { + "tagName": "@internal", + "syntaxKind": "modifier" + }, + { + "tagName": "@label", + "syntaxKind": "inline" + }, + { + "tagName": "@link", + "syntaxKind": "inline", + "allowMultiple": true + }, + { + "tagName": "@override", + "syntaxKind": "modifier" + }, + { + "tagName": "@packageDocumentation", + "syntaxKind": "modifier" + }, + { + "tagName": "@param", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@privateRemarks", + "syntaxKind": "block" + }, + { + "tagName": "@public", + "syntaxKind": "modifier" + }, + { + "tagName": "@readonly", + "syntaxKind": "modifier" + }, + { + "tagName": "@remarks", + "syntaxKind": "block" + }, + { + "tagName": "@returns", + "syntaxKind": "block" + }, + { + "tagName": "@sealed", + "syntaxKind": "modifier" + }, + { + "tagName": "@see", + "syntaxKind": "block" + }, + { + "tagName": "@throws", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@typeParam", + "syntaxKind": "block", + "allowMultiple": true + }, + { + "tagName": "@virtual", + "syntaxKind": "modifier" + }, + { + "tagName": "@betaDocumentation", + "syntaxKind": "modifier" + }, + { + "tagName": "@internalRemarks", + "syntaxKind": "block" + }, + { + "tagName": "@preapproved", + "syntaxKind": "modifier" + } + ], + "supportForTags": { + "@alpha": true, + "@beta": true, + "@defaultValue": true, + "@decorator": true, + "@deprecated": true, + "@eventProperty": true, + "@example": true, + "@experimental": true, + "@inheritDoc": true, + "@internal": true, + "@label": true, + "@link": true, + "@override": true, + "@packageDocumentation": true, + "@param": true, + "@privateRemarks": true, + "@public": true, + "@readonly": true, + "@remarks": true, + "@returns": true, + "@sealed": true, + "@see": true, + "@throws": true, + "@typeParam": true, + "@virtual": true, + "@betaDocumentation": true, + "@internalRemarks": true, + "@preapproved": true + }, + "reportUnsupportedHtmlElements": false + } + }, + "kind": "Package", + "canonicalReference": "@rbxts/rlog!", + "docComment": "/**\n * Metadata based logging framework for ROBLOX projects.\n *\n * @remarks\n *\n * `rlog` exports the {@link RLog} class as the primary entry point.\n *\n * @packageDocumentation\n */\n", + "name": "@rbxts/rlog", + "preserveMemberOrder": false, + "members": [ + { + "kind": "EntryPoint", + "canonicalReference": "@rbxts/rlog!", + "name": "", + "preserveMemberOrder": false, + "members": [ + { + "kind": "Enum", + "canonicalReference": "@rbxts/rlog!EncodingType:enum", + "docComment": "/**\n * Enum representing the types of encoding strategies.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare enum EncodingType " + } + ], + "fileUrlPath": "src/configuration/index.ts", + "releaseTag": "Public", + "name": "EncodingType", + "preserveMemberOrder": false, + "members": [ + { + "kind": "EnumMember", + "canonicalReference": "@rbxts/rlog!EncodingType.DEEP:member", + "docComment": "/**\n * Deep encoding strategy that processes elements thoroughly.\n *\n * More specifically, this will ensure all data is properly encoded and accounted for; inspecting the individual type of each property in a provided object.\n *\n * @see\n *\n * {@link EncodingType.FAST}\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "DEEP = " + }, + { + "kind": "Content", + "text": "0" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "DEEP" + }, + { + "kind": "EnumMember", + "canonicalReference": "@rbxts/rlog!EncodingType.FAST:member", + "docComment": "/**\n * Fast encoding strategy that focuses on speed.\n *\n * More specifically, this will just try to encode all data to a JSON string or using `tostring` if encoding to a JSON string fails.\n *\n * So nested types (or roblox datatypes) will not be properly encoded.\n *\n * Useful if you're not logging any complex data, and want to avoid extra runtime overhead.\n *\n * @see\n *\n * {@link EncodingType.DEEP}\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "FAST = " + }, + { + "kind": "Content", + "text": "1" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "FAST" + } + ] + }, + { + "kind": "TypeAlias", + "canonicalReference": "@rbxts/rlog!LogData:type", + "docComment": "/**\n * Type representing the additional data associated with a log entry.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type LogData = " + }, + { + "kind": "Reference", + "text": "Record", + "canonicalReference": "!Record:type" + }, + { + "kind": "Content", + "text": "" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "src/common/index.ts", + "releaseTag": "Public", + "name": "LogData", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 3 + } + }, + { + "kind": "TypeAlias", + "canonicalReference": "@rbxts/rlog!LogEnricherCallback:type", + "docComment": "/**\n * Type representing a callback function for enriching log entries, or an \"enricher\".\n *\n * Enrichers optionally mutate {@link LogEntry}s. You can add data to a {@link LogEntry}, edit its {@link LogEntry.metadata | metadata}, or just return it if you don't need to do anything.\n *\n * To learn more about enrichers, and how they work, see {@link RLog.withEnricher | withEnricher}.\n *\n * @param entry - The log entry to enrich.\n *\n * @param config - The configuration used for logging.\n *\n * @returns The enriched log entry.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type LogEnricherCallback = " + }, + { + "kind": "Content", + "text": "(entry: " + }, + { + "kind": "Reference", + "text": "LogEntry", + "canonicalReference": "@rbxts/rlog!LogEntry:type" + }, + { + "kind": "Content", + "text": ", config: " + }, + { + "kind": "Reference", + "text": "RLogConfig", + "canonicalReference": "@rbxts/rlog!RLogConfig:type" + }, + { + "kind": "Content", + "text": ") => " + }, + { + "kind": "Reference", + "text": "LogEntry", + "canonicalReference": "@rbxts/rlog!LogEntry:type" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "src/common/index.ts", + "releaseTag": "Public", + "name": "LogEnricherCallback", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 7 + } + }, + { + "kind": "TypeAlias", + "canonicalReference": "@rbxts/rlog!LogEntry:type", + "docComment": "/**\n * A single logging event.\n *\n * Each message has its own instance of this, with relevant data attached.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type LogEntry = " + }, + { + "kind": "Content", + "text": "{\n level: " + }, + { + "kind": "Reference", + "text": "LogLevel", + "canonicalReference": "@rbxts/rlog!LogLevel:enum" + }, + { + "kind": "Content", + "text": ";\n message: string;\n data: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": ";\n metadata: " + }, + { + "kind": "Reference", + "text": "LogMetadata", + "canonicalReference": "@rbxts/rlog!LogMetadata:type" + }, + { + "kind": "Content", + "text": ";\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "src/common/index.ts", + "releaseTag": "Public", + "name": "LogEntry", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 8 + } + }, + { + "kind": "Enum", + "canonicalReference": "@rbxts/rlog!LogLevel:enum", + "docComment": "/**\n * Enum representing the various log levels, or \"importance\" of a {@link LogEntry}.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare enum LogLevel " + } + ], + "fileUrlPath": "src/common/index.ts", + "releaseTag": "Public", + "name": "LogLevel", + "preserveMemberOrder": false, + "members": [ + { + "kind": "EnumMember", + "canonicalReference": "@rbxts/rlog!LogLevel.DEBUG:member", + "docComment": "/**\n * The second lowest level of logging.\n *\n * Generally used for messages that you don't necessarily need to see at runtime, but they're useful when you need to find out why something is happening.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "DEBUG = " + }, + { + "kind": "Content", + "text": "1" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "DEBUG" + }, + { + "kind": "EnumMember", + "canonicalReference": "@rbxts/rlog!LogLevel.ERROR:member", + "docComment": "/**\n * The highest level of logging.\n *\n * Used to indicate issues or exceptions that broke the application, and need to be fixed.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "ERROR = " + }, + { + "kind": "Content", + "text": "4" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "ERROR" + }, + { + "kind": "EnumMember", + "canonicalReference": "@rbxts/rlog!LogLevel.INFO:member", + "docComment": "/**\n * The baseline level of logging.\n *\n * Useful for messages that signify an event or interaction. Usually occur only once or twice in a control flow, and are used less for debugging, and more for seeing what's going on in your application.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "INFO = " + }, + { + "kind": "Content", + "text": "2" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "INFO" + }, + { + "kind": "EnumMember", + "canonicalReference": "@rbxts/rlog!LogLevel.VERBOSE:member", + "docComment": "/**\n * The lowest level of logging.\n *\n * Verbose messages are those that are not usually useful unless you need to see deep step-by-step processes in your application.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "VERBOSE = " + }, + { + "kind": "Content", + "text": "0" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "VERBOSE" + }, + { + "kind": "EnumMember", + "canonicalReference": "@rbxts/rlog!LogLevel.WARNING:member", + "docComment": "/**\n * Not as bad as an {@link LogLevel.ERROR | ERROR}, but something that you should be looked at.\n *\n * Useful for situations where something isn't necessarily breaking, but it's behaving in a way that isn't desired.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "WARNING = " + }, + { + "kind": "Content", + "text": "3" + } + ], + "initializerTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "name": "WARNING" + } + ] + }, + { + "kind": "TypeAlias", + "canonicalReference": "@rbxts/rlog!LogMetadata:type", + "docComment": "/**\n * Metadata associated with a log entry.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type LogMetadata = " + }, + { + "kind": "Content", + "text": "{\n timestamp: number;\n correlation_id?: string;\n tag?: string;\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "src/common/index.ts", + "releaseTag": "Public", + "name": "LogMetadata", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "TypeAlias", + "canonicalReference": "@rbxts/rlog!LogSinkCallback:type", + "docComment": "/**\n * Type representing a callback function for consuming log entries, or a \"sink\".\n *\n * Sinks optionally consume {@link LogEntry}s. If you return `true`, then the log will be stopped, and no further sinks will be called. The {@link LogEntry} will also not be logged to the console.\n *\n * To learn more about sinks, and how they work, see {@link RLog.withSink | withSink}.\n *\n * @param entry - The log entry to handle.\n *\n * @param config - The configuration used for logging.\n *\n * @returns A boolean indicating whether the log was consumed, or void.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type LogSinkCallback = " + }, + { + "kind": "Content", + "text": "(entry: " + }, + { + "kind": "Reference", + "text": "LogEntry", + "canonicalReference": "@rbxts/rlog!LogEntry:type" + }, + { + "kind": "Content", + "text": ", config: " + }, + { + "kind": "Reference", + "text": "RLogConfig", + "canonicalReference": "@rbxts/rlog!RLogConfig:type" + }, + { + "kind": "Content", + "text": ") => boolean | void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "src/common/index.ts", + "releaseTag": "Public", + "name": "LogSinkCallback", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 6 + } + }, + { + "kind": "TypeAlias", + "canonicalReference": "@rbxts/rlog!PartialRLogConfig:type", + "docComment": "/**\n * Version of {@link RLogConfig} that allows all data to be absent.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type PartialRLogConfig = " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": "<" + }, + { + "kind": "Reference", + "text": "ExcludeMembers", + "canonicalReference": "!ExcludeMembers:type" + }, + { + "kind": "Content", + "text": "<" + }, + { + "kind": "Reference", + "text": "RLogConfig", + "canonicalReference": "@rbxts/rlog!RLogConfig:type" + }, + { + "kind": "Content", + "text": ", " + }, + { + "kind": "Reference", + "text": "SerializationConfig", + "canonicalReference": "@rbxts/rlog!SerializationConfig:type" + }, + { + "kind": "Content", + "text": ">> & {\n readonly serialization?: " + }, + { + "kind": "Reference", + "text": "Partial", + "canonicalReference": "!Partial:type" + }, + { + "kind": "Content", + "text": "<" + }, + { + "kind": "Reference", + "text": "SerializationConfig", + "canonicalReference": "@rbxts/rlog!SerializationConfig:type" + }, + { + "kind": "Content", + "text": ">;\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "src/configuration/index.ts", + "releaseTag": "Public", + "name": "PartialRLogConfig", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 13 + } + }, + { + "kind": "Class", + "canonicalReference": "@rbxts/rlog!RLog:class", + "docComment": "/**\n * Class for faciliating Roblox Logging.\n *\n * You can also use {@link rlog} or {@link rLog}- for style purposes.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export declare class RLog " + } + ], + "fileUrlPath": "src/rlog.ts", + "releaseTag": "Public", + "isAbstract": false, + "name": "RLog", + "preserveMemberOrder": false, + "members": [ + { + "kind": "Constructor", + "canonicalReference": "@rbxts/rlog!RLog:constructor(1)", + "docComment": "/**\n * Constructs a new {@link RLog} instance.\n *\n * Uses the provided table in place of the argument names.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "constructor({ config, tag, parent, sinks, enrichers, correlation_id }: " + }, + { + "kind": "Reference", + "text": "RLogConstructorParameters", + "canonicalReference": "@rbxts/rlog!RLogConstructorParameters:type" + }, + { + "kind": "Content", + "text": ");" + } + ], + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "{ config, tag, parent, sinks, enrichers, correlation_id }", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + } + ] + }, + { + "kind": "Constructor", + "canonicalReference": "@rbxts/rlog!RLog:constructor(2)", + "docComment": "/**\n * Constructs a new {@link RLog} instance.\n *\n * @param config - Configuration settings to use for this logger instance.\n *\n * @param tag - Optional tag for this logger instance.\n *\n * @param parent - Optional parent logger instance.\n *\n * @param sinks - Optional array of sink callbacks.\n *\n * @param enrichers - Optional array of enricher callbacks.\n *\n * @param correlation_id - Optional correlation ID.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "constructor(config?: " + }, + { + "kind": "Reference", + "text": "PartialRLogConfig", + "canonicalReference": "@rbxts/rlog!PartialRLogConfig:type" + }, + { + "kind": "Content", + "text": ", tag?: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", parent?: " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ", sinks?: " + }, + { + "kind": "Reference", + "text": "LogSinkCallback", + "canonicalReference": "@rbxts/rlog!LogSinkCallback:type" + }, + { + "kind": "Content", + "text": "[]" + }, + { + "kind": "Content", + "text": ", enrichers?: " + }, + { + "kind": "Reference", + "text": "LogEnricherCallback", + "canonicalReference": "@rbxts/rlog!LogEnricherCallback:type" + }, + { + "kind": "Content", + "text": "[]" + }, + { + "kind": "Content", + "text": ", correlation_id?: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ");" + } + ], + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 2, + "parameters": [ + { + "parameterName": "config", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": true + }, + { + "parameterName": "tag", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + }, + { + "parameterName": "parent", + "parameterTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "isOptional": true + }, + { + "parameterName": "sinks", + "parameterTypeTokenRange": { + "startIndex": 7, + "endIndex": 9 + }, + "isOptional": true + }, + { + "parameterName": "enrichers", + "parameterTypeTokenRange": { + "startIndex": 10, + "endIndex": 12 + }, + "isOptional": true + }, + { + "parameterName": "correlation_id", + "parameterTypeTokenRange": { + "startIndex": 13, + "endIndex": 14 + }, + "isOptional": true + } + ] + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#child:member(1)", + "docComment": "/**\n * Creates a child logger with an optional correlation ID.\n *\n * There are two components at play here: correlation ids, and child loggers.\n *\n * #### Correlation IDs\n *\n * Correlation IDs are a way to keep track of logging events that occur in a single \"flow\" or \"logical process\". For example, you could create a child logger for a function:\n * ```ts\n * function buyPet(player: Player, pet: PetId) {\n * const logger = rLog.default.child();\n * logger.v(\"Player is purchasing a pet\", { player: player, pet: pet });\n *\n * // ... buy pet\n *\n * logger.d(\"Player pet bought\");\n * }\n *\n * buyPet(Players.LocalPlayer, \"1\");\n * // > [VERBOSE]: Player is purchasing a pet\n * // > { \"correlation_id\": \"adss8fd_1318za_112\", \"data\": { \"player\": 1333, \"pet\": \"1\" } }\n * // >\n * // > [DEBUG]: Player pet bought\n * // > { \"correlation_id\": \"adss8fd_1318za_112\" }\n * ```\n *\n * Correlation IDs can be used to track the flow of a function call. This is especially useful in client to server remote calls, where you want each call to be associated with its own logs.\n *\n * This also helps in preventing the need to re-log data, as you can filter for the correlation id to find the relevant data.\n *\n * #### Child Loggers\n *\n * The relationship between a parent and child logger comes with two benefits:\n *\n * ##### Shared Correlation IDs\n *\n * The child logger will (by default) inherit the correlation id of the parent.\n *\n * If you provide your own `correlation_id`, it will override the child's.\n *\n * If you don't provide one, and the parent doesn't have one, a new will be generated.\n *\n * Although, this behavior can be disabled with the {@link RLogConfig | autoGenerateCorrelation} setting.\n *\n * ##### Shared Sinks and Enrichers\n *\n * A child logger has its own sinks and enrichers, meaning you can attach sinks and enrichers to only the child logger without affecting the parent.\n *\n * But after a child logger has called its own enrichers (if any), it will then call the parent's.\n *\n * It will repeat this process with sinks.\n *\n * ##### Usage\n *\n * Child loggers are especially useful when tracking the control flow across multiple functions:\n * ```\n * import { PurchaseHandler } from \"./purchaseHandler\";\n *\n * const Logger = new rLog(settings, \"Actions\");\n *\n * function buyPet(player: Player, pet: PetId) {\n * const logger = Logger.child();\n * logger.v(\"Player is purchasing a pet\", { player: player, pet: pet });\n *\n * PurchaseHandler.processPet(logger, player, pet);\n *\n * logger.d(\"Player pet bought\");\n * }\n *\n * buyPet(Players.LocalPlayer, \"1\");\n * // > [VERBOSE]: Actions -> Player is purchasing a pet\n * // > { \"correlation_id\": \"adss8fd_1318za_112\", \"data\": { \"player\": 1333, \"pet\": \"1\" } }\n * // >\n * // > [VERBOSE]: PurchaseHandler -> Processing a pet purchase\n * // > { \"correlation_id\": \"adss8fd_1318za_112\", \"data\": { \"player\": 1333, \"pet\": \"1\" } }\n * // >\n * // > [DEBUG]: PurchaseHandler -> Pet purchase processed\n * // > { \"correlation_id\": \"adss8fd_1318za_112\" }\n * // >\n * // > [DEBUG]: Actions -> Player pet bought\n * // > { \"correlation_id\": \"adss8fd_1318za_112\" }\n * ```\n *\n * @param correlation_id - Optional Correlation ID for tracking. Defaults to the current `correlation_id`, if any.\n *\n * @returns The new {@link RLog} instance.\n *\n * @see\n *\n * {@link RLog.childWithTag | childWithTag}\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "child(correlation_id?: " + }, + { + "kind": "Content", + "text": "string | undefined" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "correlation_id", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "child" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#childWithTag:member(1)", + "docComment": "/**\n * Creates a child logger with a specific tag and optional correlation ID.\n *\n * Alternative version of {@link RLog.child | child} that allows you to specify a unique `tag` for the child instance.\n *\n * _Note that child loggers do not inherit their parent's tag unless you call this method._\n *\n * @param tag - The tag for the child logger. Defaults to the calling instance's `tag`, if any.\n *\n * @param correlation_id - Optional correlation ID. Defaults to the calling instance's `correlation_id`, if any.\n *\n * @returns The new {@link RLog} instance.\n *\n * @example\n * ```ts\n * const Logger = new rLog(settings);\n *\n * function processPurchase(parent: RLog, player: Player, pet: PetId) {\n * const logger = parent.childWithTag(\"processPurchase\")\n *\n * logger.v(\"Processing a pet purchase\", { player: player, pet: pet });\n *\n * // ...\n *\n * logger.d(\"Pet purchase processed\")\n * }\n *\n * function buyPet(parent: RLog, player: Player, pet: PetId) {\n * const logger = parent.childWithTag(\"buyPet\");\n *\n * logger.v(\"Player is purchasing a pet\", { player: player, pet: pet });\n *\n * processPurchase(logger, player, pet);\n *\n * logger.d(\"Player pet bought\");\n * }\n *\n * buyPet(Logger, Players.LocalPlayer, \"1\");\n * // > [VERBOSE]: buyPet -> Player is purchasing a pet\n * // > { \"correlation_id\": \"adss8fd_1318za_112\", \"data\": { \"player\": 1333, \"pet\": \"1\" } }\n * // >\n * // > [VERBOSE]: processPurchase -> Processing a pet purchase\n * // > { \"correlation_id\": \"adss8fd_1318za_112\", \"data\": { \"player\": 1333, \"pet\": \"1\" } }\n * // >\n * // > [DEBUG]: processPurchase -> Pet purchase processed\n * // > { \"correlation_id\": \"adss8fd_1318za_112\" }\n * // >\n * // > [DEBUG]: buyPet -> Player pet bought\n * // > { \"correlation_id\": \"adss8fd_1318za_112\" }\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "childWithTag(tag?: " + }, + { + "kind": "Content", + "text": "string | undefined" + }, + { + "kind": "Content", + "text": ", correlation_id?: " + }, + { + "kind": "Content", + "text": "string | undefined" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "tag", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": true + }, + { + "parameterName": "correlation_id", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "childWithTag" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#clone:member(1)", + "docComment": "/**\n * Creates a new {@link RLog} instance with all the same settings and properties.\n *\n * Everything is deep copied, so any mutations to the original will safely not replicate.\n *\n * @returns A duplicate of this {@link RLog} instance.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "clone(): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [], + "isOptional": false, + "isAbstract": false, + "name": "clone" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#clone:member(2)", + "docComment": "/**\n * Creates a new {@link RLog} instance with all the same settings and properties.\n *\n * The provided {@link RLogConstructorParameters | parameters} will be merged with the existing parameters on this instance.\n *\n * Everything is deep copied, so any mutations to the original will safely not replicate.\n *\n * @returns A duplicate of this {@link RLog} instance.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "clone({ config, tag, parent, sinks, enrichers, correlation_id }: " + }, + { + "kind": "Reference", + "text": "RLogConstructorParameters", + "canonicalReference": "@rbxts/rlog!RLogConstructorParameters:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 2, + "parameters": [ + { + "parameterName": "{ config, tag, parent, sinks, enrichers, correlation_id }", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + } + ], + "isOptional": false, + "isAbstract": false, + "name": "clone" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#d:member(1)", + "docComment": "/**\n * Shorthand version of {@link RLog.debug | debug}.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "d(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "d" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#debug:member(1)", + "docComment": "/**\n * Logs a debug message.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n *\n * @see\n *\n * {@link RLog.d | d}\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "debug(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "debug" + }, + { + "kind": "Property", + "canonicalReference": "@rbxts/rlog!RLog.default:member", + "docComment": "/**\n * The default or \"global\" {@link RLog} instance.\n *\n * All loggers inherit from this, so it's a convenient way for attaching global sinks or enrichers.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "static readonly default: " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isReadonly": true, + "isOptional": false, + "releaseTag": "Public", + "name": "default", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isStatic": true, + "isProtected": false, + "isAbstract": false + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#e:member(1)", + "docComment": "/**\n * Shorthand version of {@link RLog.error | error}.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "e(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "e" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#error:member(1)", + "docComment": "/**\n * Logs an error message.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n *\n * @see\n *\n * {@link RLog.e | e}\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "error(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "error" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#i:member(1)", + "docComment": "/**\n * Shorthand version of {@link RLog.info | info}.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "i(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "i" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#info:member(1)", + "docComment": "/**\n * Logs an informational message.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n *\n * @see\n *\n * {@link RLog.i | i}\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "info(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "info" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#log:member(1)", + "docComment": "/**\n * Logs a message with a specified log level.\n *\n * @param level - The log level.\n *\n * @param message - The log message.\n *\n * @param data - Optional data to log. Will be encoded according to this logger's {@link RLogConfig | config}.\n *\n * @see\n *\n * {@link RLog.verbose | verbose}, {@link RLog.debug | debug}, {@link RLog.info | info}, {@link RLog.warning | warning}, {@link RLog.error | error}\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "log(level: " + }, + { + "kind": "Reference", + "text": "LogLevel", + "canonicalReference": "@rbxts/rlog!LogLevel:enum" + }, + { + "kind": "Content", + "text": ", message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 7, + "endIndex": 8 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "level", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "log" + }, + { + "kind": "Property", + "canonicalReference": "@rbxts/rlog!RLog#parent:member", + "docComment": "/**\n * The parent {@link RLog} of this instance.\n *\n * See {@link RLog.child | child} for more details on parent and child instances.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "readonly parent: " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": " | undefined" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isReadonly": true, + "isOptional": false, + "releaseTag": "Public", + "name": "parent", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 3 + }, + "isStatic": false, + "isProtected": false, + "isAbstract": false + }, + { + "kind": "Property", + "canonicalReference": "@rbxts/rlog!RLog#path:member", + "docComment": "/**\n * The full path of this {@link RLog}.\n *\n * A {@link RLog} path is a concatenation of names (tags) of all its parent instances, with the root being `DEFAULT`.\n *\n * In other words, its the hierarchy of the instance.\n *\n * Instances without a tag are referred to as anonymous instances, and as such are labeled as ``.\n *\n * @example\n * ```\n * const main = new RLog().withTag(\"main\");\n * const secondary = main.childWithTag(\"secondary\");\n * const anonymous = secondary.child();\n *\n * print(main.path);\n * print(secondary.path);\n * print(anonymous.path);\n * // > DEFAULT.main\n * // > DEFAULT.main.secondary\n * // > DEFAULT.main.secondary.\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "readonly path: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isReadonly": true, + "isOptional": false, + "releaseTag": "Public", + "name": "path", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isStatic": false, + "isProtected": false, + "isAbstract": false + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog.SetDefaultConfig:member(1)", + "docComment": "/**\n * Sets the config for the {@link RLog.default | default} instance.\n *\n * Since all {@link RLog} instances inherit their config from the default instance, this is a convenient way to provide default configuration settings.\n *\n * _Note that this will **not** change the config for instances already created._\n *\n * @param config - The {@link RLogConfig} to use.\n *\n * @example\n * ```ts\n * RLog.SetDefaultConfig({ { serialization: { encodeFunctions: true } } });\n *\n * // Inherits the `encodeFunctions` setting automatically\n * const logger = new RLog({ serialization: { encodeRobloxTypes: false } });\n *\n * logger.i(\"Player died\", { player: player, location: player.Position, revive: () => {} });\n * // > [INFO]: Player died\n * // > { \"data\": { \"player\": 1338, \"location\": \"\", \"revive\": \"\" } }\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "static SetDefaultConfig(config: " + }, + { + "kind": "Reference", + "text": "PartialRLogConfig", + "canonicalReference": "@rbxts/rlog!PartialRLogConfig:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": true, + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "config", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + } + ], + "isOptional": false, + "isAbstract": false, + "name": "SetDefaultConfig" + }, + { + "kind": "Property", + "canonicalReference": "@rbxts/rlog!RLog#tag:member", + "docComment": "/**\n * The tag of this {@link RLog} instance.\n *\n * Tags are used for filtering logs.\n *\n * See {@link RLog.withTag | withTag} for more details.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "readonly tag: " + }, + { + "kind": "Content", + "text": "string | undefined" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isReadonly": true, + "isOptional": false, + "releaseTag": "Public", + "name": "tag", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isStatic": false, + "isProtected": false, + "isAbstract": false + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#v:member(1)", + "docComment": "/**\n * Shorthand version of {@link RLog.verbose | verbose}.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "v(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "v" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#verbose:member(1)", + "docComment": "/**\n * Logs a verbose message.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n *\n * @see\n *\n * {@link RLog.v | v}\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "verbose(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "verbose" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#w:member(1)", + "docComment": "/**\n * Shorthand version of {@link RLog.warning | warning}.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "w(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "w" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#warn:member(1)", + "docComment": "/**\n * Shorthand version of {@link RLog.warning | warning}.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "warn(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "warn" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#warning:member(1)", + "docComment": "/**\n * Logs a warning message.\n *\n * @param message - The message to log.\n *\n * @param data - Optional data to log.\n *\n * @see\n *\n * {@link RLog.w | w}, {@link RLog.warn | warn}\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "warning(message: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", data?: " + }, + { + "kind": "Reference", + "text": "LogData", + "canonicalReference": "@rbxts/rlog!LogData:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Content", + "text": "void" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "message", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "data", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "warning" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#withConfig:member(1)", + "docComment": "/**\n * Returns a new {@link RLog} with the config merged with the existing config.\n *\n * You can use this to toggle certain features on {@link RLog.child | child} instances, or conditionally apply certain configurations.\n *\n * @param config - Configuration settings to apply to the new instance.\n *\n * @returns The new {@link RLog} instance\n *\n * @example\n * ```ts\n * let logger = new RLog({ minLogLevel: LogLevel.DEBUG });\n *\n * const data = { position: new Vector2(5, 10) };\n *\n * logger.v(\"Hello verbose!\", data);\n * logger.d(\"Hello debug!\", data);\n * // > [DEBUG]: Hello debug!\n * // > { data: { position: { X: 5, Y: 10 } } }\n *\n * // Inherits the minLogLevel\n * logger = logger.withConfig({ serialization: { encodeRobloxTypes: false } });\n *\n * logger.v(\"Hello verbose!\", data);\n * logger.d(\"Hello debug!\", data);\n * // > [DEBUG]: Hello debug!\n * // > { data: { position: \"\" } }\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "withConfig(config: " + }, + { + "kind": "Reference", + "text": "PartialRLogConfig", + "canonicalReference": "@rbxts/rlog!PartialRLogConfig:type" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "config", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + } + ], + "isOptional": false, + "isAbstract": false, + "name": "withConfig" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#withCorrelationId:member(1)", + "docComment": "/**\n * Returns a new {@link RLog} with the correlation_id set to `correlation_id`.\n *\n * Correlation IDs are appended to log messages when present, for further tracking beyond {@link RLog.withTag | tags}. Especially useful when tracking control flows across services or files.\n *\n * To learn more about Correlation IDs, see {@link RLog.child | child}.\n *\n * @param correlation_id - The new correlation_id to use.\n *\n * @returns The new {@link RLog} instance.\n *\n * @example\n * ```ts\n * const logger = new RLog().withCorrelationId(\"12345\");\n *\n * logger.d(\"Hello world!\");\n * // > [DEBUG]: \"Hello world!\"\n * // > { correlation_id: \"12345\" }\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "withCorrelationId(correlation_id: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "correlation_id", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + } + ], + "isOptional": false, + "isAbstract": false, + "name": "withCorrelationId" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#withEnricher:member(1)", + "docComment": "/**\n * Creates a new {@link RLog} instance with the given `enricher` added.\n *\n * Enrichers are callbacks that may or may not add data to (or mutate directly) a {@link LogEntry}.\n *\n * In the case of multiple enrichers, they are called in the order they are added.\n *\n * Furthermore, child enrichers are called before {@link RLog.child | parent} enrichers.\n *\n * _Note that enrichers are called before sinks._\n *\n * @param enricher - The enricher callback.\n *\n * @param minLevel - The minimum {@link LogLevel} for the enricher. The enricher will not be called for logs that are below this. Defaults to {@link LogLevel.VERBOSE}.\n *\n * @returns The new {@link RLog} instance.\n *\n * @example\n * ```ts\n * function MyCustomEnricher(entry: LogEntry, config: RLogConfig): LogEntry {\n * // attach the local player's user id if we're running in a LocalScript\n * if(RunService.IsClient()) {\n * entry.data[\"player\"] = Players.LocalPlayer.UserId;\n * }\n *\n * // return the modified entry\n * return entry;\n * }\n *\n * const logger = new RLog().withEnricher(MyCustomEnricher);\n *\n * logger.v(\"Hello verbose\");\n * // > [VERBOSE]: Hello Verbose\n * // > { \"data\": { \"player\": 1333 } }\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "withEnricher(enricher: " + }, + { + "kind": "Reference", + "text": "LogEnricherCallback", + "canonicalReference": "@rbxts/rlog!LogEnricherCallback:type" + }, + { + "kind": "Content", + "text": ", minLevel?: " + }, + { + "kind": "Reference", + "text": "LogLevel", + "canonicalReference": "@rbxts/rlog!LogLevel:enum" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "enricher", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "minLevel", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "withEnricher" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#withEnrichers:member(1)", + "docComment": "/**\n * Creates a new {@link RLog} instance with all of the given `enrichers` added.\n *\n * Version of {@link RLog.withEnricher | withEnricher} that allows you to provide multiple enrichers at once.\n *\n * @param enrichers - Array of enricher callbacks.\n *\n * @param minLevel - The minimum {@link LogLevel} for the enrichers. The enrichers will not be called for logs that are below this. Defaults to {@link LogLevel.VERBOSE}.\n *\n * @returns The new {@link RLog} instance.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "withEnrichers(enrichers: " + }, + { + "kind": "Reference", + "text": "ReadonlyArray", + "canonicalReference": "!ReadonlyArray:interface" + }, + { + "kind": "Content", + "text": "<" + }, + { + "kind": "Reference", + "text": "LogEnricherCallback", + "canonicalReference": "@rbxts/rlog!LogEnricherCallback:type" + }, + { + "kind": "Content", + "text": ">" + }, + { + "kind": "Content", + "text": ", minLevel?: " + }, + { + "kind": "Reference", + "text": "LogLevel", + "canonicalReference": "@rbxts/rlog!LogLevel:enum" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 8, + "endIndex": 9 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "enrichers", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 5 + }, + "isOptional": false + }, + { + "parameterName": "minLevel", + "parameterTypeTokenRange": { + "startIndex": 6, + "endIndex": 7 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "withEnrichers" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#withMinLogLevel:member(1)", + "docComment": "/**\n * Returns a new {@link RLog} with the minLogLevel set to `minLogLevel`.\n *\n * Messages below the minimum level will be ignored.\n *\n * You can also set this in the {@link RLogConfig | config}, this method is purely provided as a means for easier changing.\n *\n * @param minLevel - The {@link LogLevel} to allow logs for.\n *\n * @returns The new {@link RLog} instance\n *\n * @example\n * ```ts\n * let logger = new RLog();\n *\n * logger.v(\"Hello verbose!\");\n * logger.d(\"Hello debug!\");\n * // > [VERBOSE]: Hello verbose!\n * // > [DEBUG]: Hello debug!\n *\n * logger = logger.withMinLogLevel(LogLevel.DEBUG);\n *\n * logger.v(\"Hello verbose!\");\n * logger.d(\"Hello debug!\");\n * // > [DEBUG]: Hello debug!\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "withMinLogLevel(minLevel: " + }, + { + "kind": "Reference", + "text": "LogLevel", + "canonicalReference": "@rbxts/rlog!LogLevel:enum" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "minLevel", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + } + ], + "isOptional": false, + "isAbstract": false, + "name": "withMinLogLevel" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#withParent:member(1)", + "docComment": "/**\n * Returns a new {@link RLog} with the parent set to the provided `parent`.\n *\n * You can use this to switch the parents of {@link RLog.child | child} instances, or whatever else you fancy.\n *\n * @param parent - The new parent to use on the new instance.\n *\n * @returns The new {@link RLog} instance\n *\n * @example\n * ```ts\n * const mainLogger = new RLog(settings, \"Main\");\n * const secondaryLogger = new RLog(settings, \"Secondary\");\n *\n * print(mainLogger.path);\n * print(secondaryLogger.path);\n * // > DEFAULT.Main\n * // > DEFAULT.Secondary\n *\n * const newSecondary = secondaryLogger.withParent(mainLogger);\n *\n * print(newSecondary.path);\n * // > DEFAULT.Main.Secondary\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "withParent(parent: " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": " | undefined" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 4, + "endIndex": 5 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "parent", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 3 + }, + "isOptional": false + } + ], + "isOptional": false, + "isAbstract": false, + "name": "withParent" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#withSink:member(1)", + "docComment": "/**\n * Creates a new {@link RLog} instance with the given `sink` added.\n *\n * Sinks are callbacks that take in a {@link LogEntry} and return a boolean indicating if the entry was \"consumed\".\n *\n * If an entry is \"consumed\", that means it should not be processed any more.\n *\n * This is especially useful if you want to log your events to an external server, but not the local console.\n *\n * In the case of multiple sinks, they are called in the order they are added.\n *\n * Furthermore, child sinks are called before {@link RLog.child | parent} sinks.\n *\n * _Note that the {@link LogEntry} you receive will already be enriched._\n *\n * @param sink - The sink callback.\n *\n * @param minLevel - The minimum {@link LogLevel} for the sink. The sink will not be called for logs that are below this. Defaults to {@link LogLevel.VERBOSE}.\n *\n * @returns The new {@link RLog} instance.\n *\n * @example\n * ```ts\n * function MyCustomSink(entry: LogEntry, config: RLogConfig): boolean {\n * // ... log to external server\n * return true; // consume the message, meaning don't pass it along\n * }\n *\n * const logger = new RLog().withSink(MyCustomSink);\n *\n * logger.v(\"Hello verbose\"); // no output to the console, since it was consumed.\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "withSink(sink: " + }, + { + "kind": "Reference", + "text": "LogSinkCallback", + "canonicalReference": "@rbxts/rlog!LogSinkCallback:type" + }, + { + "kind": "Content", + "text": ", minLevel?: " + }, + { + "kind": "Reference", + "text": "LogLevel", + "canonicalReference": "@rbxts/rlog!LogLevel:enum" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "sink", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "minLevel", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "withSink" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#withSinks:member(1)", + "docComment": "/**\n * Creates a new {@link RLog} instance with all of the given `sinks` added.\n *\n * Version of {@link RLog.withSink | withSink} that allows you to provide multiple sinks at once.\n *\n * @param sinks - Array of sink callbacks.\n *\n * @param minLevel - The minimum {@link LogLevel} for the sinks. The sinks will not be called for logs that are below this. Defaults to {@link LogLevel.VERBOSE}.\n *\n * @returns The new {@link RLog} instance.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "withSinks(sinks: " + }, + { + "kind": "Reference", + "text": "ReadonlyArray", + "canonicalReference": "!ReadonlyArray:interface" + }, + { + "kind": "Content", + "text": "<" + }, + { + "kind": "Reference", + "text": "LogSinkCallback", + "canonicalReference": "@rbxts/rlog!LogSinkCallback:type" + }, + { + "kind": "Content", + "text": ">" + }, + { + "kind": "Content", + "text": ", minLevel?: " + }, + { + "kind": "Reference", + "text": "LogLevel", + "canonicalReference": "@rbxts/rlog!LogLevel:enum" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 8, + "endIndex": 9 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "sinks", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 5 + }, + "isOptional": false + }, + { + "parameterName": "minLevel", + "parameterTypeTokenRange": { + "startIndex": 6, + "endIndex": 7 + }, + "isOptional": true + } + ], + "isOptional": false, + "isAbstract": false, + "name": "withSinks" + }, + { + "kind": "Method", + "canonicalReference": "@rbxts/rlog!RLog#withTag:member(1)", + "docComment": "/**\n * Returns a new {@link RLog} with the tag set to `tag`.\n *\n * Tags are appended to log messages when present, for easier filtering.\n *\n * Usually, they're used at the class level to keep track of all logs facilitated by a single class\n *\n * @param tag - The new tag to use.\n *\n * @returns The new {@link RLog} instance.\n *\n * @example\n * ```ts\n * let logger = new RLog();\n *\n * logger.d(\"Hello world!\");\n * // > [DEBUG]: \"Hello world!\"\n *\n * logger = logger.withTag(\"main\");\n *\n * logger.d(\"Hello world!\");\n * // > [DEBUG]: main -> \"Hello world!\"\n * ```\n *\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "withTag(tag: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": "): " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isStatic": false, + "returnTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "releaseTag": "Public", + "isProtected": false, + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "tag", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + } + ], + "isOptional": false, + "isAbstract": false, + "name": "withTag" + } + ], + "implementsTokenRanges": [] + }, + { + "kind": "Variable", + "canonicalReference": "@rbxts/rlog!rlog:var", + "docComment": "/**\n * Mapping to {@link RLog}\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "rlog: " + }, + { + "kind": "Content", + "text": "typeof " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + } + ], + "fileUrlPath": "src/rlog.ts", + "isReadonly": true, + "releaseTag": "Public", + "name": "rlog", + "variableTypeTokenRange": { + "startIndex": 1, + "endIndex": 3 + } + }, + { + "kind": "Variable", + "canonicalReference": "@rbxts/rlog!rLog:var", + "docComment": "/**\n * Mapping to {@link RLog}\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "rLog: " + }, + { + "kind": "Content", + "text": "typeof " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + } + ], + "fileUrlPath": "src/rlog.ts", + "isReadonly": true, + "releaseTag": "Public", + "name": "rLog", + "variableTypeTokenRange": { + "startIndex": 1, + "endIndex": 3 + } + }, + { + "kind": "TypeAlias", + "canonicalReference": "@rbxts/rlog!RLogConfig:type", + "docComment": "/**\n * Configuration settings for {@link RLog}.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type RLogConfig = " + }, + { + "kind": "Content", + "text": "{\n readonly minLogLevel: " + }, + { + "kind": "Reference", + "text": "LogLevel", + "canonicalReference": "@rbxts/rlog!LogLevel:enum" + }, + { + "kind": "Content", + "text": ";\n readonly functionTags: boolean;\n readonly fileTags: boolean;\n readonly serialization: " + }, + { + "kind": "Reference", + "text": "SerializationConfig", + "canonicalReference": "@rbxts/rlog!SerializationConfig:type" + }, + { + "kind": "Content", + "text": ";\n readonly autoGenerateChildCorrelation: boolean;\n readonly autoGenerateCorrelation: boolean;\n readonly correlationGenerator?: () => string;\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "src/configuration/index.ts", + "releaseTag": "Public", + "name": "RLogConfig", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 6 + } + }, + { + "kind": "TypeAlias", + "canonicalReference": "@rbxts/rlog!RLogConstructorParameters:type", + "docComment": "/**\n * Table version of the constructor parameters for {@link RLog}.\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type RLogConstructorParameters = " + }, + { + "kind": "Content", + "text": "{\n config?: " + }, + { + "kind": "Reference", + "text": "PartialRLogConfig", + "canonicalReference": "@rbxts/rlog!PartialRLogConfig:type" + }, + { + "kind": "Content", + "text": ";\n tag?: string;\n parent?: " + }, + { + "kind": "Reference", + "text": "RLog", + "canonicalReference": "@rbxts/rlog!RLog:class" + }, + { + "kind": "Content", + "text": ";\n sinks?: " + }, + { + "kind": "Reference", + "text": "LogSinkCallback", + "canonicalReference": "@rbxts/rlog!LogSinkCallback:type" + }, + { + "kind": "Content", + "text": "[];\n enrichers?: " + }, + { + "kind": "Reference", + "text": "LogEnricherCallback", + "canonicalReference": "@rbxts/rlog!LogEnricherCallback:type" + }, + { + "kind": "Content", + "text": "[];\n correlation_id?: string;\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "src/rlog.ts", + "releaseTag": "Public", + "name": "RLogConstructorParameters", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 10 + } + }, + { + "kind": "TypeAlias", + "canonicalReference": "@rbxts/rlog!SerializationConfig:type", + "docComment": "/**\n * Configuration settings for serialization.\n *\n * @see\n *\n * {@link RLogConfig}\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export type SerializationConfig = " + }, + { + "kind": "Content", + "text": "{\n readonly minLogLevel: " + }, + { + "kind": "Reference", + "text": "LogLevel", + "canonicalReference": "@rbxts/rlog!LogLevel:enum" + }, + { + "kind": "Content", + "text": ";\n readonly encodeRobloxTypes: boolean;\n readonly encodeFunctions: boolean;\n readonly deepEncodeTables: boolean;\n readonly encodeType: " + }, + { + "kind": "Reference", + "text": "EncodingType", + "canonicalReference": "@rbxts/rlog!EncodingType:enum" + }, + { + "kind": "Content", + "text": ";\n readonly encodeMethod: string;\n}" + }, + { + "kind": "Content", + "text": ";" + } + ], + "fileUrlPath": "src/configuration/index.ts", + "releaseTag": "Public", + "name": "SerializationConfig", + "typeTokenRange": { + "startIndex": 1, + "endIndex": 6 + } + } + ] + } + ] +} diff --git a/input/rlog.api.md b/input/rlog.api.md new file mode 100644 index 0000000..7f21ea9 --- /dev/null +++ b/input/rlog.api.md @@ -0,0 +1,126 @@ +## API Report File for "@rbxts/rlog" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +/// + +// @public +export enum EncodingType { + DEEP = 0, + FAST = 1 +} + +// @public +export type LogData = Record; + +// @public +export type LogEnricherCallback = (entry: LogEntry, config: RLogConfig) => LogEntry; + +// @public +export type LogEntry = { + level: LogLevel; + message: string; + data: LogData; + metadata: LogMetadata; +}; + +// @public +export enum LogLevel { + DEBUG = 1, + ERROR = 4, + INFO = 2, + VERBOSE = 0, + WARNING = 3 +} + +// @public +export type LogMetadata = { + timestamp: number; + correlation_id?: string; + tag?: string; +}; + +// @public +export type LogSinkCallback = (entry: LogEntry, config: RLogConfig) => boolean | void; + +// @public +export type PartialRLogConfig = Partial> & { + readonly serialization?: Partial; +}; + +// @public +export class RLog { + constructor({ config, tag, parent, sinks, enrichers, correlation_id }: RLogConstructorParameters); + constructor(config?: PartialRLogConfig, tag?: string, parent?: RLog, sinks?: LogSinkCallback[], enrichers?: LogEnricherCallback[], correlation_id?: string); + child(correlation_id?: string | undefined): RLog; + childWithTag(tag?: string | undefined, correlation_id?: string | undefined): RLog; + clone(): RLog; + clone({ config, tag, parent, sinks, enrichers, correlation_id }: RLogConstructorParameters): RLog; + d(message: string, data?: LogData): void; + debug(message: string, data?: LogData): void; + static readonly default: RLog; + e(message: string, data?: LogData): void; + error(message: string, data?: LogData): void; + i(message: string, data?: LogData): void; + info(message: string, data?: LogData): void; + log(level: LogLevel, message: string, data?: LogData): void; + readonly parent: RLog | undefined; + readonly path: string; + static SetDefaultConfig(config: PartialRLogConfig): void; + readonly tag: string | undefined; + v(message: string, data?: LogData): void; + verbose(message: string, data?: LogData): void; + w(message: string, data?: LogData): void; + warn(message: string, data?: LogData): void; + warning(message: string, data?: LogData): void; + withConfig(config: PartialRLogConfig): RLog; + withCorrelationId(correlation_id: string): RLog; + withEnricher(enricher: LogEnricherCallback, minLevel?: LogLevel): RLog; + withEnrichers(enrichers: ReadonlyArray, minLevel?: LogLevel): RLog; + withMinLogLevel(minLevel: LogLevel): RLog; + withParent(parent: RLog | undefined): RLog; + withSink(sink: LogSinkCallback, minLevel?: LogLevel): RLog; + withSinks(sinks: ReadonlyArray, minLevel?: LogLevel): RLog; + withTag(tag: string): RLog; +} + +// @public +export const rLog: typeof RLog; + +// @public +export const rlog: typeof RLog; + +// @public +export type RLogConfig = { + readonly minLogLevel: LogLevel; + readonly functionTags: boolean; + readonly fileTags: boolean; + readonly serialization: SerializationConfig; + readonly autoGenerateChildCorrelation: boolean; + readonly autoGenerateCorrelation: boolean; + readonly correlationGenerator?: () => string; +}; + +// @public +export type RLogConstructorParameters = { + config?: PartialRLogConfig; + tag?: string; + parent?: RLog; + sinks?: LogSinkCallback[]; + enrichers?: LogEnricherCallback[]; + correlation_id?: string; +}; + +// @public +export type SerializationConfig = { + readonly minLogLevel: LogLevel; + readonly encodeRobloxTypes: boolean; + readonly encodeFunctions: boolean; + readonly deepEncodeTables: boolean; + readonly encodeType: EncodingType; + readonly encodeMethod: string; +}; + +``` diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..6cdfae5 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2596 @@ +{ + "name": "@rbxts/rlog", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@rbxts/rlog", + "version": "1.0.0", + "license": "Apache-2.0", + "dependencies": { + "@rbxts/object-utils": "^1.0.4", + "@rbxts/reverse-array": "^1.0.3", + "@rbxts/rust-classes": "^0.12.0", + "@rbxts/services": "^1.5.4", + "@rbxts/set-timeout": "^1.1.2", + "@rbxts/stacks-and-queues": "^1.0.5", + "@rbxts/string-utils": "^1.0.3", + "@rbxts/t": "^3.1.1", + "@rbxts/testez": "https://github.com/xeqi/testez#patch-1" + }, + "devDependencies": { + "@rbxts/compiler-types": "^2.3.0-types.1", + "@rbxts/jest": "^0.1.0", + "@rbxts/types": "^1.0.795", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-roblox-ts": "^0.0.36", + "prettier": "^3.2.5", + "prettier-plugin-organize-imports": "^3.2.4", + "roblox-ts": "^2.3.0", + "typescript": "^5.4.2" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@rbxts/compiler-types": { + "version": "2.3.0-types.1", + "resolved": "https://registry.npmjs.org/@rbxts/compiler-types/-/compiler-types-2.3.0-types.1.tgz", + "integrity": "sha512-NZWNo+fC4icfJte+NiDSDdWJo1KwzD0MDQ2iBi70YhNYlkA7+Xc+B1udbVqxLJuBur2JxG5bbKrpMAfHqfCtbw==", + "dev": true + }, + "node_modules/@rbxts/jest": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@rbxts/jest/-/jest-0.1.0.tgz", + "integrity": "sha512-0JmmHh0vPbydCRhPWNaU8eb9RcY82i80RP6N5uJphLSZSV57kUvX8ahk1RhbPcn8xFoTmh+Pm6YEdGiPAzX1BA==", + "dev": true, + "dependencies": { + "@rbxts/jest-globals": "0.1.0", + "@rbxts/jest-vendor": "0.1.0", + "@rbxts/pretty-format": "0.1.0" + } + }, + "node_modules/@rbxts/jest-globals": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@rbxts/jest-globals/-/jest-globals-0.1.0.tgz", + "integrity": "sha512-k6sPSVfohlHRLLBT+LuK5xhWy87YzNg7LpcWmPkzXZUUM6iUU+uXWtphegcT+fR4ZHRXFt0tjDepA61uMRQQQA==", + "dev": true, + "dependencies": { + "@rbxts/jest-matcher-utils": "0.1.0", + "@rbxts/jest-vendor": "0.1.0", + "@rbxts/pretty-format": "0.1.0" + } + }, + "node_modules/@rbxts/jest-matcher-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@rbxts/jest-matcher-utils/-/jest-matcher-utils-0.1.0.tgz", + "integrity": "sha512-SvUm5b47KvxjXWMdg3Ei7nMaAurLI8uDlOR7lN02QNCSSqm1KekkLe1p/knc4adyZuq3L/07cDUSRYLCIgn9qA==", + "dev": true, + "dependencies": { + "@rbxts/jest-vendor": "0.1.0", + "@rbxts/pretty-format": "0.1.0" + } + }, + "node_modules/@rbxts/jest-vendor": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@rbxts/jest-vendor/-/jest-vendor-0.1.0.tgz", + "integrity": "sha512-qEQbp8cUtIkiOFoxIC2wR7ml3++0Pf56Xf17YIGTQRrQig3UAZincD+DHxVd/YNHft38MRGpD7FinWfroNxUNA==", + "dev": true, + "dependencies": { + "@rbxts/react-vendor": "*" + } + }, + "node_modules/@rbxts/linked-lists": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@rbxts/linked-lists/-/linked-lists-1.0.4.tgz", + "integrity": "sha512-ZC2yHSv38A7PppTXEu9urP3zUrRaRM2N8CElmGstgd5c8hy9s9muEg2pBm+4nw8b1KsnY1MvjWHPiD3l95jC1g==", + "dependencies": { + "@rbxts/testez": "^0.3.1-ts.6" + } + }, + "node_modules/@rbxts/linked-lists/node_modules/@rbxts/testez": { + "version": "0.3.1-ts.7", + "resolved": "https://registry.npmjs.org/@rbxts/testez/-/testez-0.3.1-ts.7.tgz", + "integrity": "sha512-DkIlRFdMODHjJPEYJT/cPYv2ZQzSqAufF4XAsqrx7zFg8OVAkSHY5aGChGoPNrZo0PM4zz9bw46ZIVqLfcM05Q==" + }, + "node_modules/@rbxts/object-utils": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@rbxts/object-utils/-/object-utils-1.0.4.tgz", + "integrity": "sha512-dLLhf022ipV+9i910sOE7kl9losKHoon0WgeerHqVMQA5EYsLUsVT2AxhJuhk8MiDn5oJ2GiFofE/LadY9TpJQ==" + }, + "node_modules/@rbxts/pretty-format": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@rbxts/pretty-format/-/pretty-format-0.1.0.tgz", + "integrity": "sha512-ZEZM6wd2kWXhXYcr+Q6Vey2wcre6JP6LDRX4u6PnLOEHmSy5XiLCmed1sicYFQfFYgkG5bRk+sGCySSWFEbqoA==", + "dev": true, + "dependencies": { + "@rbxts/jest-vendor": "0.1.0" + } + }, + "node_modules/@rbxts/react-vendor": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@rbxts/react-vendor/-/react-vendor-0.4.0.tgz", + "integrity": "sha512-roWs9FmR7CQDK1N6gE/36tiCBQRl8v1S0pUJD2Ly3ZMVvfjAk2gixrkqGcKFGtXQQq6r4dTAtHduAeZJBd640g==", + "dev": true + }, + "node_modules/@rbxts/reverse-array": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rbxts/reverse-array/-/reverse-array-1.0.3.tgz", + "integrity": "sha512-dHm/p72kdwwsza+pDSR/78QOeg/p94D6NVbHtwURLSZyAMsObX9R/ux//CF5bpCNDniwz3+8CrIGm6P4WvvNCw==", + "dependencies": { + "@rbxts/testez": "^0.3.1-ts.7" + } + }, + "node_modules/@rbxts/reverse-array/node_modules/@rbxts/testez": { + "version": "0.3.1-ts.7", + "resolved": "https://registry.npmjs.org/@rbxts/testez/-/testez-0.3.1-ts.7.tgz", + "integrity": "sha512-DkIlRFdMODHjJPEYJT/cPYv2ZQzSqAufF4XAsqrx7zFg8OVAkSHY5aGChGoPNrZo0PM4zz9bw46ZIVqLfcM05Q==" + }, + "node_modules/@rbxts/rust-classes": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@rbxts/rust-classes/-/rust-classes-0.12.0.tgz", + "integrity": "sha512-Ibk532/9tHswqU9AdJlLGDjb3fD+tisI0WzTvzsbFcndcdRfEmpBqXC0JZ+4+lIfSERJmL4zRXZQNN//nJ4rmw==" + }, + "node_modules/@rbxts/services": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@rbxts/services/-/services-1.5.4.tgz", + "integrity": "sha512-Klh+gRIT8zy3xRTX1YD6FZ9nAMzkzPLTHmciigt59PEF7PJXo31CF0IU0RegQ7VSMrz1iOnXwxbIwy3htcMfOA==" + }, + "node_modules/@rbxts/set-timeout": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rbxts/set-timeout/-/set-timeout-1.1.2.tgz", + "integrity": "sha512-P/A0IiH9wuZdSJYr4Us0MDFm61nvIFR0acfKFHLkcOsgvIgELC90Up9ugiSsaMEHRIcIcO5UjE39LuS3xTzQHw==", + "dependencies": { + "@rbxts/services": "^1.5.1" + } + }, + "node_modules/@rbxts/stacks-and-queues": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@rbxts/stacks-and-queues/-/stacks-and-queues-1.0.5.tgz", + "integrity": "sha512-G8r7eMjN9AVKLItmILj1XncVhF+MrgT3CGRmdr8IB7c93WIulRUwnbQ8Uk+8nyE9rxL8HpR7Ne+WO5ocMemx6A==", + "dependencies": { + "@rbxts/linked-lists": "^1.0.1" + } + }, + "node_modules/@rbxts/string-utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rbxts/string-utils/-/string-utils-1.0.3.tgz", + "integrity": "sha512-nsZsPdGsrsBdwLg7qQ5RGHoVhfvK+U3GvZ/6S+7KufqaFrbHWk2lufESob/C3xYf5sAeXgTJKWUnDJknYBGTIQ==" + }, + "node_modules/@rbxts/t": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@rbxts/t/-/t-3.1.1.tgz", + "integrity": "sha512-r+IvHHGLt9ZM8+cJAs5Q7ZyGaSlsbkXTaeat85FxRmjjozykHLbQ24rY/5utJbp63a5uCy3Wyl1fGv/Gk/GnIw==" + }, + "node_modules/@rbxts/testez": { + "version": "0.4.2-ts.0", + "resolved": "git+ssh://git@github.com/xeqi/testez.git#6fb2caaae1bb6e030f3de9ba4f81ba2702ba9dca", + "license": "Apache 2.0" + }, + "node_modules/@rbxts/types": { + "version": "1.0.798", + "resolved": "https://registry.npmjs.org/@rbxts/types/-/types-1.0.798.tgz", + "integrity": "sha512-5X8KDOpHrPb4dE2hFuUmSavmLx1AAOnxrxZXJA1aZU0hqfaoxWoNckBJsTVCTj+Q9fVEAhbhQ+Cpk1QVj78W4g==", + "dev": true + }, + "node_modules/@roblox-ts/luau-ast": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@roblox-ts/luau-ast/-/luau-ast-1.0.11.tgz", + "integrity": "sha512-+maoLYpqY0HK8ugLFHS3qz0phMyDaN3i21jjW75T2ZaqJg84heKDUo98iXClvnx3mUDhW10IxqH+cYJ2iftYhQ==", + "dev": true + }, + "node_modules/@roblox-ts/path-translator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@roblox-ts/path-translator/-/path-translator-1.0.0.tgz", + "integrity": "sha512-Lp6qVUqjmXIrICy2KPKRiX8IkJ+lNqn6RqoUplLiTr+4JehIN+mJv0tTnE72XRyIfcx0VWl5nKrRwUuqcOj1yg==", + "dev": true, + "dependencies": { + "ajv": "^8.12.0", + "fs-extra": "^11.2.0" + } + }, + "node_modules/@roblox-ts/path-translator/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@roblox-ts/path-translator/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@roblox-ts/rojo-resolver": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@roblox-ts/rojo-resolver/-/rojo-resolver-1.0.6.tgz", + "integrity": "sha512-+heTECMo6BdH3a3h4DCj+8kJvwKuxWqBevcW/m2BzQaVtmo1GtLa4V4bJCMvDuAMeEqYKQZUB7546nN2dcqqAA==", + "dev": true, + "dependencies": { + "ajv": "^8.12.0", + "fs-extra": "^11.1.1" + } + }, + "node_modules/@roblox-ts/rojo-resolver/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@roblox-ts/rojo-resolver/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.14.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz", + "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "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 + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-roblox-ts": { + "version": "0.0.36", + "resolved": "https://registry.npmjs.org/eslint-plugin-roblox-ts/-/eslint-plugin-roblox-ts-0.0.36.tgz", + "integrity": "sha512-vlbgfHY1heWSyDunVX3gIOamCy28KqrJlDkmuDOyYVBo8uLqdvbFkbWkdGxn59Vky1m6pFcvZGU6TObfmwm5Pg==", + "dev": true, + "dependencies": { + "@types/node": "^20.8.0", + "@typescript-eslint/experimental-utils": "^5.62.0", + "typescript": "^5.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "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.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/prettier-plugin-organize-imports": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz", + "integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==", + "dev": true, + "peerDependencies": { + "@volar/vue-language-plugin-pug": "^1.0.4", + "@volar/vue-typescript": "^1.0.4", + "prettier": ">=2.0", + "typescript": ">=2.9" + }, + "peerDependenciesMeta": { + "@volar/vue-language-plugin-pug": { + "optional": true + }, + "@volar/vue-typescript": { + "optional": true + } + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/roblox-ts": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/roblox-ts/-/roblox-ts-2.3.0.tgz", + "integrity": "sha512-swz+3sxHcB1ww5iUkwxzPFqrbWYmjD9uDriLhta5MAShvRFW4Vdku/aBSU4KiLqtVWYvYo32G+5bXg1Pw2yvIA==", + "dev": true, + "dependencies": { + "@roblox-ts/luau-ast": "^1.0.11", + "@roblox-ts/path-translator": "^1.0.0", + "@roblox-ts/rojo-resolver": "^1.0.6", + "chokidar": "^3.6.0", + "fs-extra": "^11.2.0", + "kleur": "^4.1.5", + "resolve": "^1.22.6", + "typescript": "=5.2.2", + "yargs": "^17.7.2" + }, + "bin": { + "rbxtsc": "out/CLI/cli.js" + } + }, + "node_modules/roblox-ts/node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "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" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4e872dc --- /dev/null +++ b/package.json @@ -0,0 +1,63 @@ +{ + "name": "@rbxts/rlog", + "version": "1.0.0", + "description": "Context based Server-Side logging solution for ROBLOX projects.", + "main": "out/init.lua", + "scripts": { + "build": "rbxtsc --noInclude", + "dev": "rbxtsc -w --type game --rojo test.project.json --noInclude", + "watch": "rbxtsc -w --noInclude", + "prepublishOnly": "npm run build" + }, + "keywords": [ + "rlog", + "rbxts", + "roblox", + "roblox-ts", + "typescript", + "logging" + ], + "author": "Daymon Littrell-Reyes", + "repository": "daymxn/rlog", + "bugs": { + "url": "https://github.com/daymxn/rlog/issues" + }, + "license": "Apache-2.0", + "types": "out/index.d.ts", + "files": [ + "out", + "!**/*.tsbuildinfo", + "!**/*.spec.lua", + "!**/*.spec.d.ts" + ], + "publishConfig": { + "access": "public" + }, + "devDependencies": { + "@rbxts/compiler-types": "^2.3.0-types.1", + "@rbxts/jest": "^0.1.0", + "@rbxts/types": "^1.0.795", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-roblox-ts": "^0.0.36", + "prettier": "^3.2.5", + "prettier-plugin-organize-imports": "^3.2.4", + "roblox-ts": "^2.3.0", + "typescript": "^5.4.2" + }, + "dependencies": { + "@rbxts/object-utils": "^1.0.4", + "@rbxts/reverse-array": "^1.0.3", + "@rbxts/rust-classes": "^0.12.0", + "@rbxts/services": "^1.5.4", + "@rbxts/set-timeout": "^1.1.2", + "@rbxts/stacks-and-queues": "^1.0.5", + "@rbxts/string-utils": "^1.0.3", + "@rbxts/t": "^3.1.1", + "@rbxts/testez": "https://github.com/xeqi/testez#patch-1" + } +} diff --git a/src/common/index.ts b/src/common/index.ts new file mode 100644 index 0000000..f3c9e0c --- /dev/null +++ b/src/common/index.ts @@ -0,0 +1,178 @@ +import { RLogConfig } from "../configuration"; +import { LogContext, RLog } from "../rlog"; + +/** + * Enum representing the various log levels, or "importance" of a {@link LogEntry}. + * + * @public + */ +export enum LogLevel { + /** + * The lowest level of logging. + * + * Verbose messages are those that are not usually useful + * unless you need to see deep step-by-step processes in your + * application. + */ + VERBOSE, + + /** + * The second lowest level of logging. + * + * Generally used for messages that you don't necessarily + * need to see at runtime, but they're useful when you need + * to find out why something is happening. + */ + DEBUG, + + /** + * The baseline level of logging. + * + * Useful for messages that signify an event or interaction. + * Usually occur only once or twice in a control flow, and are used + * less for debugging, and more for seeing what's going on in your application. + */ + INFO, + + /** + * Not as bad as an {@link LogLevel.ERROR | ERROR}, but something that you should be looked at. + * + * Useful for situations where something isn't necessarily breaking, but it's behaving + * in a way that isn't desired. + */ + WARNING, + + /** + * The highest level of logging. + * + * Used to indicate issues or exceptions that broke the application, and need to be fixed. + */ + ERROR, +} + +/** + * Type representing the additional data associated with a log entry. + * + * @public + */ +export type LogData = Record; + +/** + * A single logging event. + * + * Each message has its own instance of this, with relevant data + * attached. + * + * @public + */ +export type LogEntry = { + /** The log level of the entry. */ + level: LogLevel; + /** The message associated with the log entry. */ + message: string; + /** Additional data associated with the log entry. */ + data: LogData; + encoded_data: LogData; + + config: Writable; + + context?: LogContext; + timestamp: number; + source_metadata: SourceMetadata; +}; + +/** + * Type representing a callback function for consuming log entries, or a "sink". + * + * Sinks optionally consume {@link LogEntry}s. If you return `true`, + * then the log will be stopped, and no further sinks will be called. The {@link LogEntry} will + * also not be logged to the console. + * + * To learn more about sinks, and how they work, see {@link RLog.withSink | withSink}. + * + * @param entry - The log entry to handle. + * @param attachment - The instance for where this sink is attached. + * @param source - The instance for where this event is occuring. + * + * @returns A boolean indicating whether the log was consumed, or void. + * + * @public + */ +export type LogSinkCallback = (entry: LogEntry) => boolean | void; + +// TODO(): documentation +export function sink(entry: LogEntry, sinks: LogSinkCallback[]) { + if (sinks.isEmpty()) { + warn("rLog entry is missing sinks. I don't have anywhere to send this message.\n", entry.message); + return; + } + + sinks.some((sinker) => sinker(entry) === true); +} + +/** + * Type representing a callback function for enriching log entries, or an "enricher". + * + * Enrichers optionally mutate {@link LogEntry}s. You can add data to a {@link LogEntry}, + * edit its {@link LogEntry.source_metadata | metadata}, or just return it if you don't need to + * do anything. + * + * To learn more about enrichers, and how they work, see {@link RLog.withEnricher | withEnricher}. + * + * @param entry - The log entry to enrich. + * @param attachment - The instance for where this enricher is attached. + * @param source - The instance for where this event is occuring. + * + * @returns The enriched log entry. + * + * @public + */ +export type LogEnricherCallback = (entry: LogEntry) => LogEntry; + +// TODO(): documentation +export function enrich(entry: LogEntry, enrichers: LogEnricherCallback[]): LogEntry { + return enrichers.reduce((log, enricher) => enricher(log), entry); +} + +/** + * Type representing a callback function for converting log entries to output. + * + * @param entry - The log entry to convert. + * + * @returns Any amount of arguments to output in the entry's place + * + * @public + */ +export type FormatMethodCallback = (entry: LogEntry) => LuaTuple; + +// TODO(): document +export type SourceMetadata = { + /** + * The name of the function where this was created. + * + * May be undefined if this was created within an anonymous function. + */ + function_name?: string; + + /** + * The nearest function name of where this was created. + * + * May be undefined if we can't find one (such as reaching max depth, or a stack full of anonymous functions) + * + * Can be used in place of {@link SourceContext.function_name | function_name} for getting an idea of what's + * going on, even in anonymous functions. + * + * If {@link SourceContext.function_name | function_name} is present, this value will be the same. + */ + nearest_function_name?: string; + + /** + * The full name of the file where this was created. + */ + file_path: string; + + /** + * The line number in the file where this was created. + */ + line_number: number; +}; diff --git a/src/configuration/index.ts b/src/configuration/index.ts new file mode 100644 index 0000000..653f4d5 --- /dev/null +++ b/src/configuration/index.ts @@ -0,0 +1,359 @@ +import { reverseArray } from "@rbxts/reverse-array"; +import { RunService } from "@rbxts/services"; +import { LogEnricherCallback, LogEntry, LogLevel, LogSinkCallback } from "../common"; +import { RLog } from "../rlog"; + +const isStudio = RunService.IsStudio(); + +/** + * Configuration settings for serialization. + * + * @see {@link RLogConfig} + * + * @public + */ +export type SerializationConfig = { + /** + * Whether to encode Roblox-specific types. + * + * When this setting is disabled, all roblox-specific types will + * instead just be represented as `""`. + * + * @defaultValue `true` + * + * @example + * ```ts + * logger.i("Player died", { player: player, location: player.Position }); + * // > [INFO]: Player died + * // > { "data": { "player": 1338, "location": "" } } + * ``` + */ + readonly encodeRobloxTypes: boolean; + + /** + * Whether to encode Roblox-specific types. + * + * When this setting is disabled, all function types will + * be represented as `""`. Otherwise, they'll be excluded + * from the outputted JSON. + * + * @defaultValue `false` + * + * @example + * ```ts + * class PlayerClass { + * constructor(public name: string) {}; + * public eatFood() { + * // ... + * } + * } + * + * const player = new PlayerClass("daymon"); + * + * let logger = new RLog({ serialization: { encodeFunctions: true } }); + * + * logger.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "data": { "player": { "name": "daymon", "eatFood": "" } } } + * + * logger = new RLog({ serialization: { encodeFunctions: false } }); + * + * logger.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "data": { "player": { "name": "daymon" } } } + * ``` + */ + readonly encodeFunctions: boolean; + + /** + * Whether to perform deep encoding on tables. + * + * When disabled, tables will not be recursively encoded. Which may cause you + * to miss out on certain data types being properly translated (eg; roblox data types). + * + * This will occur even if you have {@link SerializationConfig.encodeRobloxTypes | encodeRobloxTypes} + * enabled. + * + * But if you have deeply nested data types, or are wanting to save on performance, + * this may be desirable. + * + * @defaultValue `true` + * + * @example + * ``` + * const event = { + * source: { + * position: new Vector2(1, 1), + * distance: 100 + * }, + * target: new Vector2(2, 2), + * }; + * + * let logger = new RLog({ serialization: { deepEncodeTables: true } }); + * logger.i("Gun was fired", event); + * // > [INFO]: Gun was fired + * // > { "data": { "source": { "position": { "X": 1, "Y": 1}, "distance": 100 }, "target": { "X": 2, "Y": 2} } } + * + * logger = new RLog({ serialization: { deepEncodeTables: false } }); + * logger.i("Gun was fired", event); + * // > [INFO]: Gun was fired + * // > { "data": { "source": { "position": null, "distance": 100 }, "target": { "X": 2, "Y": 2} } } + * ``` + */ + readonly deepEncodeTables: boolean; + + /** + * The method name to use for custom serialization. + * + * When encoding an object, the encoder will first check if the object has + * a method with this name. If it does, it will call that method instead of + * trying to manually encode it. + * + * @defaultValue `__tostring` + * + * @example + * ```ts + * class PlayerClass { + * constructor(public name: string) {}; + * + * public encode() { + * return { name: this.name }; + * } + * } + * + * const player = new PlayerClass("daymon"); + * + * let logger = new RLog(); + * + * logger.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "data": { "player": "PlayerClass" } } + * + * logger = new RLog({ serialization: { encodeMethod: "encode" } }); + * + * logger.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "data": { "player": { "name": "daymon" } } } + * ``` + */ + readonly encodeMethod: string; // TODO(): we should provide a fallback too for custom encoding, might be a stretch for a serialization lib though tbh +}; + +/** + * Default configuration for serialization. + * + * @internal + */ +export const defaultSerializationConfig: Readonly = { + encodeRobloxTypes: true, + encodeFunctions: false, + encodeMethod: "__tostring", + deepEncodeTables: true, +}; + +/** + * Configuration settings for {@link RLog}. + * + * @public + */ +export type RLogConfig = { + /** + * Sets the minimum {@link LogLevel} for data to be logged. + * + * Messages below the minimum level will be ignored. + * + * @defaultValue If in studio {@link LogLevel.VERBOSE | VERBOSE}, else {@link LogLevel.WARNING | WARNING} + * + * @example + * ```ts + * let logger = new RLog(); + * + * logger.v("Hello verbose!"); + * logger.d("Hello debug!"); + * // > [VERBOSE]: Hello verbose! + * // > [DEBUG]: Hello debug! + * + * logger = logger.withMinLogLevel(LogLevel.DEBUG); + + * logger.v("Hello verbose!"); + * logger.d("Hello debug!"); + * // > [DEBUG]: Hello debug! + * ``` + */ + readonly minLogLevel: LogLevel; + + /** Settings to use when encoding {@link LogEntry.data | data} in logs. */ + readonly serialization: SerializationConfig; + + /** + * Optional function to generate correlation IDs. + * + * By default, Correlation IDs are generated via a combination of + * {@link https://create.roblox.com/docs/en-us/reference/engine/classes/HttpService#GenerateGUID | HttpService.GenerateGUID } + * and the current time- to avoid conflicts. + * + * If you specify your own function, it will be called anytime a + * new Correlation ID is requested. + * + * Especially useful if you want to create Correlation IDs to match + * ids in your external database. + * + * @example + * ```ts + * function generateCorrelationID(): string { + * return "1"; + * } + * + * const logger = new RLog({ correlationGenerator: generateCorrelationID }); + * + * const child = logger.child(); + * child.i("Player created", { player: player }); + * // > [INFO]: Player created + * // > { "correlation_id": "1", "data": { "player": 1338 } } + * ``` + */ + readonly correlationGenerator?: () => string; + + // children do not inherit + // TODO(): documentation + readonly tag?: string; + + // TODO(): documentation + readonly sinks?: LogSinkCallback[]; + + // TODO(): documentation + readonly enrichers?: LogEnricherCallback[]; + + /** + * Allows logs that have context to bypass {@link RLogConfig.minLogLevel | minLogLevel} under certain + * circumstances. + * + * With this setting enabled, even if the {@link RLogConfig.minLogLevel | minLogLevel} is set + * to filter out logs below {@link LogLevel.WARNING | WARNING}, if one of the logs in the context + * is that of {@link LogLevel.WARNING | WARNING} or above, then _all_ of the logs in the context + * will be sent through. + * + * Allows you to set a high {@link RLogConfig.minLogLevel | minLogLevel} without sacrificing + * a proper log trace whenever something bad happens. + * + * // TODO(): in the wiki we'll go into what goes on behind the scenes, and the ContextManager + * + * @defaultValue `false` + * + * @see {@link RLogConfig.suspendContext | suspendContext} + * + * @example + * ```ts + * // TODO() + * ``` + */ + readonly contextBypass: boolean; + + /** + * Prevents logs from propogating until the context is killed. + * + * With this setting enabled, logs with context will not be sent until the context is stopped. + * + * All of the messages will be sent at once when the context is stopped. + * + * Can be used in tangent with {@link RLogConfig.contextBypass | contextBypass} to + * retain log order. + * + * @defaultValue `false` + * + * @example + * ```ts + * // TODO() + * ``` + */ + readonly suspendContext: boolean; +}; + +/** + * Default configuration for {@link RLog}. + * + * @internal + */ +export const defaultRLogConfig: Readonly = { + minLogLevel: isStudio ? LogLevel.VERBOSE : LogLevel.WARNING, + serialization: defaultSerializationConfig, + contextBypass: false, + suspendContext: false, +}; + +/** + * Version of {@link RLogConfig} that allows all data to be absent. + * + * @public + */ +export type PartialRLogConfig = Partial> & { + readonly serialization?: Partial; +}; + +/** + * Merges a variable amount of config files. + * + * Configs that come later take precedence over those before. + * + * Uses the {@link defaultRLogConfig | default} config as a baseline. + * + * @param configs - A variable list of config files to merge together. + * + * @returns The merged config files. + * + * @internal + */ +// TODO(): see if there's any use case where we _wouldn't_ want the default config involved +// TODO(): reduce the amount of places where we need to call this. maybe make primary constructors take in full rLog configs or something idk +export function mergeConfigs(...configs: ReadonlyArray): RLogConfig { + const validConfigs = configs.filterUndefined(); + + const serialization = validConfigs.reduce( + (acc, it) => ({ + ...acc, + ...(it.serialization ?? {}), + }), + defaultSerializationConfig + ); + + const mergedConfigs = validConfigs.reduce( + (acc, it) => ({ + ...acc, + ...(it ?? {}), + tag: it.tag, + }), + defaultRLogConfig + ); + + // TODO(): cleanup. there needs to be a better way to do this + // note: could also check if the last config is actually even a partial. cause if it's not, we can just return it deep copied + const addedSinks = new Set(); + const addedEnrichers = new Set(); + + const enrichers: LogEnricherCallback[] = []; + const sinks: LogSinkCallback[] = []; + + const flipped = reverseArray(validConfigs); + + for (const config of flipped) { + config.sinks?.forEach((it) => { + if (!addedSinks.has(it)) { + addedSinks.add(it); + sinks.push(it); + } + }); + config.enrichers?.forEach((it) => { + if (!addedEnrichers.has(it)) { + addedEnrichers.add(it); + enrichers.push(it); + } + }); + } + + return { + ...mergedConfigs, + sinks: [...sinks], + enrichers: [...enrichers], + serialization: serialization, + } as RLogConfig; +} diff --git a/src/context/index.ts b/src/context/index.ts new file mode 100644 index 0000000..63c5364 --- /dev/null +++ b/src/context/index.ts @@ -0,0 +1 @@ +export { LogContextManager } from "./log-context-manager"; diff --git a/src/context/log-context-manager.ts b/src/context/log-context-manager.ts new file mode 100644 index 0000000..015ac11 --- /dev/null +++ b/src/context/log-context-manager.ts @@ -0,0 +1,75 @@ +import { LogEntry, LogLevel, sink } from "../common"; +import { LogContext } from "../rlog"; + +const flaggedContext: Set = new Set(); +const pendingMessages: Map = new Map(); +const promisedMessages: Map = new Map(); + +function getMessages(correlation: string) { + if (flaggedContext.has(correlation)) { + return pendingMessages.get(correlation) ?? []; + } else if (promisedMessages.has(correlation)) { + return promisedMessages.get(correlation) ?? []; + } + return undefined; +} + +/** @internal */ +export namespace LogContextManager { + // save to send later + export function save(message: LogEntry, context: LogContext) { + const messages = pendingMessages.get(context.correlation_id) ?? []; + + pendingMessages.set(context.correlation_id, [...messages, message]); + + if (message.level >= LogLevel.WARNING) { + flaggedContext.add(context.correlation_id); + } + } + + export function push(message: LogEntry, context: LogContext) { + save(message, context); + const messages = promisedMessages.get(context.correlation_id) ?? []; + + promisedMessages.set(context.correlation_id, [...messages, message]); + } + + export function flag(message: LogEntry) { + if (message.context) { + flaggedContext.add(message.context.correlation_id); + } + } + + // to be called when a context is closed. try to process it. + export function flush(context: LogContext) { + const entries = getMessages(context.correlation_id); + if (entries) { + if (entries.isEmpty()) { + warn( + "rLog Context Manager doesn't have any messages for a context. This shouldn't happen.", + "\nCorrelation ID:", + context.correlation_id + ); + } + + for (const pending of entries) { + sink(pending, pending.config.sinks ?? []); + } + } + + flaggedContext.delete(context.correlation_id); + pendingMessages.delete(context.correlation_id); + promisedMessages.delete(context.correlation_id); + } + + export function clear() { + flaggedContext.clear(); + pendingMessages.clear(); + } + + // TODO(): export as a method in rLog. user has to call it. + // otherwise, we could end up closing context that the user already bound to close to do + export function forceFlush() { + // TODO(): implement + } +} diff --git a/src/context/log-context.ts b/src/context/log-context.ts new file mode 100644 index 0000000..fb41892 --- /dev/null +++ b/src/context/log-context.ts @@ -0,0 +1,15 @@ +/** + * Intead, we'll migrate to a world where you don't create loggers per file, but create optional configs. + * + * Then, in function's, you'll start context by "using" those configs. + * + * Benefits: + * - We can inherit the default without needing people to face race conditions. + * - We can create a more strict definition and seperation between context, config, and loggers + * - It makes it easier in usage because you don't have `Logger` and `logger`. You'd just have `config` and `logger` or something like that + * + * We'll need to move some things to config though- like tags + * + * I just realized... rLog is really only meant for the server, huh? should note this somewhere + * "Context based Server-Side logging for ROBLOX" + */ diff --git a/src/enrichers/file-tag-enricher.ts b/src/enrichers/file-tag-enricher.ts new file mode 100644 index 0000000..bde6f0d --- /dev/null +++ b/src/enrichers/file-tag-enricher.ts @@ -0,0 +1,9 @@ +import { LogEntry } from "../common"; + +export function fileTagEnricher(entry: LogEntry) { + if (entry.config.tag === undefined) { + entry.config.tag = entry.source_metadata.file_path; + } + + return entry; +} diff --git a/src/enrichers/function-tag-enricher.ts b/src/enrichers/function-tag-enricher.ts new file mode 100644 index 0000000..ebd378a --- /dev/null +++ b/src/enrichers/function-tag-enricher.ts @@ -0,0 +1,9 @@ +import { LogEntry } from "../common"; + +export function functionTagEnricher(entry: LogEntry) { + if (entry.config.tag === undefined) { + entry.config.tag = entry.source_metadata.nearest_function_name; + } + + return entry; +} diff --git a/src/enrichers/index.ts b/src/enrichers/index.ts new file mode 100644 index 0000000..40274e4 --- /dev/null +++ b/src/enrichers/index.ts @@ -0,0 +1,3 @@ +export { fileTagEnricher } from "./file-tag-enricher"; +export { functionTagEnricher } from "./function-tag-enricher"; +export { sourceMetadataEnricher } from "./source-metadata-enricher"; diff --git a/src/enrichers/source-metadata-enricher.ts b/src/enrichers/source-metadata-enricher.ts new file mode 100644 index 0000000..a8d717d --- /dev/null +++ b/src/enrichers/source-metadata-enricher.ts @@ -0,0 +1,60 @@ +import { LogEntry } from "../common"; +import { RLog } from "../rlog"; + +/** + * Attaches source metadata to a log entry. + * + * The metadata is attached under the `source_metadata` key in data. + * + * You also need to have {@link RLog.forceSourceMetadata | source metadata} enabled + * for metadata to be properly found. + * + * If a value is `undefined`, it will not be populated. + * + * @public + * + * @example + * ### Setup + * #### In file `main.ts` + * ```ts + * import { rLog, attachSourceMetadata } from "@rbxts/rlog"; + * rLog.setDefaultConfig({ forceSourceMetadata: true }).withEnricher(attachSourceMetadata); + * + * import { doAction } from "./actions"; + * + * doAction(); + * ``` + * + * #### In file `actions.ts` + * ```ts + * import { rLog } from "@rbxts/rlog"; + * + * const Logger = new rLog().withTag("Actions"); + * + * export function doAction() { + * const log = Logger.child(); + * + * log.i("Hello world!"); + * } + * ``` + * + * ### Output + * ```text + * [INFO]: Actions -> Hello world! + * { + * data: { + * source_metadata: { + * file_name: "actions", + * full_file_path: "ReplicatedStorage.TS.actions", + * function_name: "doAction" + * } + * } + * } + * ``` + */ +// TODO(): update docs +export function sourceMetadataEnricher(entry: LogEntry): LogEntry { + entry.encoded_data["source_metadata"] = entry.source_metadata; + + return entry; +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..6e60264 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,13 @@ +/** + * Metadata based logging framework for ROBLOX projects. + * + * @remarks + * `rlog` exports the {@link RLog} class as the primary entry point. + * + * @packageDocumentation + */ +export { LogData, LogEnricherCallback, LogEntry, LogLevel, LogSinkCallback } from "./common"; +export { PartialRLogConfig, RLogConfig, SerializationConfig } from "./configuration"; +export { fileTagEnricher, functionTagEnricher, sourceMetadataEnricher } from "./enrichers"; +export { RLog, RLogConstructorParameters, rLog, rLogger, rlog } from "./rlog"; +export { robloxConsoleSink } from "./sinks"; diff --git a/src/rlog.ts b/src/rlog.ts new file mode 100644 index 0000000..28c88fa --- /dev/null +++ b/src/rlog.ts @@ -0,0 +1,593 @@ +import { HttpService } from "@rbxts/services"; +import { enrich, LogData, LogEntry, LogLevel, sink, SourceMetadata } from "./common"; +import { mergeConfigs, PartialRLogConfig, RLogConfig } from "./configuration"; +import { LogContextManager } from "./context/log-context-manager"; +import { serialize } from "./serialization"; +import { robloxConsoleSink } from "./sinks"; + +const FILE_NAME = debug.info(1, "s")[0]; + +/** + * Table version of the constructor parameters for {@link RLog}. + * + * @public + */ +export type RLogConstructorParameters = { + config?: PartialRLogConfig; + context?: LogContext; + inheritDefault?: boolean; +}; + +function isConstructorParameters(value: object): value is RLogConstructorParameters { + return "config" in value || "context" in value; +} + +// TODO(): needs testing +function extractSourceMetadata(): SourceMetadata { + const metadata = { + function_name: undefined, + nearest_function_name: undefined, + file_path: undefined, + line_number: undefined, + } as Writable>; + + let stack_level = 2; + let file; + do { + stack_level += 1; + + const [file, line, func] = debug.info(stack_level, "sln"); + if (file === FILE_NAME) continue; + if (metadata.file_path === undefined) { + metadata.file_path = file; + metadata.function_name = func; + metadata.line_number = line; + } + if (metadata.nearest_function_name === undefined) { + metadata.nearest_function_name = func; + } else { + break; + } + } while (file !== undefined); + + return metadata as SourceMetadata; +} + +function GenerateCorrelationID(config: RLogConfig) { + if (config.correlationGenerator) return config.correlationGenerator(); + + return `${DateTime.now().UnixTimestamp}_${HttpService.GenerateGUID(false)}`; +} + +// TODO(): document +export type ContextCallback = (context: LogContext) => R; + +function isContextCallback(value: unknown): value is ContextCallback { + return typeIs(value, "function"); +} + +// TODO(): document +export function withLogContext(callback: ContextCallback): R; +// TODO(): document. don't forget about @inheritDoc +export function withLogContext(config: PartialRLogConfig, callback: ContextCallback): R; + +// will run the callback right away +// will catch errors so we can close context, but will rethrow them after +// TODO(): document +export function withLogContext(arg1: PartialRLogConfig | ContextCallback, arg2?: ContextCallback): R { + if (isContextCallback(arg1)) { + const createdContext = LogContext.start(); + try { + return arg1(createdContext); + } finally { + createdContext.stop(); + } + } else if (isContextCallback(arg2)) { + const createdContext = LogContext.start(arg1); + + try { + return arg2(createdContext); + } finally { + createdContext.stop(); + } + } else { + error(`withLogContext called with invalid arguments:\narg1:"${arg1}"\narg2:"${arg2}"`); + } +} + +// TODO(): document +export async function withLogContextAsync(callback: ContextCallback>): Promise; +// TODO(): document. don't forget about @inheritDoc +export async function withLogContextAsync( + config: PartialRLogConfig, + callback: ContextCallback> +): Promise; + +// will run the callback right away +// will catch errors so we can close context, but will rethrow them after +// TODO(): document +export async function withLogContextAsync( + arg1: PartialRLogConfig | ContextCallback>, + arg2?: ContextCallback> +): Promise { + if (isContextCallback(arg1)) { + const createdContext = LogContext.start(); + + return arg1(createdContext).finally(() => { + createdContext.stop(); + }) as Promise; + } else if (isContextCallback(arg2)) { + const createdContext = LogContext.start(arg1); + + return arg2(createdContext).finally(() => { + createdContext.stop(); + }) as Promise; + } else { + return Promise.reject( + `withLogContext called with invalid arguments:\narg1:"${arg1}"\narg2:"${arg2}"` + ) as Promise; + } +} + +// TODO(): document +export class LogContext { + private _dead: boolean = false; + + public IsDead() { + return this._dead; + } + + constructor( + public readonly correlation_id: string, + public readonly config: RLogConfig + ) {} + + public withConfig(config: PartialRLogConfig) { + if (this._dead) error("Attempted to use a dead LogContext via `LogContext.withConfig`"); + + return new LogContext(this.correlation_id, mergeConfigs(this.config, config)); + } + + public use(config?: PartialRLogConfig) { + if (this._dead) error("Attempted to use a dead LogContext via `LogContext.use`"); + + return new rLog(config, this); + } + + public stop() { + this._dead = true; + LogContextManager.flush(this); + } + + public static start(config?: PartialRLogConfig): LogContext { + const finalConfig = mergeConfigs(config); + const id = GenerateCorrelationID(finalConfig); + + return new LogContext(id, finalConfig); + } +} + +/** + * Class for faciliating Roblox Logging. + * + * You can also use {@link rlog} or {@link rLog}- for style purposes. + * + * @public + */ +export class RLog { + /** + * @internal + */ + public _config: RLogConfig; + + /** + * TODO(): document + */ + public readonly context: LogContext | undefined; + + /** + * The default or "global" {@link RLog} instance. + * + * All loggers inherit from this, so it's a convenient way for + * attaching global sinks, enrichers, or configuration. + */ + public static readonly default = new RLog({ sinks: [robloxConsoleSink()] }, undefined); + + /** + * Constructs a new {@link RLog} instance. + * + * Uses the provided table in place of the argument names. + */ + public constructor({ config, context, inheritDefault }: RLogConstructorParameters); + + /** + * Constructs a new {@link RLog} instance. + * + * @param config - Configuration settings to use for this logger instance. + * + */ + public constructor(config?: PartialRLogConfig, context?: LogContext, inheritDefault?: boolean); + + /** + * Constructs a new {@link RLog} instance. + * + * See the other constructors for more details. + */ + public constructor( + config: PartialRLogConfig | RLogConstructorParameters = {}, + context?: LogContext, + inheritDefault: boolean = true + ) { + if (isConstructorParameters(config)) { + context = config.context; + inheritDefault = config.inheritDefault ?? true; + config = config.config ?? {}; + } + + this._config = mergeConfigs(inheritDefault ? RLog.default?._config : undefined, context?.config, config); + if (context) { + this.context = new LogContext(context.correlation_id, this._config); + } + } + + /** + * Sets the config for the {@link RLog.default | default} instance. + * + * Since all {@link RLog} instances inherit their config from the default instance, + * this is a convenient way to provide default configuration settings. + * + * _Note that this will **not** change the config for instances already created._ + * + * @param config - The {@link RLogConfig} to use. + * + * @example + * ```ts + * RLog.SetDefaultConfig({ { serialization: { encodeFunctions: true } } }); + * + * // Inherits the `encodeFunctions` setting automatically + * const logger = new RLog({ serialization: { encodeRobloxTypes: false } }); + * + * logger.i("Player died", { player: player, location: player.Position, revive: () => {} }); + * // > [INFO]: Player died + * // > { "data": { "player": 1338, "location": "", "revive": "" } } + * ``` + */ + public static SetDefaultConfig(config: PartialRLogConfig) { + this.default._config = mergeConfigs(config); + } + + public static UpdateDefaultConfig(config: PartialRLogConfig) { + this.default._config = mergeConfigs(this.default._config, config); + } + + public static ResetDefaultConfig() { + this.default._config = mergeConfigs({ sinks: [robloxConsoleSink()] }); + } + + /** + * Creates a new {@link RLog} instance with all the same settings and properties. + * + * Everything is deep copied, so any mutations to the original will safely not replicate. + * + * @returns A duplicate of this {@link RLog} instance. + */ + public clone(): RLog; + + /** + * Creates a new {@link RLog} instance with all the same settings and properties. + * + * The provided {@link RLogConstructorParameters | parameters} will be merged with + * the existing parameters on this instance. + * + * Everything is deep copied, so any mutations to the original will safely not replicate. + * + * @returns A duplicate of this {@link RLog} instance. + */ + public clone({ config, context }: RLogConstructorParameters): RLog; + + /** + * Creates a new {@link RLog} instance with all the same settings and properties. + * + * Everything is deep copied, so any mutations to the original will safely not replicate. + * + * @param params - Optionally provide new arguments to merge with the new instance. + * + * @returns A duplicate of this {@link RLog} instance. + */ + public clone(params: RLogConstructorParameters = {}): RLog { + const config = mergeConfigs(this._config, params.config); + + return new RLog({ config: config, context: this.context }); + } + + /** + * Logs a message with a specified log level. + * + * @param level - The log level. + * @param message - The log message. + * @param data - Optional data to log. Will be encoded according to this logger's {@link RLogConfig | config}. + * + * @see {@link RLog.verbose | verbose}, {@link RLog.debug | debug}, {@link RLog.info | info}, {@link RLog.warning | warning}, {@link RLog.error | error} + */ + public log(level: LogLevel, message: string, data: LogData = {}) { + let isOverride = false; + if (this._config.minLogLevel > level) { + if (!this.context || !this._config.contextBypass) return; + isOverride = true; + } + + const isFlag = this.context && level >= LogLevel.WARNING; + + const baseEntry: LogEntry = { + level: level, + message: message, + data: data, + encoded_data: serialize(this._config.serialization, data), + config: this._config, + context: this.context, + timestamp: DateTime.now().UnixTimestampMillis, + source_metadata: extractSourceMetadata(), + }; + + const enrichedEntry = enrich(baseEntry, this._config.enrichers ?? []); + + if (isOverride) { + // enrichers could remove the context, which is allowed + if (baseEntry.context) { + LogContextManager.save(baseEntry, baseEntry.context); + } + } else { + if (isFlag) { + LogContextManager.flag(baseEntry); + } + if (baseEntry.config.suspendContext && baseEntry.context) { + LogContextManager.push(baseEntry, baseEntry.context); + } else { + sink(enrichedEntry, baseEntry.config.sinks ?? []); + } + } + } + + /** + * Logs a verbose message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.v | v} + */ + public verbose(message: string, data: LogData = {}) { + this.log(LogLevel.VERBOSE, message, data); + } + + /** + * Shorthand version of {@link RLog.verbose | verbose}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + public v(message: string, data: LogData = {}) { + this.verbose(message, data); + } + + /** + * Logs a debug message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.d | d} + */ + public debug(message: string, data: LogData = {}) { + this.log(LogLevel.DEBUG, message, data); + } + + /** + * Shorthand version of {@link RLog.debug | debug}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + public d(message: string, data: LogData = {}) { + this.debug(message, data); + } + + /** + * Logs an informational message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.i | i} + */ + public info(message: string, data: LogData = {}) { + this.log(LogLevel.INFO, message, data); + } + + /** + * Shorthand version of {@link RLog.info | info}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + public i(message: string, data: LogData = {}) { + this.info(message, data); + } + + /** + * Logs a warning message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.w | w}, {@link RLog.warn | warn} + */ + public warning(message: string, data: LogData = {}) { + this.log(LogLevel.WARNING, message, data); + } + + /** + * Shorthand version of {@link RLog.warning | warning}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + public warn(message: string, data: LogData = {}) { + this.warning(message, data); + } + + /** + * Shorthand version of {@link RLog.warning | warning}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + public w(message: string, data: LogData = {}) { + this.warning(message, data); + } + + /** + * Logs an error message. + * + * @param message - The message to log. + * @param data - Optional data to log. + * + * @see {@link RLog.e | e} + */ + public error(message: string, data: LogData = {}) { + this.log(LogLevel.ERROR, message, data); + } + + /** + * Shorthand version of {@link RLog.error | error}. + * + * @param message - The message to log. + * @param data - Optional data to log. + */ + public e(message: string, data: LogData = {}) { + this.error(message, data); + } + + /** + * Returns a new {@link RLog} with the config merged with the existing config. + * + * You can use this to toggle certain features on {@link RLog.child | child} instances, or + * conditionally apply certain configurations. + * + * @param config - Configuration settings to apply to the new instance. + * + * @returns The new {@link RLog} instance + * + * @example + * ```ts + * let logger = new RLog({ minLogLevel: LogLevel.DEBUG }); + * + * const data = { position: new Vector2(5, 10) }; + * + * logger.v("Hello verbose!", data); + * logger.d("Hello debug!", data); + * // > [DEBUG]: Hello debug! + * // > { data: { position: { X: 5, Y: 10 } } } + * + * // Inherits the minLogLevel + * logger = logger.withConfig({ serialization: { encodeRobloxTypes: false } }); + + * logger.v("Hello verbose!", data); + * logger.d("Hello debug!", data); + * // > [DEBUG]: Hello debug! + * // > { data: { position: "" } } + * ``` + */ + public withConfig(config: PartialRLogConfig): RLog { + return this.clone({ config: config }); + } + + /** + * Returns a new {@link RLog} with the minLogLevel set to `minLogLevel`. + * + * Messages below the minimum level will be ignored. + * + * You can also set this in the {@link RLogConfig | config}, this method is purely + * provided as a means for easier changing. + * + * @param minLevel - The {@link LogLevel} to allow logs for. + * + * @returns The new {@link RLog} instance + * + * @example + * ```ts + * let logger = new RLog(); + * + * logger.v("Hello verbose!"); + * logger.d("Hello debug!"); + * // > [VERBOSE]: Hello verbose! + * // > [DEBUG]: Hello debug! + * + * logger = logger.withMinLogLevel(LogLevel.DEBUG); + + * logger.v("Hello verbose!"); + * logger.d("Hello debug!"); + * // > [DEBUG]: Hello debug! + * ``` + */ + public withMinLogLevel(minLevel: LogLevel): RLog { + return this.clone({ config: { minLogLevel: minLevel } }); + } + + /** + * Returns a new {@link RLog} with the tag set to `tag`. + * + * Tags are appended to log messages when present, for easier filtering. + * + * Usually, they're used at the class level to keep track of all logs + * facilitated by a single class + * + * @param tag - The new tag to use. + * + * @returns The new {@link RLog} instance. + * + * @example + * ```ts + * let logger = new RLog(); + * + * logger.d("Hello world!"); + * // > [DEBUG]: "Hello world!" + * + * logger = logger.withTag("main"); + * + * logger.d("Hello world!"); + * // > [DEBUG]: main -> "Hello world!" + * ``` + */ + public withTag(tag: string): RLog { + return this.clone({ config: { tag: tag } }); + } + + // TODO(): document + public withContext(context: LogContext): RLog { + return this.clone({ context: context }); + } +} + +/** + * Mapping to {@link RLog} + * + * @public + */ +export const rlog = RLog; + +/** + * Mapping to {@link RLog} + * + * @public + */ +export const rLog = RLog; + +/** + * Mapping to {@link RLog.default} for easier default usage. + * + * TODO(): Update docs and use places to use this instead + * + * @public + */ +export const rLogger = RLog.default; diff --git a/src/serialization/index.ts b/src/serialization/index.ts new file mode 100644 index 0000000..ca3e67c --- /dev/null +++ b/src/serialization/index.ts @@ -0,0 +1,171 @@ +import Object from "@rbxts/object-utils"; +import { HttpService } from "@rbxts/services"; +import { t } from "@rbxts/t"; +import { LogData } from "../common"; +import { SerializationConfig } from "../configuration"; + +/** + * Encodes an element to a JSON string. + * + * Internally just wraps around {@link HttpService.JSONEncode} to avoid + * errors. + * + * @param element - The element to encode. + * + * @returns The JSON string, or undefined if encoding fails. + */ +function encodeToJson(element: unknown): string | undefined { + try { + return HttpService.JSONEncode(element); + } catch (e) { + return undefined; + } +} + +/** + * Encodes an element to a JSON string or returns the element as a string. + * + * Variant of {@link encodeToJson} that calls {@link tostring} on failure. + * + * @param element - The element to encode. + * + * @returns The JSON string if encoding is successful, otherwise the result of + * calling {@link tostring} on the element. + * + * @internal + */ +export function encodeToJsonOrString(element: unknown): string { + return encodeToJson(element) ?? tostring(element); +} + +/** + * Serializes specific Roblox types to a a valid JSON representation. + * + * @param value - The value to serialize. + * + * @returns A valid JSON representation of the value, or undefined if the type is not supported. + */ +function serializeRobloxType(value: unknown): EncodableValue | undefined { + if (typeIs(value, "Vector3")) { + return { + X: value.X, + Y: value.Y, + Z: value.Z, + }; + } + + if (typeIs(value, "Vector2")) { + return { + X: value.X, + Y: value.Y, + }; + } + + if (typeIs(value, "Instance")) { + return value.GetFullName(); + } + + if (typeIs(value, "EnumItem")) { + return tostring(value); + } + + if (typeIs(value, "CFrame")) { + return `CFrame(${value.GetComponents().join(", ")})`; + } + + return undefined; +} + +/** + * Helper type to force typescript to let us call methods on {@link object objects}. + */ +type ElementWithEncodeCallback = { + [any: string]: unknown; +}; + +/** + * Values that can be present in an {@link object} and properly encoded + * to JSON. + */ +type EncodableValue = string | number | boolean | object; + +function isArray(element: unknown): element is defined[] { + return t.array(t.any)(element); +} + +/** + * Encodes a table element according to the {@link config}. + * + * This method also catches self reference and converts them to `` + * to avoid stack overflows. Although, if there's more complex cyclic references, + * this will not catch them. + * + * @param config - The serialization configuration. + * @param element - The table element to encode. + * + * @returns A valid value that can be encoded into a JSON element. + */ +function encodeTable(config: SerializationConfig, element: object): EncodableValue { + if (config.encodeMethod in element) { + const method = (element as ElementWithEncodeCallback)[config.encodeMethod]; + if (typeIs(method, "function")) { + return method() as object; + } + } + + if (isArray(element)) return element.map((it: unknown) => encodeToObjectOrString(config, it)); + + if (!config.deepEncodeTables) return element; + + const newElement: Record = {}; + + for (const [key, value] of Object.entries(element)) { + if (value === element) { + newElement[`${key}`] = ``; + } else { + newElement[`${key}`] = encodeToObjectOrString(config, value); + } + } + + return newElement; +} + +/** + * Encodes an element to a valid JSON element according to the {@link config}. + * + * @param config - The serialization configuration. + * @param element - The element to encode. + * + * @returns An encodable value or undefined if the element cannot be encoded. + */ +function encodeToObjectOrString(config: SerializationConfig, element: unknown): EncodableValue | undefined { + const elementType = typeOf(element); + + switch (elementType) { + case "number": + case "string": + case "boolean": + return element as EncodableValue; + case "table": { + return encodeTable(config, element as object); + } + case "function": { + return config.encodeFunctions ? "" : undefined; + } + default: { + if (!config.encodeRobloxTypes) return `<${elementType}>`; + + return serializeRobloxType(element) ?? `<${elementType}>`; + } + } +} + +/** + * Public facing serialization. Converts to valid json according to config. + */ +export function serialize(config: SerializationConfig, element: LogData): LogData { + const encodedElement = encodeToObjectOrString(config, element); + + // TODO(): refactor so this cast isn't needed + return encodedElement as LogData; +} diff --git a/src/services.d.ts b/src/services.d.ts new file mode 100644 index 0000000..879f1e8 --- /dev/null +++ b/src/services.d.ts @@ -0,0 +1,11 @@ +// declare module "@rbxts/testez/globals" { +// interface CustomMatchers { +// contain(value: unknown): { pass: boolean; message: string }; +// } +// } + +// declare module "@rbxts/testez/globals" { +// interface Expectation { +// contain(received: unknown[], expected: unknown[]): { pass: boolean; message: string }; +// } +// } diff --git a/src/sinks/index.ts b/src/sinks/index.ts new file mode 100644 index 0000000..0d3f073 --- /dev/null +++ b/src/sinks/index.ts @@ -0,0 +1 @@ +export { robloxConsoleSink } from "./roblox-console-sink"; diff --git a/src/sinks/roblox-console-sink.ts b/src/sinks/roblox-console-sink.ts new file mode 100644 index 0000000..5ba384d --- /dev/null +++ b/src/sinks/roblox-console-sink.ts @@ -0,0 +1,60 @@ +import Object from "@rbxts/object-utils"; +import { HttpService } from "@rbxts/services"; +import { LogEntry, LogLevel } from "../common"; + +/** + * Type representing a callback function for converting log entries to output. + * + * @param entry - The log entry to convert. + * + * @returns Any amount of arguments to output in the entry's place + * + * @public + */ +export type FormatMethodCallback = (entry: LogEntry) => LuaTuple; + +// TODO(): document +export type OutputMethodCallback = (entry: LogEntry, messages: LuaTuple) => void; + +// TODO(): document +export type RobloxConsoleSinkConfig = { + formatMethod?: FormatMethodCallback; + outputMethod?: OutputMethodCallback; + minLogLevel?: LogLevel; + disable?: boolean; +}; + +// TODO(): document +export function robloxConsoleSink({ formatMethod, outputMethod, minLogLevel, disable }: RobloxConsoleSinkConfig = {}) { + return (entry: LogEntry) => { + if (disable) return; + if (minLogLevel !== undefined && entry.level < minLogLevel) return; + + const formatEntry = formatMethod ?? defaultFormatEntry; + const outputEntry = outputMethod ?? defaultOutputEntry; + + const output = formatEntry(entry); + + outputEntry(entry, output); + }; +} + +const defaultOutputEntry: OutputMethodCallback = (entry, messages) => { + if (entry.level >= LogLevel.WARNING) { + warn(...messages); + } else { + print(...messages); + } +}; + +function defaultFormatEntry(entry: LogEntry) { + const tag = entry.config.tag !== undefined ? `${entry.config.tag} -> ` : ""; + + const data = { + correlation_id: entry.context?.correlation_id, + timestamp: entry.timestamp, + data: Object.isEmpty(entry.encoded_data) ? undefined : entry.encoded_data, + }; + + return $tuple(`[${LogLevel[entry.level]}]:`, `${tag}${entry.message}\n${HttpService.JSONEncode(data)}`); +} diff --git a/src/tests/matchers.ts b/src/tests/matchers.ts new file mode 100644 index 0000000..ead449e --- /dev/null +++ b/src/tests/matchers.ts @@ -0,0 +1,120 @@ +/// + +import Object from "@rbxts/object-utils"; +import { HttpService } from "@rbxts/services"; + +function tryToEncode(element: defined) { + try { + return HttpService.JSONEncode(element); + } catch (e) { + return tostring(element); + } +} + +const contain: CustomMatchers = (source: defined[], value: defined) => { + const pass = source.includes(value); + + return { + pass: pass, + message: `Expected ${tryToEncode(source)} to include ${value}`, + }; +}; + +// handles arrays, but not as you'd expect. should probably fix that +function deepChecker( + prefix: string, + source: Record, + other: Record, + checkInverse: boolean = true +): string | undefined { + if (typeOf(other) !== "table") return `Expected a table, but was something else: "${typeOf(other)}" (${other})`; + + const sourceMembers = Object.entries(source); + const destMembers = Object.entries(other); + + for (const [key, value] of sourceMembers) { + const otherValue = other[key]; + const thisType = typeOf(value); + const otherType = typeOf(otherValue); + + if (otherType === "nil") { + return `Expected "${prefix}${key}" to be present, but it was missing.`; + } + + if (thisType !== otherType) { + return `Expected "${prefix}${key}" to be of type "${thisType}" (${value}), but was "${otherType}" (${otherValue}) instead.`; + } + + if (thisType === "table") { + const result = deepChecker(`${key}.`, value, otherValue as Record, checkInverse); + if (result !== undefined) return result; + } else if (value !== otherValue) { + return `Expected "${prefix}${key}" to equal ${value}, but it was ${otherValue} instead.`; + } + } + + if (checkInverse) { + for (const [key, value] of destMembers) { + if (source[key] === undefined) { + return `Did not expect "${prefix}${key}" (${value}) to be present.`; + } + } + } +} + +const deepEqualMatcher: CustomMatchers = (source: defined, value: defined) => { + const result = deepChecker("", source, value); + + return { + pass: result === undefined, + message: result, + }; +}; + +const matchObjectMatcher: CustomMatchers = (source: defined, value: defined) => { + const result = deepChecker("", value, source, false); + + return { + pass: result === undefined, + message: result, + }; +}; + +type InferArrayElement = T extends (infer U)[] ? U : never; + +interface Checker { + readonly to: Checker; + readonly be: Checker; + readonly been: Checker; + readonly have: Checker; + readonly was: Checker; + readonly at: Checker; + readonly never: Checker; + + a: (typeName: ReturnType) => Checker; + an: (typeName: ReturnType) => Checker; + ok: () => Checker; + equal: (otherValue: unknown) => Checker; + near: (this: Checker, otherValue: number, limit?: number) => Checker; + throw: (this: Checker, search?: string) => Checker; + contain: (this: Checker, value: InferArrayElement) => Checker; + deepEqual: (this: Checker, value: T) => Checker; + matchObject: (this: Checker, value: unknown) => Checker; + // some: (this: Checker, values: T) => Checker; +} + +let exp = expect; + +export function check(value: T): Checker { + return exp(value) as unknown as Checker; +} + +export function bind(source: typeof expect) { + source.extend({ + contain: contain, + deepEqual: deepEqualMatcher, + matchObject: matchObjectMatcher, + }); + + exp = source; +} diff --git a/src/tests/rlog.spec.ts b/src/tests/rlog.spec.ts new file mode 100644 index 0000000..dc9569f --- /dev/null +++ b/src/tests/rlog.spec.ts @@ -0,0 +1,620 @@ +/// +import Object, { deepEquals } from "@rbxts/object-utils"; +import { HttpService, LogService } from "@rbxts/services"; +import { includes, startsWith } from "@rbxts/string-utils"; +import { t } from "@rbxts/t"; +import { LogData, LogEntry, LogLevel, SourceMetadata } from "../common"; +import { LogContextManager } from "../context"; +import { LogContext, rlog, withLogContext } from "../rlog"; +import { bind, check } from "./matchers"; + +// TODO(): maybe split into separate files? + +type LoggedMessage = { + level: LogLevel; + text: string; + data?: T; + extra: { + source_metadata?: SourceMetadata; + timestamp: number; + correlation_id?: string; + }; +}; + +const mustBeALogLevel = t.keyOf(LogLevel); + +const MessageFormat = "%[(%a+)%]:%s(.+)\n(.+)"; + +// TODO(): Future work -> assertions library? also need a deepcopy that exports better messages +// eg; deepCopy({x: 5}, {x: "5"}) -> Expected "x" to be 5 (number) but was "5" (string) instead + +// TODO(): clean this shit up jesus +// TODO(): add tests for provided sinks and enrichers whenever I split this up +export = () => { + function parseMessage(message: string) { + const [level, text, extra] = message.match(MessageFormat); + assert(mustBeALogLevel(level)); + assert(t.string(text)); + assert(t.string(extra)); + + const data = HttpService.JSONDecode(extra) as LogData; + + assert(t.number(data.timestamp)); + + return { + level: LogLevel[level], + text: text, + data: data["data"] as LogData, + extra: { + ...data, + }, + }; + } + + const messages: string[] = []; + + function getMessages>(canBeEmpty: boolean = false): LoggedMessage[] { + task.wait(); + + const history = [...messages]; + if (!canBeEmpty) check(history.isEmpty()).to.equal(false); + + return history.map((it) => parseMessage(it)) as LoggedMessage[]; + } + + beforeAll(() => { + bind(expect); + LogService.MessageOut.Connect((message) => { + messages.push(message); + }); + }); + + beforeEach(() => { + task.wait(); + messages.clear(); + LogContextManager.clear(); + rlog.ResetDefaultConfig(); + + task.wait(); + }); + + describe("loggers", () => { + it("should output to the console", () => { + const logger = new rlog(); + + logger.log(LogLevel.INFO, "Hello world!"); + + task.wait(); + check(messages.isEmpty()).to.equal(false); + + const message = messages[0]; + check(includes(message, "Hello world!")).to.equal(true); + }); + + it("should output data", () => { + const logger = new rlog(); + + logger.log(LogLevel.INFO, "Hello world!", { person: "me!" }); + + const message = getMessages()[0]; + + check(message?.data?.["person"]).to.equal("me!"); + }); + + it("should respect all the log levels", () => { + const logger = new rlog(); + + for (const level of Object.values(LogLevel)) { + logger.log(level, LogLevel[level]); + } + + const messages = getMessages(); + + for (const message of messages) { + check(LogLevel[message.level]).to.equal(message.text); + } + }); + + it("should use the correct log levels", () => { + const logger = new rlog(); + + logger.v("VERBOSE"); + logger.verbose("VERBOSE"); + + logger.i("INFO"); + logger.info("INFO"); + + logger.d("DEBUG"); + logger.debug("DEBUG"); + + logger.w("WARNING"); + logger.warn("WARNING"); + logger.warning("WARNING"); + + logger.e("ERROR"); + logger.error("ERROR"); + + const messages = getMessages(); + + for (const message of messages) { + check(LogLevel[message.level]).to.equal(message.text); + } + }); + + it("should not log below min log level", () => { + const logger = new rlog({ minLogLevel: LogLevel.WARNING }); + + for (const level of Object.values(LogLevel)) { + logger.log(level, "Message"); + } + + const messages = getMessages(); + + const possibleLevels = [LogLevel.WARNING, LogLevel.ERROR]; + + for (const message of messages) { + check(possibleLevels).to.contain(message.level); + } + }); + + it("should use tags", () => { + const logger = new rlog().withTag("cool"); + + logger.i("Message"); + + const message = getMessages()[0]; + + check(startsWith(message.text, "cool")).to.equal(true); + }); + + it("should inherit default settings", () => { + rlog.SetDefaultConfig({ minLogLevel: LogLevel.ERROR }); + const logger = new rlog({ serialization: { encodeRobloxTypes: false } }); + + check(logger._config).to.matchObject({ + minLogLevel: LogLevel.ERROR, + serialization: { + encodeRobloxTypes: false, + }, + }); + }); + + it("should override default settings", () => { + rlog.SetDefaultConfig({ minLogLevel: LogLevel.ERROR }); + const logger = new rlog({ minLogLevel: LogLevel.WARNING }); + + check(logger._config.minLogLevel).to.equal(LogLevel.WARNING); + }); + + it("should merge configs", () => { + const main = new rlog({ serialization: { encodeFunctions: true } }); + const secondary = main.withConfig({ serialization: { encodeRobloxTypes: false } }); + + const data = { + position: new Vector2(5, 10), + callback: () => {}, + }; + + secondary.i("Message", data); + + const message = getMessages()[0]; + + check(message.data).to.matchObject({ + position: "", + callback: "", + }); + }); + }); + + describe("serialization", () => { + it("should serialize nested tables", () => { + const logger = new rlog({ serialization: { deepEncodeTables: true } }); + + const data = { player: { name: "daymon", position: new Vector3(1, 2, 3) } }; + + logger.i("Message", data); + + const message = getMessages()[0]; + + check(message.data).to.matchObject({ + player: { + name: "daymon", + position: { X: 1, Y: 2, Z: 3 }, + }, + }); + }); + + it("should not serialize nested tables", () => { + const logger = new rlog({ serialization: { deepEncodeTables: false } }); + + const data = { player: { name: "daymon", position: new Vector3(1, 2, 3) } }; + + logger.i("Message", data); + + const message = getMessages()[0]; + + check(message.data?.player.name).to.equal(data.player.name); + check(message.data?.player.position).to.equal(undefined); + }); + + it("should serialize functions", () => { + const logger = new rlog({ serialization: { encodeFunctions: true } }); + + logger.i("Message", { callback: () => {} }); + + const message = getMessages()[0]; + + check(message.data?.callback).to.equal(""); + }); + + it("should not serialize functions", () => { + const logger = new rlog({ serialization: { encodeFunctions: false } }); + + logger.i("Message", { callback: () => {} }); + + const message = getMessages()[0]; + + check(message.data?.callback).to.equal(undefined); + }); + + it("should serialize roblox types", () => { + const logger = new rlog({ serialization: { encodeRobloxTypes: true } }); + + const data = { position: new Vector2(1, 2) }; + + logger.i("Message", data); + + const message = getMessages()[0]; + + const position = message.data?.position as object; + + check(deepEquals(position, { X: 1, Y: 2 })).to.equal(true); + }); + + it("should not serialize roblox types", () => { + const logger = new rlog({ serialization: { encodeRobloxTypes: false } }); + + const data = { position: new Vector2(1, 2) }; + + logger.i("Message", data); + + const message = getMessages()[0]; + + check(message.data?.position).to.equal(""); + }); + + it("should call the proper encode method", () => { + const playerInstance = { + name: "Nuketown", + year: 2025, + + encode: () => { + return playerInstance.name; + }, + }; + + const logger = new rlog({ serialization: { encodeMethod: "encode" } }); + + const data = { player: { instance: playerInstance } }; + + logger.i("Message", data); + + const message = getMessages()[0]; + + check(message.data?.player?.instance).to.equal(playerInstance.encode()); + }); + + it("should catch self references", () => { + const logger = new rlog(); + + const data = { name: "daymon", owner: {} }; + data.owner = data; + + logger.i("Message", data); + + const message = getMessages()[0]; + + check(message.data?.name).to.equal(data.name); + check(message.data?.owner).to.equal(""); + }); + + it("should serialize complex types", () => { + const logger = new rlog({ + serialization: { encodeFunctions: true, encodeRobloxTypes: true }, + }); + + const data = { + name: "michael jackson", + son: {}, + age: 50, + location: { + position: new Vector3(1, 2, 3), + rotation: CFrame.Angles(1, 2, 3), + }, + foods: ["pizza", "chicken", "ice cream"], + songs: [ + { + chart: 1, + name: "Billie Jean", + streams: { + daily: 1_275_673, + total: 1_825_629_259, + locations: [new Vector3(1, 0, 1), new Vector2(9, 5)], + }, + }, + { + chart: 4, + name: "Thriller", + streams: { + daily: 282_714, + total: 613_444_407, + locations: [new Vector3(1, 0, 1), new Vector2(9, 5)], + }, + }, + { + chart: 15, + name: "Chicago", + streams: { + daily: 297_643, + total: 283_537_103, + locations: [new Vector3(1, 0, 1), new Vector2(9, 5)], + }, + }, + ], + extra: { + spawn: game.Workspace.CurrentCamera, + lighting: 3.14159, + video_status: Enum.AdEventType.VideoLoaded, + present: false, + sing: () => {}, + }, + }; + data.son = data; + + const expectedResult = { + ...data, + son: "", + location: { + position: { X: 1, Y: 2, Z: 3 }, + rotation: `CFrame(${data.location.rotation.GetComponents().join(", ")})`, + }, + songs: data.songs.map((it) => ({ + ...it, + streams: { + ...it.streams, + locations: [ + { X: 1, Y: 0, Z: 1 }, + { X: 9, Y: 5 }, + ], + }, + })), + extra: { + ...data.extra, + spawn: "Workspace.Camera", + video_status: "Enum.AdEventType.VideoLoaded", + sing: "", + }, + }; + + logger.i("Message", data); + + const message = getMessages()[0]?.data as object; + + check(deepEquals(message, expectedResult)).to.equal(true); + }); + }); + + describe("sinks", () => { + it("should consume messages", () => { + const sink = () => { + return true; + }; + + const logger = new rlog({ sinks: [sink] }); + + logger.i("Message"); + + const messages = getMessages(true); + + check(messages.isEmpty()).to.equal(true); + }); + + it("should pass messages", () => { + let called = false; + const firstSink = () => { + return false; + }; + + const secondSink = () => { + called = true; + return false; + }; + + const logger = new rlog({ sinks: [firstSink, secondSink] }); + + logger.i("Message"); + + const messages = getMessages(true); + + check(messages.isEmpty()).to.equal(false); + check(called).to.equal(true); + }); + }); + + describe("enrichers", () => { + it("should change type", () => { + const enricher = (entry: LogEntry) => { + entry.message = "changed"; + return entry; + }; + + const logger = new rlog({ enrichers: [enricher] }); + + logger.i("Message"); + + const message = getMessages()[0]; + + check(message.text).to.equal("changed"); + }); + + it("should pass messages", () => { + const firstEnricher = (entry: LogEntry) => { + entry.message = "changed"; + return entry; + }; + + const secondEnricher = (entry: LogEntry) => { + entry.message = `${entry.message}2`; + return entry; + }; + + const logger = new rlog({ enrichers: [firstEnricher, secondEnricher] }); + + logger.i("Message"); + + const message = getMessages()[0]; + + check(message.text).to.equal("changed2"); + }); + }); + + describe("context", () => { + it("should generate correlation ids", () => { + const context = LogContext.start(); + + check(context.correlation_id).to.be.ok(); + }); + + it("should use custom generator", () => { + const generate = () => "test"; + + const context = LogContext.start({ correlationGenerator: generate }); + check(context.correlation_id).to.equal("test"); + }); + + it("should create valid rLog instances", () => { + const context = LogContext.start(); + + const logger = context.use(); + + check(logger.context).to.be.ok(); + check(logger.context?.correlation_id).to.equal(context.correlation_id); + }); + + it("should merge configs", () => { + const firstConfig = { minLogLevel: LogLevel.ERROR }; + const secondConfig = { tag: "x", serialization: { encodeRobloxTypes: false } }; + + const context = LogContext.start(firstConfig); + const logger = context.use(secondConfig); + + const combinedConfig = { ...firstConfig, ...secondConfig }; + + check(logger._config).to.matchObject(combinedConfig); + }); + + it("should error when dead", () => { + const context = LogContext.start(); + context.stop(); + + expect(() => context.use()).to.throw("dead"); + expect(() => context.withConfig({})).to.throw("dead"); + }); + + it("should accept new configs", () => { + const context = LogContext.start({ minLogLevel: LogLevel.ERROR }); + const newContext = context.withConfig({ tag: "x" }); + + check(context.correlation_id).to.equal(context.correlation_id); + expect(context.config.tag).to.equal(undefined); + expect(newContext.config.tag).to.equal("x"); + }); + + it("should handle the lifecycle when expected", () => { + const context = withLogContext((newContext) => { + const logger = newContext.use(); + logger.i("Message"); + + return newContext; + }); + + expect(context.IsDead()).to.equal(true); + }); + + it("should output the correlation id", () => { + const context = LogContext.start(); + + const logger = context.use(); + + logger.i("Message"); + + const message = getMessages()[0]; + + expect(message.extra.correlation_id).to.equal(context.correlation_id); + }); + + it("should not mix correlation ids", () => { + const firstContext = LogContext.start(); + const secondContext = LogContext.start(); + + const firstLogger = firstContext.use(); + const secondLogger = secondContext.use(); + + firstLogger.i("Message"); + secondLogger.i("Message"); + + const messages = getMessages(); + + const firstMessage = messages[0]; + const secondMessage = messages[1]; + + expect(firstContext.correlation_id).to.never.equal(secondContext.correlation_id); + expect(firstMessage.extra.correlation_id).to.equal(firstContext.correlation_id); + expect(secondMessage.extra.correlation_id).to.equal(secondContext.correlation_id); + }); + + it("should maintain context when enabled", () => { + const context = LogContext.start(); + + const logger = context.use({ minLogLevel: LogLevel.WARNING, contextBypass: true }); + const otherLogger = new rlog({ minLogLevel: LogLevel.WARNING }); + + otherLogger.info("Message without correlation ID"); + + logger.d("First message"); + logger.d("Second message"); + + const messagesBeforeError = getMessages(true); + expect(messagesBeforeError.isEmpty()).to.equal(true); + + logger.w("Third message"); + logger.d("Fourth message"); + + const messagesAfterError = getMessages(); + expect(messagesAfterError.size()).to.equal(1); + + context.stop(); + + const messagesAfterStop = getMessages(); + expect(messagesAfterStop.size()).to.equal(4); + }); + + it("should suspend context when enabled", () => { + const context = LogContext.start(); + + const logger = context.use({ suspendContext: true }); + + logger.d("First message"); + logger.d("Second message"); + logger.e("Third message"); + + const messagesBeforeStop = getMessages(true); + expect(messagesBeforeStop.isEmpty()).to.equal(true); + + context.stop(); + + const messagesAfterStop = getMessages(); + expect(messagesAfterStop.size()).to.equal(3); + }); + }); +}; diff --git a/src/util/index.ts b/src/util/index.ts new file mode 100644 index 0000000..3466b1f --- /dev/null +++ b/src/util/index.ts @@ -0,0 +1,7 @@ +import { startsWith } from "@rbxts/string-utils"; + +/** @internal */ +export function trimStart(str: string, trim: string): string { + if (startsWith(str, trim)) return str.sub(trim.size()); + return str; +} diff --git a/test.project.json b/test.project.json new file mode 100644 index 0000000..4d78a0b --- /dev/null +++ b/test.project.json @@ -0,0 +1,22 @@ +{ + "name": "package-test", + "globIgnorePaths": ["**/package.json", "**/tsconfig.json"], + "tree": { + "$className": "DataModel", + "ReplicatedStorage": { + "$className": "ReplicatedStorage", + "rbxts_include": { + "$path": "include", + "node_modules": { + "$className": "Folder", + "@rbxts": { + "$path": "node_modules/@rbxts" + } + } + }, + "TS": { + "$path": "out" + } + } + } +} diff --git a/testez-companion.toml b/testez-companion.toml new file mode 100644 index 0000000..d12fce5 --- /dev/null +++ b/testez-companion.toml @@ -0,0 +1,4 @@ +roots = ["ReplicatedStorage/TS"] + +[extraOptions] +timeout = 10 \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8dc5f5d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + // required + "allowSyntheticDefaultImports": true, + "downlevelIteration": true, + "jsx": "react", + "jsxFactory": "Roact.createElement", + "jsxFragmentFactory": "Roact.createFragment", + "module": "commonjs", + "moduleResolution": "node", + "noLib": true, + "resolveJsonModule": true, + "experimentalDecorators": true, + "forceConsistentCasingInFileNames": true, + "moduleDetection": "force", + "strict": true, + "target": "ESNext", + "typeRoots": ["node_modules/@rbxts"], + + // configurable + "rootDir": "src", + "outDir": "out", + "incremental": true, + "tsBuildInfoFile": "out/tsconfig.tsbuildinfo", + "declaration": true, + "declarationMap": true, + }, + "exclude": [ + "example/**/*", + "out/**/*", + "wiki/**/*" + ] +} diff --git a/wiki/.gitignore b/wiki/.gitignore new file mode 100644 index 0000000..b2d6de3 --- /dev/null +++ b/wiki/.gitignore @@ -0,0 +1,20 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/wiki/.prettierrc b/wiki/.prettierrc new file mode 100644 index 0000000..4e7f2d0 --- /dev/null +++ b/wiki/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 120, + "tabWidth": 2, + "trailingComma": "all", + "useTabs": false, + "proseWrap": "always" +} diff --git a/wiki/README.md b/wiki/README.md new file mode 100644 index 0000000..a7f7401 --- /dev/null +++ b/wiki/README.md @@ -0,0 +1,46 @@ +# Website + +This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. + +-- TODO(): update `log` formatting in code snippets for colors. also curious about the `log` format anyhow + +### Installation + +``` +$ yarn +``` + +### Local Development + +``` +$ yarn start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without +having to restart the server. + +### Build + +``` +$ yarn build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting +service. + +### Deployment + +Using SSH: + +``` +$ USE_SSH=true yarn deploy +``` + +Not using SSH: + +``` +$ GIT_USER= yarn deploy +``` + +If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the +`gh-pages` branch. diff --git a/wiki/babel.config.js b/wiki/babel.config.js new file mode 100644 index 0000000..e00595d --- /dev/null +++ b/wiki/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/wiki/docs/advanced/_category_.json b/wiki/docs/advanced/_category_.json new file mode 100644 index 0000000..e02fbd6 --- /dev/null +++ b/wiki/docs/advanced/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Advanced", + "position": 3, + "link": { + "type": "generated-index", + "description": "Advanced aspects of rLog." + } +} diff --git a/wiki/docs/advanced/google-cloud-logging.mdx b/wiki/docs/advanced/google-cloud-logging.mdx new file mode 100644 index 0000000..aec0057 --- /dev/null +++ b/wiki/docs/advanced/google-cloud-logging.mdx @@ -0,0 +1,13 @@ +--- +description: Learn how to get started with Google Cloud Logging in your +--- + +# Google Cloud Logging + +:::warning + +This feature is not yet implemented. + +This page will be filled out when it is. It'll likely be an external package. + +::: diff --git a/wiki/docs/advanced/roblox-console-configuration.mdx b/wiki/docs/advanced/roblox-console-configuration.mdx new file mode 100644 index 0000000..d89df21 --- /dev/null +++ b/wiki/docs/advanced/roblox-console-configuration.mdx @@ -0,0 +1,302 @@ +--- +description: Learn how to configure the roblox console output from your logs. +--- + +# Roblox Console Configuration + +**rLog** provides the `robloxConsoleSink` as a default sink for outputting to the roblox console, with sensible defaults +for formatting and behavior. Sometimes though, you may want to customize this behavior to fit your own use-case. + +:::info what you'll learn + +- How the `robloxConsoleSink` is applied to instances +- How to configure the `robloxConsoleSink` +- How to customize the format of your logs +- How to customize where your logs go +- How to disable console output for certain instances + +::: + +## Configuration + +The `robloxConsoleSink` is (by default) applied on the default instance, but you can manually configure it by overriding +the sink. + +```ts +import { rLog, robloxConsoleSink } from "@rbxts/rlog"; + +rLog.UpdateDefaultConfig({ + sinks: [ + robloxConsoleSink({ + // ... + }), + ], +}); +``` + +The `robloxConsoleSink` function takes an argument of `RobloxConsoleSinkConfig` that you can use to configure special +behavior. + +```ts +export type RobloxConsoleSinkConfig = { + formatMethod?: FormatMethodCallback; + outputMethod?: OutputMethodCallback; + minLogLevel?: LogLevel; + disable?: boolean; +}; +``` + +### Custom Formatting + +The `formatMethod` setting can be used to customize the behavior of converting log entries to output objects. + +```ts +export type FormatMethodCallback = (entry: LogEntry) => LuaTuple; +``` + +Notice how the output type is a `LuaTuple` and _not_ a string? Since the `print` and `warn` globals in roblox allow you +to specify a variable amount of arguments, you can use this to take advantage of certain features the roblox console +provides. + +```ts title="custom-formatter.ts" +import { LogEntry, FormatMethodCallback } from "@rbxts/rlog"; + +export const customFormatMethod: FormatMethodCallback = (entry) => { + return $tuple(entry.message, entry.encoded_data); +}; +``` + +```ts +import { rLog, robloxConsoleSink } from "@rbxts/rlog"; +import { customFormatMethod } from "./custom-formatter"; + +rLog.UpdateDefaultConfig({ + sinks: [ + robloxConsoleSink({ + formatMethod: customFormatMethod, + }), + ], +}); + +const logger = new rLog(); + +logger.i("Hello world!", { time: DateTime.now() }); +``` + +```logs title="Console" +Hello world! ▶ {...} +``` + +By taking advantage of the fact that the roblox console will natively wrap tables, we can create collapsible tables in +our output instead of just the entire output as JSON. + +#### Default Behavior + +You may only want to change something minor in regards to formatting, while retaining the other existing behavior the +`robloxConsoleSink` provides by default. + +While you'll need to implement it all yourself, you can use this function to get an idea of what the default +`formatMethod` does: + +```ts +function defaultFormatEntry(entry: LogEntry) { + const tag = entry.config.tag !== undefined ? `${entry.config.tag} -> ` : ""; + + const data = { + correlation_id: entry.context?.correlation_id, + timestamp: entry.timestamp, + data: Object.isEmpty(entry.encoded_data) ? undefined : entry.encoded_data, + }; + + return $tuple(`[${LogLevel[entry.level]}]:`, `${tag}${entry.message}\n${HttpService.JSONEncode(data)}`); +} +``` + +### Custom Output + +The `outputMethod` setting can be used to customize the behavior of sending the formatted message to the roblox console. + +```ts +export type OutputMethodCallback = (entry: LogEntry, messages: LuaTuple) => void; +``` + +This method will be called after `formatMethod` is called, and is the last destination for the `robloxConsoleSink`. + +```ts title="custom-output.ts" +import { LogEntry, OutputMethodCallback } from "@rbxts/rlog"; + +export const customOutputMethod: OutputMethodCallback = (entry, messages) => { + print(...messages); +}; +``` + +```ts +import { rLog, robloxConsoleSink } from "@rbxts/rlog"; +import { customOutputMethod } from "./custom-output"; + +rLog.UpdateDefaultConfig({ + sinks: [ + robloxConsoleSink({ + outputMethod: customOutputMethod, + }), + ], +}); + +const logger = new rLog(); + +logger.i("Hello world!"); +``` + +```logs title="Console" +[INFO]: Hello world! +``` + +#### Default Behavior + +The default behavior is actually very straightforward. It just checks if the entry is of `WARNING` or higher, and +spreads it out to the relevant global. + +```ts +const defaultOutputEntry: OutputMethodCallback = (entry, messages) => { + if (entry.level >= LogLevel.WARNING) { + warn(...messages); + } else { + print(...messages); + } +}; +``` + +### Min Log Level + +The `minLogLevel` setting can be used to configure the minimum `LogLevel` that actually gets output to the roblox +console. + +This can be useful if you only want to log certain levels to the roblox console, while still allowing them to be ran +through the other sinks you have. + +```ts +import { rLog, robloxConsoleSink, LogLevel } from "@rbxts/rlog"; + +rLog.UpdateDefaultConfig({ + sinks: [ + robloxConsoleSink({ + minLogLevel: LogLevel.DEBUG, + }), + ], +}); + +const logger = new rLog(); + +logger.i("Hello world!"); +logger.d("Goodbye world!"); +``` + +```logs title="Console" +[DEBUG]: Goodbye world! +``` + +### Disabling the Sink + +The `disable` setting will completely disable the roblox sink; messages will not be sent to the roblox console. + +```ts +import { rLog, robloxConsoleSink } from "@rbxts/rlog"; +import { RunService } from "@rbxts/services"; + +rLog.UpdateDefaultConfig({ + sinks: [ + robloxConsoleSink({ + disable: !RunService.IsStudio(), // disable logging during production + }), + ], +}); +``` + +This is mainly provided as a way to temporarily toggle the roblox console, or setup configuration for only logging to +the console under certain situations. + +## Instance Overrides + +Since sinks override one another when merging configs, you can configure unique settings for individual instances. + +For example, maybe I want to exclude data from my console logs- but only for a specific scope. + +```ts title="custom-formatter.ts" +import { LogEntry, FormatMethodCallback } from "@rbxts/rlog"; + +export const customFormatMethod: FormatMethodCallback = (entry) => { + if (entry.context) { + return $tuple(entry.message, { + correlation_id: entry.context.correlation_id, + }); + } else { + return $tuple(entry.message); + } +}; +``` + +```ts title="pets" +import { LogContext, LogConfig, robloxConsoleSink } from "@rbxts/rlog"; +import { customFormatMethod } from "./custom-formatter"; + +const config: LogConfig = { + tag: "Actions", + sinks: [robloxConsoleSink({ formatMethod: customFormatMethod })], +}; + +export function buyPet(context: LogContext, player: PlayerId, pet: PetId) { + const logger = context.use(config); + logger.i("Buying pet", { player: player, pet: pet }); + // ... +} +``` + +```ts +import { withLogContext, LogConfig } from "@rbxts/rlog"; +import { remotes } from "./remotes"; +import { buyPet } from "./pets"; + +const config: LogConfig = { tag: "Remotes" }; + +remotes.buyPet.connect((player: Player, pet: PetId) => { + withLogContext((context) => { + const logger = context.use(config); + logger.i("Player asked to buy a pet", { player: player, pet: pet }); + + buyPet(context, player.UserId, pet); + }); +}); +``` + +```logs title="Console" +[INFO]: Remotes -> Player asked to buy a pet +{ + data: { player: "Player1", pet: "18219" }, + correlation_id: "QQLRSFsPfoTfgD7b" +} + +[INFO]: Actions -> Buying pet +{ correlation_id: "QQLRSFsPfoTfgD7b" } +``` + +## Best Practices + +- **Consider using custom enrichers**: If your intent is to add or remove extra data from the output- then consider + using a custom enricher instead. Customizing the `robloxConsoleSink` is behavior intended for when you have _multiple_ + sinks and want behavior to be different for the roblox console only. +- **Avoid yielding**: As the same with any other sink, you should avoid any yielding behavior in your custom formatting + or output methods, as it could prevent other logs from being properly processed. +- **Be mindful with custom formats**: When providing a `customFormat`, you are responsible for attaching the + `correlation_id`, `timestamp`, and `encoded_data` to your final output. These are things they may cause problems + during debugging should you forget to include them. + +## Summary + +Let's recap what we've learned about customizing the roblox console output: + +- The `robloxConsoleSink` accepts a **config** as a parameter. +- Format methods decide the **shape** of the data output to the console. +- Output methods decide **how** data is output to the console. +- Custom format methods are **responsible** for ensuring all [expected] data is present in the output. +- The `minLogLevel` setting can **prevent** logs from reaching the roblox console while _retaining_ output to other + sinks. diff --git a/wiki/docs/advanced/source-metadata.mdx b/wiki/docs/advanced/source-metadata.mdx new file mode 100644 index 0000000..aa48f73 --- /dev/null +++ b/wiki/docs/advanced/source-metadata.mdx @@ -0,0 +1,194 @@ +--- +description: Learn about the source data that log entries have attached to them. +--- + +# Source Metadata + +Source Metadata is data attached to log entries that represent metadata regarding where the log occurred. + +This data can be useful for better error tracing, or supporting certain features. + +:::info what you'll learn + +- What source metadata is +- How source metadata is attached to logs +- The different components of source metadata + +::: + +## Overview + +At its core, source metadata is just a simple type. + +```ts +export type SourceMetadata = { + function_name?: string; + nearest_function_name?: string; + file_path: string; + line_number: number; +}; +``` + +You can find this type on log entries under the `source_metadata` property. + +```ts +export type LogEntry = { + level: LogLevel; + message: string; + data: LogData; + encoded_data: LogData; + config: Writable; + context?: LogContext; + timestamp: number; + // highlight-next-line + source_metadata: SourceMetadata; +}; +``` + +### Function Name + +The `function_name` property of source metadata contains the name of the function where the log occurred. + +This may be `undefined` if the log occurred in an anonymous function. + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog({ + enrichers: [ + (entry) => { + entry.message = entry.source_metadata.function_name; + return entry; + }, + ], +}); + +function GivePlayerMoney() { + logger.i("Where am I?"); +} + +GivePlayerMoney(); +``` + +```logs title="Console" +[INFO]: GivePlayerMoney +``` + +### Nearest Function Name + +If the instance was created in an anonymous function, it won't have a name. Even if the outer scope was a named +function. + +To solve this, you can use the `nearest_function_name` property instead. + +If the function _does_ have a name though, `nearest_function_name` will point to the same thing as `function_name`. + +:::warning + +If you somehow have a stack full of anonymous functions, it's possible for `nearest_function_name` to be `undefined` as +well. + +::: + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog({ + enrichers: [ + (entry) => { + entry.message = entry.source_metadata.nearest_function_name; + return entry; + }, + ], +}); + +function GivePlayerMoney() { + const doStuff = () => { + logger.i("Where am I?"); + }; + + doStuff(); +} + +GivePlayerMoney(); +``` + +```logs title="Console" +[INFO]: GivePlayerMoney +``` + +Notice how it says `GivePlayerMoney` instead of `doStuff`? This is because `doStuff` is _not_ a named function. It's a +variable that points to an anonymous function.\* + + + *technically it's an arrow function, but in luau it gets transpiled to an anonymous function + + +### File Path + +The `file_path` property of source metadata contains the full path to the file where the log occurred. + +```ts title="ReplicatedStorage/TS/main.ts" +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog({ + enrichers: [ + (entry) => { + entry.message = entry.source_metadata.file_path; + return entry; + }, + ], +}); + +function GivePlayerMoney() { + logger.i("Where am I?"); +} + +GivePlayerMoney(); +``` + +```logs title="Console" +[INFO]: ReplicatedStorage.TS.main +``` + +### Line Number + +The `line_number` property of source metadata contains the line in the file where the log occurred. + +:::info + +For example purposes, we're using the TS line number, but it's _actually_ the line number in the transpiled luau code. + +::: + +```ts {13} showLineNumbers +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog({ + enrichers: [ + (entry) => { + entry.message = `${entry.source_metadata.line_number}`; + return entry; + }, + ], +}); + +function GivePlayerMoney() { + logger.i("Where am I?"); +} + +GivePlayerMoney(); +``` + +```logs title="Console" +[INFO]: 13 +``` + +## Summary + +Let's recap what we've learned about source metadata: + +- It contains data pertaining to **where** the log occurred. +- You can use **nearest_function_name** when dealing with anonymous functions. +- **nearest_function_name** can still be `undefined` in certain situations. +- The **line_number** is the file line number in the _transpiled luau_, not the TS source. diff --git a/wiki/docs/basics/_category_.json b/wiki/docs/basics/_category_.json new file mode 100644 index 0000000..aaf8dec --- /dev/null +++ b/wiki/docs/basics/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Basics", + "position": 2, + "link": { + "type": "generated-index", + "description": "The basics of rLog." + } +} diff --git a/wiki/docs/basics/default-instance.mdx b/wiki/docs/basics/default-instance.mdx new file mode 100644 index 0000000..a494887 --- /dev/null +++ b/wiki/docs/basics/default-instance.mdx @@ -0,0 +1,269 @@ +--- +description: Learn about the default (or global) instance, and how to use it. +--- + +# Default Instance + +If you have no need for Log Context, individual configs, or any of the more advanced features **rLog** provides; then +creating individual instances can be a bit too much. + +The default ("global") instance allows you to set up a single configuration, and use it anywhere. + +:::info what you'll learn + +- What the default instance is +- How to apply global configuration settings +- How configuration inheritance works + +::: + +## Usage + +The default instance is accessible through either `rLog.default` or the `rLogger` alias. + +```ts +import { rLog, rLogger } from "@rbxts/rlog"; + +rLogger.info("Hello world!"); +rLog.default.info("Hello world!"); +``` + +```logs title="Console" +[INFO]: Hello world! + +[INFO]: Hello world! +``` + +## Configuration + +The default instance is the _only_ **rLog** that you can update the config for without creating a new instance. +Individual **rLog** instances are, by design, immutable. + +But in doing so, you have a few different ways of going about it. + +### Set a Config + +The simplest way is "setting" the default config to your own. + +```ts +import { rLog, LogLevel } from "@rbxts/rlog"; + +rLog.SetDefaultConfig({ minLogLevel: LogLevel.DEBUG }); +``` + +This will overwrite the current default config with your own. + +This will also override certain default configurations, such as the roblox console sink. If you _don't_ want to do that, +then the next section is for you. + +### Merge Configs + +The more practical way is "updating" the default config; creating a merge between the existing config and your own. + +```ts +import { rLog, LogLevel } from "@rbxts/rlog"; + +rLog.UpdateDefaultConfig({ minLogLevel: LogLevel.DEBUG }); +``` + +If there's any overlap between the current config and your own, the new config that you provide will take precedence. +But otherwise, everything else will remain the same. + +### Reset the Config + +You'll rarely need to, but if you get into a situation where you want to completely wipe the default config back to its +original settings, you can do that. + +```ts +import { rLog } from "@rbxts/rlog"; + +rLog.ResetDefaultConfig(); +``` + +### Inheritance + +All individual **rLog** instances inherit their settings from the default instance; effectively creating a merged +config. + +```ts +import { rLog, LogLevel } from "@rbxts/rlog"; + +rLog.UpdateDefaultConfig({ minLogLevel: LogLevel.DEBUG }); + +// implicitly has the minLogLevel set to DEBUG +const logger = new rLog({ tag: "MyCoolLogger" }); +``` + +:::warning + +While instances inherit from the default config, they only do so at creation time. + +So if you update or otherwise change the default config _after_ creating an instance, it won't inherit the changes. + +```ts +import { rLog, LogLevel } from "@rbxts/rlog"; + +// does not have its minLogLevel set to DEBUG +// error-next-line +const logger = new rLog({ tag: "MyCoolLogger" }); + +rLog.UpdateDefaultConfig({ minLogLevel: LogLevel.DEBUG }); +``` + +::: + +#### Settings not Inherited + +Some settings are unique in that they are not inherited, or they do so in a specific way. + +##### Tags + +Tags are not inherited at all. So setting a tag on the default instance has practically no effect downstream. + +```ts +import { rLog } from "@rbxts/rlog"; + +rLog.UpdateDefaultConfig({ tag: "Main" }); +const logger = new rLog(); + +rLogger.i("Hello world!"); +logger.i("Goodbye world!"); +``` + +```logs title="Console" +[INFO]: Main -> Hello world! + +[INFO]: Goodbye world! +``` + +##### Sinks & Enrichers + +Sinks and enrichers are applied bottom up, without duplicates. + +This means if a new instance is created with its own sinks; they will run before the default instance sinks. + +:::info + +Bottom-up meaning from the perspective of instances. They still run in the _order_ they're added, but newer instances +have their sinks and enrichers ran before older sinks and enrichers. + +::: + +```ts +import { rLog } from "@rbxts/rlog"; + +rLog.UpdateDefaultConfig({ + enrichers: [ + (entry) => { + entry.message = `${entry.message}1`; + return entry; + }, + ], +}); + +const logger = new rLog({ + enrichers: [ + (entry) => { + entry.message = `${entry.message}2`; + return entry; + }, + ], +}); + +logger.i("Enrichers: "); +``` + +```logs title="Console" +[INFO]: Enrichers: 21 +``` + +Or if a new instance is created with similiar sinks or enrichers to the default instance; those will also run before +others. + +This is what "without duplicates" means. + +```ts +import { rLog, LogEntry } from "@rbxts/rlog"; + +function AddFiveToMessageEnricher(entry: LogEntry): LogEntry { + entry.message = `${entry.message}5`; + return entry; +} + +rLog.UpdateDefaultConfig({ + enrichers: [ + AddFiveToMessageEnricher, + (entry) => { + entry.message = `${entry.message}1`; + return entry; + }, + ], +}); + +const logger = new rLog({ + enrichers: [ + AddFiveToMessageEnricher, + (entry) => { + entry.message = `${entry.message}2`; + return entry; + }, + ], +}); + +logger.i("Enrichers: "); +``` + +```logs title="Console" +[INFO]: Enrichers: 521 +``` + +Even though `AddFiveToMessageEnricher` was added already, re-adding effectively overwrites its position in the enricher +queue. + +#### Disabling Inheritance + +If you have an instance that you don't want to inherit the default configuration for, you can toggle the +`inheritDefault` parameter when creating it. + +```ts +import { rLog } from "@rbxts/rlog"; + +rLog.UpdateDefaultConfig({ + enrichers: [ + (entry) => { + entry.message = `${entry.message}1`; + return entry; + }, + ], +}); + +const logger = new rLog({ inheritDefault: false }); + +logger.i("Enrichers: "); +``` + +```logs title="Console" +[INFO]: Enrichers: +``` + +By default, this parameter is set to `true`; meaning that instances inherit from default. + +## Best Practices + +- **Centrialize global settings**: If you find yourself repeating the same config settings over and over again for every + logger, they may be better defined in the global scope. +- **Keep default usage simple**: The default instance offers a means for quick debugging, and covers simple use cases. + But **rLog** as a whole is generally designed around the principle of shared context- which doesn't really apply when + you only have a single instance. +- **Take advantage of config merging**: Configs are merged by default, so you rarely should need to repeat yourself. + It's more practical to hoist your common settings to a centrialized place- and abuse config merging to keep things + simple. + +## Summary + +Let's recap what we've learned about the default instance: + +- The default instance is the **global** instance of **rLog** that's useful for **simple** usage. +- All individual instances **inherit** their configurations from the global instance. +- Configurations between instances are **merged**, helping you follow DRY principles. +- Sinks and enrichers are ran **bottom-up** _per instance_ and _without_ **duplicates**. diff --git a/wiki/docs/basics/enrichers.mdx b/wiki/docs/basics/enrichers.mdx new file mode 100644 index 0000000..36e4e77 --- /dev/null +++ b/wiki/docs/basics/enrichers.mdx @@ -0,0 +1,304 @@ +--- +description: Learn how to add or mutate data in logs, as they're processed. +--- + +# Enrichers + +Enrichers are powerful tools that allow you to enhance log entries with additional context or metadata. They can be used +to add custom information to each log entry or modify existing data. + +:::info what you'll learn + +- What enrichers are +- How to apply enrichers to your logging setup +- How the order of enrichers affects output +- How to create your own enrichers +- What enrichers **rLog** provides out of the box + +::: + +## What is an Enricher? + +An enricher is a function that takes a log entry as input, and returns a modified log entry. This allows you to add +extra data or transform the log entry in some way before it gets output to the console. + +## Creating enrichers + +Here's a basic example of an enricher that adds a timestamp to each log entry. + +```typescript title="timestamp-enricher.ts" +import { LogEnricherCallback, LogEntry } from "@rbxts/rlog"; + +export const timestampEnricher: LogEnricherCallback = (entry: LogEntry) => { + entry.encoded_data["timestamp"] = DateTime.now(); + return entry; +}; +``` + +:::tip + +**rLog** actually already provides a timestamp property on your logs, but we'll be using this enricher as a base example +regardless; for its simplicity + +::: + +## Using enrichers + +Once you have your enricher created, you can "attach" it to your **rLog** instances via the `enrichers` setting in your +config. + +```ts +import { rLog } from "@rbxts/rlog"; +import { timestampEnricher } from "./timestamp-enricher"; + +const logger = new rLog({ enrichers: [timestampEnricher] }); +``` + +### Order of Enrichers + +Enrichers are applied to logs (or "ran") in the order they are "attached" to the **rLog** instance. + +This means that the output of the first enricher is passed as input to the next one, and so on. + +This allows for complex transformations and data enrichment flows. + +```typescript title="timestamp-enricher.ts" +import { LogEnricherCallback, LogEntry } from "@rbxts/rlog"; + +export const timestampEnricher: LogEnricherCallback = (entry: LogEntry) => { + entry.encoded_data["timestamp"] = DateTime.now(); + return entry; +}; +``` + +```typescript title="transform-timestamp-enricher.ts" +import { LogEnricherCallback, LogEntry } from "@rbxts/rlog"; + +export const transformTimestampEnricher: LogEnricherCallback = (entry: LogEntry) => { + if (typeIs(entry.encoded_data["timestamp"], "number")) { + const ms = DateTime.fromUnixTimestampMillis(entry.encoded_data.timestamp); + const formattedTimestamp = ms.FormatLocalTime("LL", "en-us"); + entry.encoded_data.timestamp = formattedTimestamp; + } + return entry; +}; +``` + +```ts +import { rLog } from "@rbxts/rlog"; +import { timestampEnricher } from "./timestamp-enricher"; +import { transformTimestampEnricher } from "./transform-timestamp-enricher"; + +const logger = new rLog().withEnrichers(timestampEnricher, transformTimestampEnricher); + +logger.i("Hello world!"); +``` + +```logs title="Console" +[INFO]: Hello world! +{ data: { timestamp: "August 14, 2024" } } +``` + +## Enricher Filters + +Not all enrichers need to run for every log entry. + +Since you have access to the entire `LogEntry`, you can make these decisions on a case-by-case basis in your enrichers. + +```ts title="timestamp-enricher.ts" +import { LogEnricherCallback, LogEntry, LogLevel, rLog } from "@rbxts/rlog"; + +export const timestampEnricher: LogEnricherCallback = (entry: LogEntry) => { + // just return the instance without changing anything + if (entry.Level < LogLevel.WARNING) return entry; + // ... +}; +``` + +## Common Use Cases + +Enrichers are versatile and extensive, and can be used to provide a lot of different features. + +### Adding Contextual Information + +You might want to add information like a User ID or Session ID to every log entry. + +```ts +function enricherForPlayer(player: Player): LogEnricherCallback { + const uid = tostring(player.UserId); + + return (entry) => { + entry.encoded_data.userId = uid; + return entry; + }; +} +``` + +### Dynamic Data Enrichment + +Enrichers can also be used to add data that changes dynamically, such as request or transaction IDs: + +```ts +const transactionEnricher: LogEnricherCallback = (entry) => { + entry.encoded_data.transactionId = generateTransactionId(); + return entry; +}; +``` + +### Conditional Enrichment + +Enrichers can modify log entries based on certain conditions. + +For example, you might only want to add certain metadata for error logs. + +```ts +const errorTraceEnricher: LogEnricherCallback = (entry) => { + if (entry.level === LogLevel.ERROR) { + entry.encoded_data.trace = debug.traceback(entry.message); + } + + return entry; +}; +``` + +### Sensitive Data Scrubbing + +You might want to avoid accidentally leaking certain data to your cloud provider or front end users. + +```ts +const scrubApiKeysEnricher: LogEnricherCallback = (entry) => { + entry.encoded_data["api_key"] = undefined; + + return entry; +}; +``` + +## Best Practices + +- **Keep Enrichers Simple**: Enrichers should be straightforward and focus on a single task, like adding a specific + piece of metadata. + +- **Order Enrichers Wisely**: Think about the order in which you apply enrichers. The output of one enricher _will_ + affect the next. + +- **Avoid Heavy Operations**: Since enrichers run for every log entry, avoid performing heavy computations inside them + to prevent slowing down your application. + +- **Avoid yielding**: If your enricher is running for every log entry, yielding inside an enricher will cause the flow + of your program to stop in that thread. In some situations this is desirable- but you generally want your enrichers to + be simple and non blocking. + +## Provided Enrichers {#provided-enrichers} + +**rLog** provides some ready to use enrichers right out of the box, to cover common use cases. + +:::tip + +If you believe you have a common use case that isn't covered by these, feel free to open an issue on the [GitHub](#), or +[Create a PR](#) to add it yourself! + +::: + +### Function Tags + +Uses the name of the nearest function as the tag, if the tag is empty. + +```ts title="actions.ts" +import { rLog } from "@rbxts/rlog"; + +export function doAction() { + const logger = new rLog(); + logger.i("Hello world!"); +} +``` + +```ts title="main.ts" +import { rLog, functionTagEnricher } from "@rbxts/rlog"; +import { doAction } from "./actions"; + +rLog.UpdateDefaultConfig({ enrichers: [functionTagEnricher] }); + +doAction(); +``` + +```logs title="Console" +[INFO]: doAction -> Hello world! +``` + +### File Tags + +Uses the path of the file as the tag, if the tag is empty. + +```ts title="ReplicatedStorage/TS/actions.ts" +import { rLog } from "@rbxts/rlog"; + +export function doAction() { + const logger = new rLog(); + logger.i("Hello world!"); +} +``` + +```ts title="ReplicatedStorage/TS/main.ts" +import { rLog, fileTagEnricher } from "@rbxts/rlog"; +import { doAction } from "./actions"; + +rLog.UpdateDefaultConfig({ enrichers: [fileTagEnricher] }); + +doAction(); +``` + +```logs title="Console" +[INFO]: ReplicatedStorage.TS.actions -> Hello world! +``` + +### Attach Source Metadata + +:::warning + +Source Metadata is a bit of an advanced topic covered in one of our [advanced guides](../advanced/source-metadata). + +::: + +Attaches source metadata to a log entry. + +The metadata is attached under the `source_metadata` key in `encoded_data`. + +```ts title="ReplicatedStorage/TS/actions.ts" +import { rLog } from "@rbxts/rlog"; + +export function doAction() { + const logger = new rLog(); + logger.i("Hello world!"); +} +``` + +```ts title="ReplicatedStorage/TS/main.ts" +import { rLog, sourceMetadataEnricher } from "@rbxts/rlog"; +import { doAction } from "./actions"; + +rLog.UpdateDefaultConfig({ enrichers: [sourceMetadataEnricher] }); + +doAction(); +``` + +```logs title="Console" +[INFO]: Hello world! +{ + data: { + source_metadata: { + function_name: "doAction", + nearest_function_name: "doAction", + file_path: "ReplicatedStorage.TS.actions", + line_number: 5 + } + } +} +``` + +## Summary + +Let's recap what we've learned about Enrichers: + +- **Enrichers** are callbacks that can add new or change existing data on a log entry. +- You can add **multiple** enrichers to an instance, but they're invoked in the order they're added. +- Enrichers can decide to **not** operate on data by returning it as is. diff --git a/wiki/docs/basics/log-context.mdx b/wiki/docs/basics/log-context.mdx new file mode 100644 index 0000000..0c3f844 --- /dev/null +++ b/wiki/docs/basics/log-context.mdx @@ -0,0 +1,587 @@ +--- +description: Learn about correlation ids, and creating linkage between logs. +--- + +import useBaseUrl from "@docusaurus/useBaseUrl"; +import ThemedImage from "@theme/ThemedImage"; + +# Log Context + +One of the most important features that **rLog** provides; log context provides a flexible and powerful way to manage +logging across different parts of your application. + +Log context centralizes correlation ids, allowing you to create a linkage between log entries in individual logic flows- +enabling more streamlined debugging in high traffic or asynchronous environments. + +:::info what you'll learn + +- What log context is +- How to track logs in individual control flows +- How to share configuration between log instances +- How to retain verbose logs only when something important happens + +::: + +## Philosophy + +**rLog** is actually partially designed around log context. The idea is to seperate your configuration from your +individual **rLog** instances, and instead of manually creating individual instances- you `use` your configuration when +needed. + +You then pass this context along to the different components of your application in the flow. + + + +:::warning + +Log context was not designed with parallel luau in mind. If you're using parallel luau, you may run into issues. + +Although, remember that `parallel !== asynchronous`. + +Log context works perfectly fine in asynchronous environments. + +::: + +## Usage + +Now that we have an idea of _what_ log context is, let's hop right into how to use it! + +### Basic Usage + +Log context have a concept of "life cycles", in which you need to `start` the context to use it, and `stop` it when +you're done. + +This is needed to support certain features that we'll get into later on in this tutorial. It also enforces strict +logical flows; forcing you to put more thought behind the structure of your application. + +You create instances of log context through `LogContext.start`, use the context in control flows with `use` and stop the +context with `stop`. + +```ts title="datastore.ts" +import { rLog, LogContext } from "@rbxts/rlog"; + +const config = { tag: "Datastore" }; + +export function AddMoney(context: LogContext, player: Player, money: number) { + // highlight-next-line + const logger = context.use(config); + + logger.i("Adding money to player save"); + // ... + logger.i("Money added"); +} +``` + +```ts title="player-actions.ts" +import { rLog, LogContext } from "@rbxts/rlog"; +import { AddMoney } from "./datastore"; + +const config = { tag: "PlayerActions" }; + +export function GiveMoney(context: LogContext, player: Player, money: number) { + // highlight-next-line + const logger = context.use(config); + + logger.i("Giving player money", { player: player, money: money }); + + AddMoney(context, player, money); + + logger.i("Money given to player"); +} +``` + +```ts title="network.ts" +import { LogContext } from "@rbxts/rlog"; +import { GiveMoney } from "./player-actions"; +import { remotes } from "./remotes"; + +remotes.giveMoney.connect((player: Player, money: number) => { + // highlight-next-line + const context = LogContext.start(); + + GiveMoney(context, player, money); + + // highlight-next-line + context.stop(); +}); +``` + +```logs title="Console" +[INFO]: PlayerActions -> Giving player money +{ + data: { player: "Player1", money: 100 }, + correlation_id: "ZnT961Kwlav6JFii" +} + +[INFO]: Datastore -> Adding money to player save +{ correlation_id: "ZnT961Kwlav6JFii" } + +[INFO]: Datastore -> Money added +{ correlation_id: "ZnT961Kwlav6JFii" } + +[INFO]: PlayerActions -> Money given to player +{ correlation_id: "ZnT961Kwlav6JFii" } +``` + +As you can see, the log context attaches a matching `correlation_id` to each log in the control flow. + +This correlation id can be used to filter for log entries in a singular invocation; avoiding the pollution of duplicate +logs of different invocations. + +This also allows you to only specify _new_ data, while still retaining debug ability. + +Notice how we only specify the `player` in the first log, even though all the other logs are also unique to the +`player`? Since you can filter your logs according to `correlation_id`, the `player` can be implied from earlier logs. +So you only need to log extra data as it's needed. + +This allows you to follow more practical DRY principles. + +### Automatic scoping + +Manually creating context with `start` and manually stopping it with `stop` can not only become verbose- but it's also +error prone. + +Failing to properly call `stop` on a log context can cause memory leaks, even if an exception occurs in your +application. + +To solve this, **rLog** provides a mechanism for _automatic_ lifecycle managment through `withLogContext`. + +```ts title="actions/pets.ts" +import { LogContext, LogConfig } from "@rbxts/rlog"; + +const config: LogConfig = { tag: "Actions" }; + +export function buyPet(context: LogContext, player: PlayerId, pet: PetId) { + const logger = context.use(config); + + logger.i("Buying pet", { player: player, pet: pet }); + + // .. + + logger.i("Pet bought"); +} +``` + +```ts +import { withLogContext } from "@rbxts/rlog"; +import { remotes } from "./remotes"; +import { buyPet } from "./actions/pets"; + +remotes.buyPet.connect((player: Player, pet: PetId) => { + // automatically starts and stops the context + withLogContext((context) => { + buyPet(context, player.UserId, pet); + }); +}); +``` + +```logs title="Console" +[INFO]: Actions -> Buying pet +{ + data: { player: "Player1", pet: "18219" }, + correlation_id: "QQLRSFsPfoTfgD7b" +} + +[INFO]: Actions -> Pet bought +{ correlation_id: "QQLRSFsPfoTfgD7b" } +``` + +:::tip + +`withLogContext` will automatically catch any exceptions that occur within its scope, `stop` the context, and then +rethrow the exception for your own processing; you don't need to worry about memory leaks occurring from unexpected +errors. + +::: + +### Functional Scoping + +While `withLogContext` is generally designed with the idea of being called at the remote level in an event based +environment- this isn't always the case. Maybe your application is more response based than event based. + +Thankfully, `withLogContext` also returns whatever you return within the scope. + +```ts title="actions/pets.ts" +import { LogContext, LogConfig } from "@rbxts/rlog"; + +const config: LogConfig = { tag: "Actions" }; + +export function buyPet(context: LogContext, player: PlayerId, pet: PetId): boolean { + const logger = context.use(config); + + logger.i("Buying pet", { player: player, pet: pet }); + + // .. + + logger.i("Pet bought"); + + return true; +} +``` + +```ts title="remotes.ts" +import { t } from "@rbxts/t"; +import { Server, remote, createRemotes } from "@rbxts/remo""; + +export const remotes = createRemotes({ + buyPet: remote(t.string).returns(t.boolean) +}) +``` + +```ts +import { withLogContext } from "@rbxts/rlog"; +import { remotes } from "./remotes"; +import { buyPet } from "./actions/pets"; + +remotes.buyPet.onRequest((player: Player, pet: PetId) => + withLogContext((context) => { + return buyPet(context, player.UserId, pet); + }), +); +``` + +This will return the `boolean` value from `buyPet` back to `onRequest`. + +### Asynchronous Scoping + +If you have asynchronous behavior you're wanting to wrap, you can use `withLogContextAsync` in place of +`withLogContext`. + +This will provide an environment for invoking asynchronous functions, and ensure the context gets closed even if the +promise fails or is cancelled. + +:::info + +`withLogContextAsync` requires `Promises.lua` at `^4.0.0`, which (at the time of this writing) not released for +`roblox-ts` yet. + +To workaround this, **rLog** bundles `Promises.lua`. If you're using an older version, you make run into issues. + +::: + +```ts +import { withLogContextAsync } from "@rbxts/rlog"; +import { remotes } from "./remotes"; +import { buyPet } from "./actions/pets"; + +remotes.buyPet.onRequest((player: Player, pet: PetId) => + withLogContextAsync(async (context) => { + return buyPet(context, player.UserId, pet); + }), +); +``` + +## Configuration + +Log Context has an internal `config` that all users of the context inherit from. By default, this is just set to the +default config, but you can specify your own during creation. + +```ts title="actions/pets.ts" +import { LogContext, LogConfig } from "@rbxts/rlog"; + +const config: LogConfig = { tag: "Actions" }; + +export function buyPet(context: LogContext, player: PlayerId, pet: PetId) { + const logger = context.use(config); + + logger.i("Buying pet", { player: player, pet: pet }); + + // .. + + logger.i("Pet bought"); +} +``` + +```ts +import { withLogContext, LogLevel } from "@rbxts/rlog"; +import { remotes } from "./remotes"; +import { buyPet } from "./actions/pets"; + +remotes.buyPet.connect((player: Player, pet: PetId) => { + withLogContext({ minLogLevel: LogLevel.DEBUG }, (context) => { + buyPet(context, player.UserId, pet); + }); +}); +``` + +You can use this to pass common configuration to all loggers under a given scope. + +There are also overrides for `withLogContextAsync` as well. + +```ts +import { withLogContextAsync, LogLevel } from "@rbxts/rlog"; +import { remotes } from "./remotes"; +import { buyPet } from "./actions/pets"; + +remotes.buyPet.onRequest((player: Player, pet: PetId) => + withLogContextAsync({ minLogLevel: LogLevel.DEBUG }, async (context) => { + return buyPet(context, player.UserId, pet); + }), +); +``` + +## Overwriting Context + +You may find yourself in edge case scenarios where you need more fine grained control over the details of a context. + +**rLog** provides a few helper methods to assist in this. + +### Config + +If you ever want to update the associated config in a log context with new values- you can use the `withConfig` method +to merge the configs and create a new context instance while retaining the correlation id. + +```ts +import { LogContext, LogLevel } from "@rbxts/rlog"; + +const mainContext = LogContext.start({ minLogLevel: LogLevel.DEBUG }); +const deepContext = context.withConfig({ serialization: { deepEncodeTables: false } }); + +const mainLogger = context.use({ tag: "Main" }); +const deepLogger = deepContext.use({ tag: "Deep" }); + +mainLogger.i("Hello info!"); +deepLogger.i("Hello info!"); + +const data = { player: { position: new Vector3(1, 2, 3) } }; +mainLogger.d("Hello debug!", data); +deepLogger.d("Hello debug!", data); + +mainContext.stop(); +deepContext.stop(); +``` + +```logs title="Console" +[DEBUG]: Main -> Hello debug! +{ + data: { + player: { + position: null + } + }, + correlation_id: "QQLRSFsPfoTfgD7b" +} + +[DEBUG]: Deep -> Hello debug +{ + data: { + player: { + position: { X: 1, Y: 2, Z: 3 } + } + }, + correlation_id: "QQLRSFsPfoTfgD7b" +} +``` + +### Instances + +Sometimes you might have an **rLog** instance that was already created, and you want to use a context with it. + +In these cases, you can't really call `use` on the context- since the logger instance already exists. + +To fix this, you can use the `withContext` method. + +:::warning + +Remember that **rLog** instances follow the principle of immutability- so you're creating a _new_ instance with the +context attached, not updating the old one. + +::: + +```ts +import { LogContext, rLog } from "@rbxts/rlog"; + +const MainLogger = new rLog(); + +const context = LogContext.start(); + +const logger = MainLogger.withContext(context); + +context.stop(); +``` + +This will also _merge_ the configs between the context and your logger instance; placing priority on the logger's +configuration. + +## Context Bypass + +The biggest reason for context having their own lifecycles is to provide support for context bypass. + +Context bypass allows logs to bypass the `minLogLevel` whenever another log in the tree exceeds `WARNING`. + +You can enable this feature by setting the `contextBypass` setting. + +```ts title="actions/pets.ts" +import { LogContext, LogConfig } from "@rbxts/rlog"; +import { save } from "./save"; + +const config: LogConfig = { tag: "Actions" }; + +export async function buyPet(context: LogContext, player: PlayerId, pet: PetId) { + const logger = context.use(config); + + logger.d("Buying pet", { player: player, pet: pet }); + + const playerSave = await save.get(context, player); + + // ... + + logger.d("Pet bought"); +} +``` + +```ts +import { rLog, LogLevel, withLogContext } from "@rbxts/rlog"; +import { remotes } from "./remotes"; +import { buyPet } from "./actions/pets"; + +rLog.UpdateDefaultConfig({ minLogLevel: LogLevel.INFO }); + +remotes.buyPet.connect((player: Player, pet: PetId) => { + // automatically starts and stops the context + withLogContextAsync({ contextBypass: true }, (context) => buyPet(context, player.UserId, pet)); +}); +``` + +```logs title="Console" + +[ERROR]: Saves -> Failed to load player save +{ + data: { err: "Roblox datastore API is down" }, + correlation_id: "QQLRSFsPfoTfgD7b" +} + +[DEBUG]: Actions -> Buying pet +{ + data: { player: "Player1", pet: "18219" }, + correlation_id: "QQLRSFsPfoTfgD7b" +} +``` + +This allows you to set a high `minLogLevel` without sacrificing a proper log trace whenever something bad happens. + +### Flushing on Close + +Internally, `contextBypass` is handled by a service called the `LogContextManager`. + +This service keeps a table mapping of correlation ids to log entries and relevant sinks; keeping them in memory until +the context is stopped. + +Although, this also means that you might have situations where logs are stored in memory that might need to be flushed +to a sink- but the game closed before they could. + +To fix this, you can call the `ForceContextFlush` method in a `bindToClose` hook. + +```ts +import { rLog } from "@rbxts/rlog"; + +game.bindToClose(() => { + rLog.ForceContextFlush(); +}); +``` + +This will force any pending messages to be sent through the sinks, regardless of the `minLogLevel`. + +:::tip + +The reason this is exposed as a method you have to call instead of a setting where **rLog** internally binds on its own +is to allow you to handle last call logging on your own. + +So if you have some internal system that logs right before the game closes, you can allow that to run before calling +this method; you have control over when the context is forced through. + +::: + +### Suspending Context + +One thing you might have noticed is that the logs that come out from a context bypass are out of order. + +This is because **rLog** places priority on getting the important message out over getting the others. + +If this behavior is undesirable, and you'd rather have your logs retain their order, you can take advantage of the +`suspendContext` setting. + +```ts title="actions/pets.ts" +import { LogContext, LogConfig } from "@rbxts/rlog"; +import { save } from "./save"; + +const config: LogConfig = { tag: "Actions" }; + +export async function buyPet(context: LogContext, player: PlayerId, pet: PetId) { + const logger = context.use(config); + + logger.d("Buying pet", { player: player, pet: pet }); + + const playerSave = await save.get(context, player); + + // ... + + logger.d("Pet bought"); +} +``` + +```ts +import { rLog, LogLevel, withLogContext } from "@rbxts/rlog"; +import { remotes } from "./remotes"; +import { buyPet } from "./actions/pets"; + +rLog.UpdateDefaultConfig({ + minLogLevel: LogLevel.INFO, + contextBypass: true, + suspendContext: true, +}); + +remotes.buyPet.connect((player: Player, pet: PetId) => { + // automatically starts and stops the context + withLogContextAsync((context) => buyPet(context, player.UserId, pet)); +}); +``` + +```logs title="Console" +[DEBUG]: Actions -> Buying pet +{ + data: { player: "Player1", pet: "18219" }, + correlation_id: "QQLRSFsPfoTfgD7b" +} + +[ERROR]: Saves -> Failed to load player save +{ + data: { err: "Roblox datastore API is down" }, + correlation_id: "QQLRSFsPfoTfgD7b" +} +``` + +`suspendContext` forces logs to be "suspended" until the context is closed. They then all get sent in the order they +were received. + +## Best Practices + +- **Wrap control flows in context**: Having a context associated with each invocation of a control flow will allow you + to avoid logs being jumbled together. +- **Only log new data in a context**: Since log context creates a straightforward linkage between other entries in the + same flow, only logging _new_ data allows you to avoid polluting your logs with the same data over and over again. +- **Use context bypass at the global scope**: If you're wanting to set a `minLogLevel` to save on verbose logging, but + still want to take advantage of the verbose logs when they're needed- then keep `contextBypass` enabled from the + default instance. +- **Force context flush on close**: To avoid accidentally missing logs, it's good practice to ensure you're calling + `ForceContextFlush` before the game closes via `bindToClose`. +- **Use automatic scoping**: Automatic scoping handles the creation, starting, and closing of context for you. Take + advantage of this to avoid accidentally leaking memory- and only manually manage the context when you need more fine + grained control. + +## Summary + +Let's recap what we've learned about log context: + +- They carry **correlation ids** for creating linkage between log entries. +- They allow you to **filter** logs in individual control flows. +- You can use them in **asynchronous** environments via `withLogContextAsync`. +- They provide a way to share **common configuration** between log instances. +- They need to be **stopped** to avoid memory leaks. +- You can use **context bypass** to allow log entries to bypass `minLogLevel` when something important occurs. diff --git a/wiki/docs/basics/log-entries.mdx b/wiki/docs/basics/log-entries.mdx new file mode 100644 index 0000000..d857db4 --- /dev/null +++ b/wiki/docs/basics/log-entries.mdx @@ -0,0 +1,145 @@ +--- +description: Learn what logs are, and how they're represented. +--- + +# Log Entries + +Log entries are the core aspect of **rLog**. They're what provide log messages, and carry the additional context of a +log. + +:::info what you'll learn + +- What log entries are +- The different components of a log +- How data is attached to logs + +::: + +## Overview + +Log entries themselves aren't nearly as complex as the systems surrounding them, but they do have a decent amount of +information attached to them. + +```ts +export type LogEntry = { + level: LogLevel; + message: string; + data: LogData; + encoded_data: LogData; + config: Writable; + context?: LogContext; + timestamp: number; + source_metadata: SourceMetadata; +}; +``` + +### Level + +The `level` is the [Log Level](log-level), or severity, of the log. + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog(); + +logger.info("Hello world!"); +``` + +In this case, `LogLevel.INFO` is the level. + +### Message + +The `message` is the actual string message intended for the log. + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog(); + +logger.info("Hello world!"); +``` + +In this instance, `Hello world!` is the message. + +### Data + +`data` is additional metadata specific to the log itself. + +```ts +export type LogData = Record; +``` + +You'll learn more about `data` in the other guides. + +### Encoded Data + +`encoded_data` is just `data` in a form that's JSON friendly, and has been ran through the **rLog** serializer. + +### Config + +`config` is a `Writable` version of the `RLogConfig` that was used when sending the log. + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog({ tag: "Main" }); + +logger.info("Hello world!"); +``` + +In this instance, `{ tag: "Main" }` is the `config`. + +### Timestamp + +`timestamp` is the epoch milliseconds in which the log occurred. + +```logs +[INFO]: Actions -> Hello world! +{ + // highlight-next-line + timestamp: 1723757975945, + correlation_id: "Xzm9InKevNRjvqqo" +} +``` + +:::info + +For the sake of brevity, most of the guides will exclude `timestamp` from their output. + +In practice, this will be a part of your logs. + +::: + +### Context + +`context` is the `LogContext` instance that was used when sending the log, if there was one present at all. + +Log Context allows you to create linkage between log entries, and is one of the most important features of **rLog**. + +But, it's a bit too complex of a topic for now; you'll learn more about it in the [Log Context](#) guide. + +#### Correlation ID + +`correlation_id` is a unique string attached to logs to identify entries that run across different `RLog` instances, but +represent the same "flow". + +These are provided via Log Context. + +```logs +[INFO]: Actions -> Hello world! +{ + timestamp: 1723757975945, + // highlight-next-line + correlation_id: "Xzm9InKevNRjvqqo" +} +``` + +You'll learn more about Correlation IDs aswell in the [Log Context](#) guide. + +## Summary + +Let's recap what we've learned about log entries: + +- They carry all the **metadata** associated with log messages +- They keep track of **when** logs were sent, and **who** sent them +- They allow logs to carry additional **user provided** data diff --git a/wiki/docs/basics/log-levels.mdx b/wiki/docs/basics/log-levels.mdx new file mode 100644 index 0000000..f8a050a --- /dev/null +++ b/wiki/docs/basics/log-levels.mdx @@ -0,0 +1,354 @@ +--- +description: Learn about the severity levels that logs can have. +--- + +# Log Levels + +Logs can have a different severity level attached to them, indicating at a quick glance the importance of a message. + +:::info what you'll learn + +- What log levels are +- How log levels are used +- The various helper methods to create different log messages +- How to apply a minimum log level to your logging setup + +::: + +## Levels + +Within **rLog**, there are five possible severity levels you can use: + +- Verbose +- Debug +- Info +- Warn +- Error + +The levels escalate in order of importance, `Verbose` being the least important, and `Error` being the most important. + +The level of a log entry is (by default) attached to the start of the message, and surrounded in brackets. + +```LogLevel +[WARN]: There was an issue! +``` + +### Verbose + +Verbose is the lowest level of logging. + +Verbose messages are those that are not usually needed unless you need to see deep step-by-step processes in your +application. + +```ts +import { rLog } from "@rbxts/rlog"; +import { sendPayment } from "./payment"; + +const logger = new rLog(); +// highlight-next-line +logger.verbose("Application started"); + +function processOrder(orderId: string, userId: string) { + // All the logging methods have short hand aliases you can use as well + // highlight-next-line + logger.v("Fetching details for order", { order: orderId, user: userId }); +} + +processOrder("12345", "user789"); +``` + +```logs title="Console" +[VERBOSE]: Application started +[VERBOSE]: Fetching details for order +{ data: { order: "12345", "user789" } } +``` + +### Debug + +Debug is the second lowest level of logging. + +Generally used for messages that you don't necessarily need to see at runtime, but they're useful when you need to find +out why something is happening. + +Essentially, messages and data that could be useful when debugging. + +```ts +import { rLog } from "@rbxts/rlog"; +import { sendPayment } from "./payment"; + +const logger = new rLog(); + +logger.verbose("Application started"); + +function processOrder(orderId: string, userId: string) { + logger.v("Fetching details for order", { order: orderId, user: userId }); + + const orderDetails = { items: ["item1", "item2"], total: 100 }; + + // highlight-next-line + logger.d(`Retrieved order details`, { details: orderDetails }); +} + +processOrder("12345", "user789"); +``` + +```logs title="Console" +[VERBOSE]: Application started +[VERBOSE]: Fetching details for order +{ data: { order: "12345", "user789" } } + +// highlight-start +[DEBUG]: Retrieved order details +{ data: { details: { items: ["item1", "item2"], total: 100 } } } +// highlight-end +``` + +### Info + +The baseline level of logging. + +Useful for messages that signify an event or interaction. Usually occur only once or twice in a control flow, and are +used less for debugging, and more for seeing what's going on in your application. + +```ts +import { rLog } from "@rbxts/rlog"; +import { sendPayment } from "./payment"; + +const logger = new rLog(); + +logger.verbose("Application started"); + +function processOrder(orderId: string, userId: string) { + // highlight-next-line + logger.i("Processing order"); + + logger.v("Fetching details for order", { order: orderId, user: userId }); + + const orderDetails = { items: ["item1", "item2"], total: 100 }; + + logger.d(`Retrieved order details`, { details: orderDetails }); + + // highlight-next-line + logger.i("Order complete"); +} + +processOrder("12345", "user789"); +``` + +```logs title="Console" +[VERBOSE]: Application started + +// highlight-next-line +[INFO]: Processing order + +[VERBOSE]: Fetching details for order +{ data: { order: "12345", "user789" } } + +[DEBUG]: Retrieved order details +{ data: { details: { items: ["item1", "item2"], total: 100 } } } + +// highlight-next-line +[INFO]: Order complete +``` + +### Warning + +Something that isn't necessarily breaking, but should be looked at. + +Depending on your style, it may end up being used less often than the other levels. + +:::info + +By default, logs with a level of `WARNING` or above are sent through `warn` in the ROBLOX console, while the rest are +sent through `print`. + +::: + +```ts +import { rLog } from "@rbxts/rlog"; +import { sendPayment } from "./payment"; + +const logger = new rLog(); + +logger.verbose("Application started"); + +function processOrder(orderId: string, userId: string) { + logger.i("Processing order"); + + logger.v("Fetching details for order", { order: orderId, user: userId }); + + const orderDetails = { items: ["item1", "item2"], total: 1 }; + + logger.d(`Retrieved order details`, { details: orderDetails }); + + if (orderDetails.total < 10) { + // highlight-next-line + logger.w("Order has a suspiciously low total"); + } + + logger.v("Sending order for payment"); + + const paymentSuccessful = sendPayment(order, userId, orderDetails); + + if (!paymentSuccessful) { + // highlight-next-line + logger.w("Payment for order failed"); + } + + logger.i("Order complete"); +} + +processOrder("12345", "user789"); +``` + +```logs title="Console" +[VERBOSE]: Application started + +[INFO]: Processing order + +[VERBOSE]: Fetching details for order +{ data: { order: "12345", "user789" } } + +[DEBUG]: Retrieved order details +{ data: { details: { items: ["item1", "item2"], total: 1 } } } + +// highlight-next-line +[WARNING]: Order has a suspiciously low total + +[VERBOSE]: Sending order for payment + +// highlight-next-line +[WARNING]: Payment for order failed + +[INFO]: Order complete +``` + +### Error + +Something went wrong, and needs to be looked at ASAP. + +Usually used to indicate fatal issues or exceptions that weren't expected, and break the application. + +```ts +import { rLog } from "@rbxts/rlog"; +import { sendPayment } from "./payment"; + +const logger = new rLog(); + +logger.verbose("Application started"); + +function processOrder(orderId: string, userId: string) { + try { + logger.i("Processing order"); + + logger.v("Fetching details for order", { order: orderId, user: userId }); + + const orderDetails = { items: ["item1", "item2"], total: 1 }; + + logger.d(`Retrieved order details`, { details: orderDetails }); + + if (orderDetails.total < 10) { + logger.w("Order has a suspiciously low total"); + } + + logger.v("Sending order for payment"); + + const paymentSuccessful = sendPayment(order, userId, orderDetails); + + if (!paymentSuccessful) { + logger.w("Payment for order failed"); + } + + logger.i("Order complete"); + } catch (e) { + // highlight-start + logger.e("An unexpected error occurred", { + reason: e.message, + }); + //highlight-end + } +} + +processOrder("12345", 789); +``` + +```logs title="Console" +[VERBOSE]: Application started + +[INFO]: Processing order + +[VERBOSE]: Fetching details for order +{ data: { order: "12345", 789 } } + +[DEBUG]: Retrieved order details +{ data: { details: { items: ["item1", "item2"], total: 1 } } } + +[WARNING]: Order has a suspiciously low total + +// highlight-start +[ERROR]: An unexpected error occurred +{ data: { reason: "Invalid UserID provided! Expected a string, but got numbers!" } } +// highlight-end +``` + +## Minimum Log Level + +Logs are great when you need them, and an eye sore when you don't. + +It's always the worst when you're trying to debug a certain issue, or see what's going on in your application, but your +output is flooded with verbose logs that you don't need right now. + +To fix this, you can set the minimum level that should actually be sent to the console. + +:::info + +By default, this is set to `VERBOSE` when in studio and `WARNING` when in a published game. If you are fine with the +defaults, you don't need to change it. + +::: + +### Config + +The first way to configure this is via the `minLogLevel` setting in your config. + +```ts +import { rLog, LogLevel } from "@rbxts/rlog"; + +const logger = new rLog({ minLogLevel: LogLevel.DEBUG }); + +logger.v("Hello verbose!"); +logger.d("Hello debug!"); +logger.i("Hello info!"); +``` + +```logs title="Console" +[DEBUG]: Hello debug! +[INFO]: Hello info! +``` + +Levels that are less than the provided `minLogLevel` are effectively "filtered out", and don't make it through to the +console. + +### Helper Method + +The second way to configure this is via the `withMinLogLevel` method on `RLog` instances. + +```ts +// returns a copy of this logger, but with the `minLogLevel` set to `DEBUG` +const logger = new rLog().withMinLogLevel(LogLevel.DEBUG); +``` + +This will return a copy of the instance, with the `minLogLevel` set to `DEBUG`. + +You'll find that a few config options have helper method alternatives like this; to allow more dynamic configuration or +functional setups. + +## Summary + +Let's recap what we've learned about log levels: + +- They respresent the **severity** or **importance** of a log +- They're the **first** part of a log message +- They have an **increasing** level of importance +- You can set a **minimum** level to output +- Levels above `INFO` are sent through the `warn` console in roblox diff --git a/wiki/docs/basics/serialization.mdx b/wiki/docs/basics/serialization.mdx new file mode 100644 index 0000000..69d7ea4 --- /dev/null +++ b/wiki/docs/basics/serialization.mdx @@ -0,0 +1,395 @@ +--- +description: Learn how your data is serialized for output. +--- + +# Serialization + +Serialization is a key feature of the **rLog** framework, enabling you to pass complex data structures as part of your +log entries. + +**rLog** automatically handles encoding this data, ensuring that it can be logged, stored, or transmitted without +issues. + +:::info what you'll learn + +- How **rLog** handles automatic serialization +- How to pass data as part of your log entries +- How to customize serialization using `SerializationConfig` +- Best practices for managing serialized data + +::: + +## Passing Data with Log Entries + +When logging messages using **rLog**, you can pass an optional second parameter that contains any additional data you +want to log. + +This data should be a table of string key mappings, but the values can be anything from another table, primitive types, +functions, or even a class. + +### Basic Example + +Here's a basic example of passing additional data with a log entry: + +```ts +import { rLog } from "@rbxts/rlog"; +import { Players } from "@rbxts/services"; + +const logger = new rLog(); + +Players.PlayerAdded.Connect((player) => { + logger.i("Player joined", { id: player.UserId, name: player.Name }); +}); +``` + +```logs title="Console" +[INFO]: Player joined +{ + data: { + id: 1, + name: "ROBLOX" + } +} +``` + +In this example, the second parameter is a table containing the Player's UserId and Name. + +**rLog** automatically serializes this data before logging it, ensuring it’s properly encoded. + +## Automatic Serialization + +By default, **rLog** uses a deep serialization strategy to ensure that all data is properly encoded, including nested +objects and Roblox-specific data types. + +### Roblox Types + +A lot of Roblox data-types don't properly encode to string or JSON, especially when nested in tables. + +**rLog** will manually encode these types, so you don't have to worry about data missing in your logs. + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog(); + +logger.d("User purchase complete", { + purchase_id: "121141", + details: { + item: "Nuke", + result: Enum.ProductPurchaseDecision.PurchaseGranted, + position: new Vector3(10, 15, 20), + rotation: new CFrame(), + }, +}); +``` + +```logs title="Console" +[DEBUG]: Hello debug! +{ + data: { + purchase_id: "121141", + details: { + item: "Nuke", + result: "Enum.ProductPurchaseDecision.PurchaseGranted", + position: { X: 10, Y: 15, Z: 20 }, + rotation: "CFrame(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)", + } + } +} +``` + +Although, you can also (partially) disable this behavior with the `encodeRobloxTypes` setting. + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog({ serialization: { encodeRobloxTypes: false } }); +``` + +```logs title="Console" +[DEBUG]: Hello debug! +{ + data: { + purchase_id: "121141", + details: { + item: "Nuke", + result: "", + position: "", + rotation: "", + } + } +} +``` + +This way, ROBLOX data types are still identifiable, but you're not overloaded with their internal values. + +This is especially useful if the values of the properties are less important than their existence and types. + +### Nested Tables + +By default, **rLog** will deep encode nested tables; even if they have Roblox data types, or classes. But this behavior +may not be desirable with larger tables. + +You can disable this behavior with the `deepEncodeTables` setting. + +:::warning + +While this will save you on performance, keep in mind that this may cause certain nested types to not be properly +encoded. + +::: + +```ts +import { rLog } from "@rbxts/rlog"; + +const event = { + source: { + position: new Vector2(1, 1), + distance: 100, + }, + target: new Vector2(2, 2), +}; + +const logger = new rLog({ serialization: { deepEncodeTables: false } }); + +logger.i("Nuke sent", event); +``` + +```logs title="Console" +[INFO]: Nuke sent +{ + data: { + source: { + // error-next-line + position: null, + distance: 100, + }, + target: { X: 1, Y: 2 } + } +} +``` + +Normally, **rLog** would be able to encode the position. + +But, with `deepEncodeTables` disabled- it's not able to properly catch it. + +### Classes + +Instances of classes are a common issue of logging libraries. Especially if your project follows a more Object-Oriented +style. + +#### Implicit Support + +By default, **rLog** will look for a `__tostring` method on class instances to try to encode them properly. This method +is automatically generated by **rbxts** for typescript classes, with a value of the class name. + +```ts +import { rLog } from "@rbxts/rlog"; + +class Person { + constructor(public name: string) {} +} + +const logger = new rLog(); + +const person = new Person("Daymon"); + +logger.debug("Person created", { me: person }); +``` + +```logs title="Console" +[DEBUG]: Person created +{ data: { me: "Person" } } +``` + +#### Custom encoding + +Although, you can customize this behavior. + +There are two ways you can customize the encoding process for class instances. + +##### Overriding + +The first (and easiest) way is by providing your own `toString` override on the class. + +`rbxts` will link to your method instead of creating their own, if you provide one. + +```ts +import { rLog } from "@rbxts/rlog"; + +class Person { + constructor(public name: string) {} + + public toString() { + return this.name; + } +} + +const logger = new rLog(); + +const person = new Person("Daymon"); + +logger.debug("Person created", { me: person }); +``` + +```logs title="Console" +[DEBUG]: Person created +{ data: { me: "Daymon" } } +``` + +##### Custom Encode Methods + +You can also provide a custom `encodeMethod` for the **rLog** serializer to look for. + +:::info + +In the case that your `encodeMethod` is not found on an instance, **rLog** will fall back to treating it is as a table. + +::: + +```ts +import { rLog } from "@rbxts/rlog"; + +class Person { + constructor(public name: string) {} + + public encode() { + return this.name; + } +} + +const logger = new rLog({ serialization: { encodeMethod: "encode" } }); + +const person = new Person("Daymon"); + +logger.debug("Person created", { me: person }); +``` + +```logs title="Console" +[DEBUG]: Person created +{ data: { me: "Daymon" } } +``` + +This way, you can retain existing interop with systems that depend on your current `toString` method, and still change +the format of your classes in logs. + +:::tip + +The serializer actually expects an `EncodableValue` as the return value. + +Meaning you can also return tables, numbers, or even booleans- if a string isn't enough for you. + +::: + +### Functions + +A not so common use-case is functions. + +By default, rLog does _not_ encode functions in the output. But, this behavior can sometimes be desirable (eg; if you're +inspecting run-time types). + +You can enable this behavior with the `encodeFunctions` config option. + +```ts +import { rLog } from "@rbxts/rlog"; + +function CreatePlayer(name: string) { + return { + name: name, + eatFood: () => { + // ... + }, + }; +} + +const logger = new rLog({ serialization: { encodeFunctions: true } }); + +const player = CreatePlayer("daymon"); + +logger.i("Player created", { player: player }); +``` + +```logs title="Console" +[INFO]: Player created +{ + data: { + player: { + name: "daymon", + eatFood: "" + } + } +} +``` + +Functions will be encoded as `` alongside their key name. + +### Self Pointers + +An edge case behavior that might come up is you have a table that has a reference to itself. This could be intentional, +or on accident. Normally, this would could issues during encoding procedures; as it would cause a stack overflow. +Thankfully, **rLog** fixes that. + +:::warning + +While **rLog** will catch surface level self pointers, it does _not_ catch deep self pointers. + +This is done for performance reasons. If you have deeply nested self pointers, you may want to provide a +[custom encoding method](#) to fix it. + +::: + +```ts +import { rLog } from "@rbxts/rlog"; + +class Person { + constructor( + public name: string, + public parent?: Person, + ) {} + + public encode() { + return { + name: this.name, + parent: this.parent, + }; + } +} + +const logger = new rLog({ serialization: { encodeMethod: "encode" } }); + +const person = new Person("Daymon"); + +person.parent = person; + +logger.debug("Person created", { me: person }); +``` + +```logs title="Console" +[DEBUG]: Person created +{ + data: { + me: { + name: "Daymon", + parent: "" + } + } +} +``` + +**rLog** will convert self pointers to the string `` to avoid these issues. + +## Best Practices + +- **Provide metadata when possible**: While there's definitely such a thing as cognitive overload when it comes to logs, + that can usually be fixed with proper filtering. It's generally a better idea to provide metadata for logs where + possible- even in small amounts. You'll be thanking yourself when it comes time to do some deep debugging. +- **Attach IDs to logs**: Any sort of identifying information can be a great help when debugging issues. So you should + try to make sure IDs like Player IDs, Asset IDs, etc., are included in your logs. + +## Summary + +Let's recap what we've learned about Serialization: + +- Serialization occurs **automatically** for ROBLOX data-types and complex data structures. +- You can **configure** your serialization with `SerializationConfig` settings. +- You can setup **custom** serialization for classes and in-house data structures. diff --git a/wiki/docs/basics/sinks.mdx b/wiki/docs/basics/sinks.mdx new file mode 100644 index 0000000..b812561 --- /dev/null +++ b/wiki/docs/basics/sinks.mdx @@ -0,0 +1,176 @@ +--- +description: Learn how to apply filters to logs, or send them to external services. +--- + +# Sinks + +Sinks are an essential part of the **rLog** framework, enabling you to filter or "consume" log entries. + +By using sinks, you can direct your logs wherever they are needed, ensuring that important information is captured and +available for analysis. + +:::info what you'll learn + +- What sinks are and their purpose in logging +- How to create and use custom sinks +- How to apply multiple sinks to a single log instance +- Best practices for using sinks effectively + +::: + +## What is a Sink? + +A sink in **rLog** is a component responsible for receiving log entries and deciding if the log should be consumed or +not. + +```ts +export type LogSinkCallback = (entry: LogEntry) => boolean | void; +``` + +## Types of Sinks + +While you can use a sink for whatever you want, they usually fall under one of two categories. + +### Filters + +One of the most basic usages of a sink is the ability to apply filters to logs. + +More specifically, excluding certain logs from the output. + +```ts title="remove-admin-calls-sink.ts" +import { rLog, LogEntry } from "@rbxts/rlog"; +import { adminList } from "./constants"; + +export function removeAdminCallsSink(entry: LogEntry): boolean { + return entry.config.tag === "ADMIN" && !adminList.includes(entry.data.player); +} +``` + +This sink applys a "filter" to log entries, such that if a log entry has the tag `"ADMIN"` and the player the log is for +isn't a valid admin, then the log is discarded. + +### Consumers + +Probably the most common [and important] type of sinks are the "consumers". + +Consumer sinks "consume" log messages, and send them to an external server instead of the local console. + +But the "consume" aspect isn't necessarily required. + +:::tip + +Since sinks have a return type of `boolean | void`, you don't _have_ to return anything. If you don't want to consume +the entry, you can just not return anything; and the implicit `void` return will be the same as `return false`. + +::: + +```ts title="log-to-database-sink.ts" +import { RunService } from "@rbxts/services"; +import { rLog } from "@rbxts/rlog"; +import { queueLogRequest } from "./log-database"; + +const debug = RunService.IsStudio(); + +export function logToDatabaseSink(entry: LogEntry): boolean { + const endpoint = debug ? "qa" : "prod"; + + queueLogRequest(entry, endpoint); + + return debug; // only allow messages through while we're in studio +} +``` + +This sink sends all logs to our backend, and only prevents them from reaching the ROBLOX console for published games. + +So in studio, we can still have our logs in the console AND in a seperate external database for deeper inspection. + +## Using Sinks + +Once you've created a sink, you can "attach" it to your **rLog** instances via the `sinks` setting in your config. + +:::warning + +Keep in mind that sinks run _after_ enrichers, so the data you're seeing is after it's been fully processed by all the +enrichers. + +::: + +```ts +import { rLog } from "@rbxts/rlog"; +import { removeAdminCallsSink } from "./remove-admin-calls-sink"; + +const logger = new rLog({ sinks: [removeAdminCallsSink] }); +``` + +### Order of Sinks + +Sinks are applied to logs (or "ran") in the order they are "attached" to the **rLog** instance. + +This means that if the first sink "consumes" an entry, the second sink won't even be called. + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog({ + sinks: [ + (entry) => { + return true; + }, + (entry) => { + error("Messages should not log to the console"); + }, + ], +}); + +logger.i("Hello world!"); +``` + +In this example, the first sink returns `true`; effectively "consuming" the log. + +So the error from the second sink is never thrown. + +## Provided Sinks {#provided-sinks} + +**rLog** provides some ready to use sinks right out of the box, to cover common use cases. + +### Roblox Console + +-- TODO() + +### Google Cloud Logging + +Sends logs to the Google Cloud Logging API, so that they can then be viewed in the Google Cloud Console. + +```ts +import { rLog, useGoogleCloudLogging } from "@rbxts/rlog"; +import { HttpService } from "@rbxts/HttpService"; + +const googleCloudLoggingSink = useGoogleCloudLogging({ + ACCESS_TOKEN: HttpService.GetSecret("GCLOUD_ACCESS_TOKEN"); +}) + +rLog.SetGlobalSinks([googleCloudLoggingSink]); +``` + +:::info + +To learn more about setting up Google Cloud Logging for your **rLog** application, see our [Google Cloud Logging](#) +guide. + +::: + +## Best Practices + +- **Avoid yielding**: Avoid yielding in your sinks, as this can slow down your logging and impact application + performance. If you're sending your logs to a backend service, this should be done via a queue that gets picked up by + a different thread. +- **Separate Concerns**: Use different sinks for different purposes (e.g., one for error logging, another for audit + trails) to keep your logs organized and easy to manage. + +## Summary + +Let's recap what we've learned about Sinks: + +- **Sinks** receive log entries and decide if they should be processed or not. +- You can use sinks to **share** logs with an external service. +- You can attach **multiple** sinks to an instance, but they're invoked in the order they're added. diff --git a/wiki/docs/basics/tags.mdx b/wiki/docs/basics/tags.mdx new file mode 100644 index 0000000..9519db5 --- /dev/null +++ b/wiki/docs/basics/tags.mdx @@ -0,0 +1,61 @@ +--- +description: Learn how to apply named categories to your logs. +--- + +# Tags + +Tags provide a way for you identify specific **rLog** instances, and allow finer categorization of your log messages. + +:::info what you'll learn + +- What tags are +- How to use tags to categorize your logs + +::: + +## Using Tags + +By default, **rLog** instances do not have a tag. You can provide one via two ways. + +### Helper Method + +One way is by using the `withTag` helper method. + +```ts +import { rLog } from "@rbxts/rlog"; + +const main = new rLog().withTag("Main"); + +main.i("Hello world!"); +``` + +```logs title="Console" +[INFO]: Main -> Hello world! +``` + +By default, tags are prefixed to the start of log messages, after the level. + +This makes identifying different instances quick and easy. + +### Config + +You can also configure the tag of an instance when setting the config. + +```ts +import { rLog } from "@rbxts/rlog"; + +const main = new rLog({ tag: "Main" }); + +main.i("Hello world!"); +``` + +```logs title="Console" +[INFO]: Main -> Hello world! +``` + +## Summary + +Let's recap what we've learned: + +- You can attach **tags** to instances to provide more fine categorization. +- Tags can be applied at the **config** level or as a **method** call. diff --git a/wiki/docs/faq.mdx b/wiki/docs/faq.mdx new file mode 100644 index 0000000..cf02443 --- /dev/null +++ b/wiki/docs/faq.mdx @@ -0,0 +1,293 @@ +# FAQ + +### Why should I use this over rbx-log? + +It depends on your use case and your style. + +From a style perspective, **rLog** follows a more TypeScript/functional style, while **rbx-log** adopts a more C#/OOP +approach. + +Feature-wise, **rbx-log** and **rLog** cover a lot of the same ground, and offer many of the same features, though there +are some unique to each. + +You can use the feature table below for reference. + +| Feature | rLog | rbx-log | +| -------------------------------------------- | ------- | ------- | +| Sinks | | | +| Enrichers | | | +| Source Context | | | +| Log Levels | | | +| Structured Logging | | | +| Minimum Log Level logging | | | +| Automatic property enrichment | | | +| Message Templates | | | +| Automatic Correlation ID generation | | | +| Correlation ID tracking | | | +| Log cascading (Context Bypass) | | | +| Surface level roblox data-type serialization | | | +| Nested roblox data-type serialization | | | +| Class serialization | | | +| Custom method serialization | | | +| Deep serialization | | | +| Function serialization | | | +| Configurable roblox data-type serialization | | | +| Log prefixes (tags) | | | +| Fatal severity | | | +| Global logging | | | +| Instance logging | | | + +If you're just starting, look at code samples of both and just go with the one that feels more natural to you +personally. + +Then, if you get to a point where you need a certain feature that the other provides, migrating to-and-from either is +fairly straightforward. + +### Why can't the library automatically pass around LogContext? + +This was something I spent a lot of time thinking on. If you come up with a solution, I'd be more than happy to +implement it. + +So let's ask the question: how do we automatically infer the context of a log? + +I came up with two possible solutions. + +#### Matching threads to context + +You can get a reference to the current thread via `coroutine.running`. You could then create a table mapping these to +their respective contexts. + +```ts +const contextTracker: Record = []; +``` + +The biggest problem with this is that it breaks across asynchronous boundaries. + +```ts +async function DoOtherThing() { + return coroutine.running(); +} + +async function DoThing() { + const thread = coroutine.running(); + const otherThread = await DoOtherThing(); + + // thread !== otherThread + // error-next-line + assert(thread === otherThread); +} +``` + +Internally, individual coroutines are creating per async function. + +Because of this, we've now lost our `LogContext`. + +##### Coroutine hierarchy + +If we could _somehow_ have a hierarchy of coroutines; a tree of which coroutines created which, then we could make this +work. + +Roblox doesn't provide anything like this though. + +You _could_ abuse `setfenv` to wrap around all `coroutine.create` calls and `task.spawn` calls- but the performance hit +would be way too large. Because, keep in mind, that you'd need to wrap around _all_ modules; even external ones. + +#### Using the function environment + +Another solution I came up with was recursively tracing the stack for a `userdata` property in the function environment +that can identify the `LogContext`. + +This _might_ work, but it'd require using `getfenv`, which would disable luau optimizations wherver you're logging. Not +to mention the performance implications it could have. + +#### Using a Transformer + +The last solution I came up with was providing some sort of transformer to automate the process. + +For example, maybe providing a `@LogContext` annotation that would mark consumers of log context- and automatically +change calls accordingly. + +```ts title="Before" +@LogContext +function SomeFunction() { + const logger = context.use(); + // ... +} + +withLogContext(() => { + SomeFunction(); +}); +``` + +```ts title="After" +function SomeFunction(context: LogContext) { + const logger = context.use(); + // ... +} + +withLogContext((context) => { + SomeFunction(context); +}); +``` + +Or maybe even a transformer that looks at the AST and figures out where context is needed, and drills it down. + +```ts title="Before" +function SomeFunctionThatLogs() { + rLogger.info("Hello world!"); +} + +function SomeFunction() { + SomeFunctionThatLogs(); +} + +withLogContext(() => { + SomeFunction(); +}); +``` + +```ts title="After" +function SomeFunctionThatLogs(context: LogContext) { + const logger = context.use(); + logger.info("Hello world!"); +} + +function SomeFunction(context: LogContext) { + SomeFunctionThatLogs(context); +} + +withLogContext((context) => { + SomeFunction(context); +}); +``` + +Either of these might actually work. The problem is that it would require a moderate amount of investment, and a lot of +testing. + +The one thing you _don't_ want to have edge cases in is your logging. + +Both of these are inherently "automagical", and are also very error prone if not implemented correctly. + +I might revisit this in the future and try to implement it, but it's something that's outside the scope of what I have +time (and the mental capacity) for currently. + +### Why should I create different rLog instances? + +You don't have to. If you don't need the extra configuration, or correlation id tracking, then you can just use the +[default instance](./basics/default-instance.mdx). + +However, there are several benefits to creating individual instances: + +1. You have more fine-grained control over configuration. + + - With individual instances, you can setup configuration settings that only apply to _some_ instances but not others. + This configuration could range from something as simple as different tags- to something more complex like custom + class encoding. + +2. You're able to take advantage of correlation ids. + + - Correlation IDs create a link between logs, allowing you to differentiate between outputs of the same log- but in + different invocations. In high traffic environments, they're a life saver when it comes time to debug. + +3. It forces you into a more functional approach. + + - Individual instances forces you to design your system in a more functional manner, in order to properly take + advantage of them. Whether this is an advantage or not depends on your coding style. For me personally, I take + towards a more functional style- so I enjoy having systems that enforce that. + +4. It helps avoid configuration coupling. + + - Since you're able to configure each instance in isolation, it allows you to make decisions about your logging + configurations on a case-by-case basis; avoiding the common pitfall of trying to wrok around a global configuration + in edge case sitations. + +5. You're more aware of where and how you're logging. + - One of the most important aspects is that it conditions you to be more aware of _when_ and _how_ you're logging. Or + more specifically, it conditions you to be more aware of when you're _not_ logging. Since you're creating instances + on a case-by-case basis, whenever you're missing one for a new class or module- it becomes a lot more apparent. + This can help you avoid missing data when it comes time to debug. + +### Are there plans to support message templates? + +The decision not to support message templates was intentional, and template support will not be added to **rLog**. + +If you want template support, I suggest you check out [rbx-log](https://github.com/roblox-aurora/rbx-log). + +#### Why? + +One of the core design philosophies of **rLog** is a seperation of the core logging message and the data associated with +it. This decision comes from my personal (and professional) experience in using various logging frameworks in large +scale applications. + +Namely, message templates can cause two common problems: + +1. Messages become overtly verbose. + + - When data is mixed in with your log messages, it becomes more difficult to understand _what_ a log is saying at a + glance. Especially when your data is niche or extensively large. When working with a large collection of logs, this + can significantly increase cognitive load when debugging- and just generally causes more problems than it helps + fix. + +2. It becomes significantly harder to `grep` logs. + - Because your messages are dynamic, it becomes much harder to filter logs according to simple queries. You have to + come up with more complex patterns; ones that may or may not cover all the edge-cases. Seeing as how logs are + typically the one thing you _don't_ want to deal with edge-cases on, this can become a huge issue. + +Although, both of these problems can be fixed by enforcing proper logging practices. For example, only using templates +with simple types, or ensuring you prefix all your log messages with a simple string before going in depth. + +But I'd rather _not_ deal with that. By not supporting message templates, you're forced to practice proper logging +practices anyways by providing clear and concise log messages; attaching data as a secondary filter when needed. + +It also makes log processing much faster, simpler, and reduces the corners (and possible edge-cases) that the logging +framework has to cover. + +### Can you add a sink for XYZ? + +Absolutely! If you have a platform or use-case that you feel is common enough, or practical enough, that a provided sink +should be made for it- I'd love to add it. + +[Open an issue](https://github.com/daymxn/rLog/issues) on the GitHub requesting the sink, and explain why you think it +should be added. When I get the free-time, I'll work on an implementation and add it to the list of provided loggers. + +Alternatively, you can [create your own PR](https://github.com/daymxn/rLog/pulls) adding the sink, and I can review that +as well. I won't always have the time to invest in implementing new sinks, so if you can add it yourself- it's much +easier for me to give a quick code-review than it is to research and implement the sink from scratch. + +### How can I export/filter my logs? + +While **rLog** does provide a bunch of utilities and configuration to help filter your logs before they hit the console, +sometimes, that's not sufficient.. Sometimes you may want to aggregate your logs and look at the big picture. + +In these cases, you'll wanna use a sink that sends your logs to _some_ external service. These external services usually +provide _rich_ in-house support for filtering, aggregating, and exporting logs. + +A popular choice, which **rLog** actually provides in-house support for, is +[Google Cloud Logging](https://cloud.google.com/logging). + +You can check out the [Getting started with Google Cloud Logging](./advanced/google-cloud-logging.mdx) guide to learn +more. + +### Can I use this for client-side logging too? + +**rLog** is advertised as a "server-side" logging framework, and it's designed to _only_ be ran on the server. + +But that isn't necessarily strictly enforced. You _can_ use **rLog** on the client-side as well. + +The drawback is that you can't cross client to server boundaries with context, and certain features may not work (such +as Google Cloud Logging). + +Client-side logging is basically a "provided as is" use case; if it works it works, but if it doesn't then I won't be +investing much time fixing it. + +### This is confusing, you could have phrased X better + +After working on something for an extended period, certain knowledge becomes "common sense". + +There might be a better way to explain certain features or processes, and I just completely overlooked it because of my +existing knowledge and bias. + +So I'm always _more_ than happy to take feedback; especially regarding documentation or design improvements. + +If you have such feedback, feel free to [open an issue](https://github.com/daymxn/rLog/issues) on the GitHub talking +about it:) diff --git a/wiki/docs/fast-breakdown.mdx b/wiki/docs/fast-breakdown.mdx new file mode 100644 index 0000000..d4716ca --- /dev/null +++ b/wiki/docs/fast-breakdown.mdx @@ -0,0 +1,604 @@ +# Fast Breakdown + +If you're already familiar with logging libraries, or just want a quick breakdown of **rLog** without reading through +the API or guides, then this is for you. + +We'll run through all the core components of **rLog** at a mid-high level, so you can get up and running quickly. + +## Instance creation + +`rLog` provides a default ("global") instance that you can use, but the intended usage is to create individual instances +per file or flow. + +```ts +import { rLog, rLogger } from "@rbxts/rlog"; + +// use the default instance +rLogger.info("Hello world!"); + +// create your own instance +const logger = new rLog(); +``` + +There are also alias exports that you can use in place of `rLog`, for stylistic purposes. + +```ts +import { RLog, rLog, rlog } from "@rbxts/rlog"; + +const logger = new rLog(); +const logger = new rlog(); +const logger = new RLog(); +``` + +## Basic Logging + +**rLog** supports log severity levels under the `LogLevel` enum. + +There are currently five types of levels. + +```ts +export enum LogLevel { + VERBOSE, + DEBUG, + INFO, + WARNING, + ERROR, +} +``` + +By default, `WARNING` and `ERROR` are output via `warn`, while the others are output via `print`. + +All logging methods can be called directly on an `rLog` instance using the method corresponding to the level name. + +Or you can call the `log` method manually. + +```ts +import { rLog, LogLevel } from "@rbxts/rlog"; + +const logger = new rLog(); + +logger.verbose("Hello verbose!"); +logger.debug("Hello debug!"); +logger.info("Hello info!"); +logger.warning("Hello warning!"); +logger.error("Hello error!"); + +logger.log(LogLevel.DEBUG, "Hello world!"); +``` + +```logs title="Console" +[VERBOSE]: Hello verbose! +[DEBUG]: Hello debug! +[INFO]: Hello info! +[WARNING]: Hello warning! +[ERROR]: Hello error! +[DEBUG]: Hello world! +``` + +Each level also has at least one short-hand alias method that you can use for style purposes. + +```ts +logger.verbose(); +logger.v(); + +logger.debug(); +logger.d(); + +logger.info(); +logger.i(); + +logger.warning(); +logger.warn(); +logger.w(); + +logger.error(); +logger.e(); +``` + +## Configuration + +**rLog** has a moderate number of configurable options available via the [RLogConfig](#) and [SerializationConfig](#) +types. + +You can apply these in a few different ways. + +### Global Settings + +You can apply settings to the default instance, and they'll be applied to all **rLog** instances automatically since +they all inherit upwards. + +```ts +import { rLog, LogLevel } from "@rbxts/rlog"; + +const config = { + minLogLevel: LogLevel.DEBUG, +}; + +// Sets the default config, replacing any present values +rLog.SetDefaultConfig(config); + +// Updates the default config, merging with the existing config +rLog.UpdateDefaultConfig({ serialization: { encodeFunctions: true } }); + +// Resets the default config to the original values +rLog.ResetDefaultConfig(); +``` + +:::warning + +While these settings are automatically applied to all instances, they are only done so for instances created after the +method call. + +If you're using context properly, this is usually not an issue though. + +::: + +### Instance Settings + +The normal way for applying settings is through the constructor of **rLog**. + +```ts +import { rLog, LogLevel } from "@rbxts/rlog"; + +const logger = new rLog({ minLogLevel: LogLevel.DEBUG }); +``` + +But there are also helper methods for many of the common settings that you can call on instances instead. + +```ts +const logger = new rLog() + .withConfig(myConfig) + .withMinLogLevel(LogLevel.DEBUG) + .withTag("Main") + .withContext(customContext); +``` + +:::warning + +**rLog** follows the principle of immutability. + +So method calls return _new_ instances, not the current instance. + +::: + +## Serialization + +**rLog** provides serialization out of the box; allowing you to attach "metadata" to your messages for easier debugging +and tracking. + +### Basic Usage + +You can pass arbitrary data as the second argument of a logging method call, and it will be internally encoded and +output alongside your message. + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog(); + +logger.debug("User purchase made", { user: 123, order: "51015" }); +``` + +```logs title="Console" +[DEBUG]: Hello debug! +{ data: { user: 123, order: "51015" } } +``` + +### ROBLOX Types & Nested Tables + +The custom encoding provided by **rLog** also supports deeply nested tables and Roblox data types out of the box. + +```ts +import { rLog } from "@rbxts/rlog"; + +const logger = new rLog(); + +logger.debug("User purchase made", { + user: { + id: 123, + purchase: { + id: 15, + details: { + item: "Nuke", + result: Enum.ProductPurchaseDecision.PurchaseGranted, + position: new Vector3(10, 15, 20), + rotation: new CFrame(), + }, + }, + }, +}); +``` + +```logs title="Console" +[DEBUG]: Hello debug! +{ + data: { + user: { + id: 123, + purchase: { + id: 15, + details: { + item: "Nuke", + result: "Enum.ProductPurchaseDecision.PurchaseGranted", + position: { X: 10, Y: 15, Z: 20 }, + rotation: "CFrame(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)", + } + } + } + } +} +``` + +:::tip + +While the ROBLOX console may (or may not, depending on the version) output them in a way that doesn't look like it, they +are actually output as valid JSON elements. + +So the output of your messages can safely be sent to backends expecting JSON. + +::: + +### Classes + +By default, serialization looks for a `__tostring` method on class instances to try to encode them properly. This method +is automatically generated by **rbxts** for typescript classes, with a value of the class name. + +```ts +import { rLog } from "@rbxts/rlog"; + +class Person { + constructor(public name: string) {} +} + +const logger = new rLog(); + +const person = new Person("Daymon"); + +logger.debug("Person created", { me: person }); +``` + +```logs title="Console" +[DEBUG]: Person created +{ data: { me: "Person" } } +``` + +While you can override this behavior by providing your own `toString` method on the class, you can also provide a custom +`encodeMethod` for the serializer to look for. + +```ts +import { rLog } from "@rbxts/rlog"; + +class Person { + constructor(public name: string) {} + + public encode() { + return this.name; + } +} + +const logger = new rLog({ serialization: { encodeMethod: "encode" } }); + +const person = new Person("Daymon"); + +logger.debug("Person created", { me: person }); +``` + +```logs title="Console" +[DEBUG]: Person created +{ data: { me: "Daymon" } } +``` + +## Enrichers + +Enrichers are callbacks that can attach additional data to log entries, or mutate existing data. + +```ts +export type LogEnricherCallback = (entry: LogEntry) => LogEntry; +``` + +### Usage + +You can use enrichers by specifying them at the config level when you create your **rLog** instance. + +:::tip + +**rLog** comes packaged with some ready-to-use enrichers out of the box for common use-cases. + +You can learn more about those in the [Provided Enrichers](./basics/enrichers#provided-enrichers) section. + +::: + +```ts +import { rLog } from "@rbxts/rlog"; + +function addTimestamp(entry: LogEntry): LogEntry { + entry.encoded_data["timestamp"] = DateTime.now(); + + return entry; +} + +const logger = new rLog({ enrichers: [addTimestamp] }); +``` + +## Sinks + +Sinks are callbacks that take in a log entry, and can optionally decide to prevent the log entry from propogating. + +They provide a way to filter or "consume" logs. + +```ts +// returning `true` means that the log should not be processed any more +export type LogSinkCallback = (entry: LogEntry, attachment: RLog, source: RLog) => boolean | void; +``` + +:::warning + +Sinks run _after_ enrichers. So the data you see from a sink will be data that has been modified by all the enrichers +already. + +::: + +### Usage + +You can use sinks by providing them at the config level when you create your **rLog** instance. + +:::tip + +**rLog** comes packaged with some ready-to-use sinks out of the box for common use-cases. + +You can learn more about those in the [Provided Sinks](./basics/sinks#provided-sinks) section. + +::: + +```ts +import { rLog } from "@rbxts/rlog"; +import { adminList } from "./constants"; + +function removeAdminCalls(entry: LogEntry) { + return entry.tag === "ADMIN" && !adminList.include(entry.encoded_data.player); +} + +const logger = new rLog({ sinks: [removeAdminCalls] }); +``` + +However, a more common use case for sinks is "consuming" logs for external storage. + +```ts +import { RunService } from "@rbxts/services"; +import { rLog } from "@rbxts/rlog"; +import { queueLogRequest } from "./log-database"; + +const debug = RunService.IsStudio(); + +function logToDatabase(entry: LogEntry) { + const endpoint = debug ? "qa" : "prod"; + + queueLogRequest(entry, endpoint); + + return !debug; // only allow messages through while we're in studio +} + +const logger = new rLog({ sinks: [logToDatabase] }); +``` + +:::warning + +Your sinks should **not** yield, as they may otherwise cause other logs to stop being output, or cause logs to be output +out of order. + +::: + +## Log Context + +Log Context provides a way to create linkage between log entries in an individual flow, making debugging easier in +high-traffic or asynchronous environments. + +### Basic Usage + +Log Context is primarily useful in cross service logging, where you want to associate all the relevant actions in a flow +with one another. + +```ts title="datastore.ts" +import { rLog, LogContext } from "@rbxts/rlog"; + +const config = { tag: "Datastore" }; + +export function AddMoney(context: LogContext, player: Player, money: number) { + const logger = context.use(config); + + logger.i("Adding money to player save"); + // ... + logger.i("Money added"); +} +``` + +```ts title="player-actions.ts" +import { rLog, LogContext } from "@rbxts/rlog"; +import { AddMoney } from "./datastore"; + +const config = { tag: "PlayerActions" }; + +export function GiveMoney(context: LogContext, player: Player, money: number) { + const logger = context.use(config); + + logger.i("Giving player money", { player: player, money: money }); + + AddMoney(context, player, money); + + logger.i("Money given to player"); +} +``` + +```ts title="network.ts" +import { LogContext } from "@rbxts/rlog"; +import { GiveMoney } from "./player-actions"; +import { remotes } from "./remotes"; + +remotes.giveMoney.connect((player: Player, money: number) => { + const context = LogContext.start(); + + GiveMoney(context, player, money); + + context.stop(); +}); +``` + +```logs title="Console" +[INFO]: PlayerActions -> Giving player money +{ + data: { player: "Player1", money: 100 }, + correlation_id: "ZnT961Kwlav6JFii" +} + +[INFO]: Datastore -> Adding money to player save +{ correlation_id: "ZnT961Kwlav6JFii" } + +[INFO]: Datastore -> Money added +{ correlation_id: "ZnT961Kwlav6JFii" } + +[INFO]: PlayerActions -> Money given to player +{ correlation_id: "ZnT961Kwlav6JFii" } +``` + +:::warning + +Log Context has a life cycle. Failing to call `stop` can cause memory leaks in your application. + +If you'd rather not manually handle this, you can use `withLogContext` instead: + +```ts +import { withLogContext } from "@rbxts/rlog"; +import { GiveMoney } from "./player-actions"; +import { remotes } from "./remotes"; + +remotes.giveMoney.connect((player: Player, money: number) => { + // automatically starts and stops the context + withLogContext((context) => { + GiveMoney(context, player, money); + }); +}); +``` + +::: + +### Context Bypass + +Enabling the `contextBypass` setting will allow logs with context to bypass the `minLogLevel` whenever another log in +the context is of severity `WARNING` or higher. + +```ts +import { rLog, withContext } from "@rbxts/rlog"; + +rLog.UpdateDefaultConfig({ minLogLevel: WARNING }); + +const config = { contextBypass: true, suspendContext: true }; + +withContext((context) => { + const logger = context.use(config); + + logger.d("Some extra data"); + logger.i("Doing stuff"); + logger.w("Something happened"); + logger.i("Done"); +}); +``` + +```logs title="Console" +[DEBUG]: Some extra data +{ correlation_id: "BNPmmqDsnpLdWiPF" } + +[INFO]: Doing stuff +{ correlation_id: "BNPmmqDsnpLdWiPF" } + +[WARNING]: Something happened +{ correlation_id: "BNPmmqDsnpLdWiPF" } + +[INFO]: Done +{ correlation_id: "BNPmmqDsnpLdWiPF" } +``` + +Since a `WARNING` message was sent through the context before it stopped, the rest of the messages in the context that +usually wouldn't have been sent were also sent. + +This can be a huge help in avoiding extra verbose logs until you actually need them (ie; when debugging). + +### Correlation IDs + +One of the biggest use cases for Log Context is Correlation IDs. + +Correlation IDs provide a way to track the flow of a process, and by default Log Context create their own unique +Correlation ID when they're created- and pass it to `rLog` instances that `use` it. + +```ts title="datastore.ts" +import { rLog, LogContext } from "@rbxts/rlog"; + +const config = { tag: "Datastore" }; + +export function AddMoney(context: LogContext, player: Player, money: number) { + const logger = context.use(config); + + logger.i("Adding money to player save"); + // ... + logger.i("Money added"); +} +``` + +```ts title="player-actions.ts" +import { rLog, LogContext } from "@rbxts/rlog"; +import { AddMoney } from "./datastore"; + +const config = { tag: "PlayerActions" }; + +export function GiveMoney(context: LogContext, player: Player, money: number) { + const logger = context.use(config); + + logger.i("Giving player money", { player: player, money: money }); + + AddMoney(context, player, money); + + logger.i("Money given to player"); +} +``` + +```ts title="network.ts" +import { withLogContext } from "@rbxts/rlog"; +import { GiveMoney } from "./player-actions"; +import { remotes } from "./remotes"; + +remotes.giveMoney.connect((player: Player, money: number) => { + withLogContext((context) => { + GiveMoney(context, player, money); + }); +}); +``` + +```logs title="Console" +[INFO]: PlayerActions -> Giving player money +{ + data: { player: "Player1", money: 100 }, + correlation_id: "ZnT961Kwlav6JFii" +} + +[INFO]: Datastore -> Adding money to player save +{ correlation_id: "ZnT961Kwlav6JFii" } + +[INFO]: Datastore -> Money added +{ correlation_id: "ZnT961Kwlav6JFii" } + +[INFO]: PlayerActions -> Money given to player +{ correlation_id: "ZnT961Kwlav6JFii" } +``` + +Correlation IDs become especially useful in high traffic (possibly asynchronous) functions, where you may have multiple +players or systems waiting on the result of a function, but from different invocations and threads. + +With Correlation IDs, you can retrieve the logs of a particular run without the noise of unrelated runs. + +## Learning more + +If you have any pending questions or want to learn more, you can read through our [API reference](#), which includes +documentation for the entire public API. + +Alternatively, you can sift through our [comprehensive wiki/guide](category/guides). + +Or if you're more of a practical learner, take a look at our [example](#) to see how **rLog** can be used in practice. diff --git a/wiki/docs/quick-start.mdx b/wiki/docs/quick-start.mdx new file mode 100644 index 0000000..e83d957 --- /dev/null +++ b/wiki/docs/quick-start.mdx @@ -0,0 +1,156 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + +# Quick Start + +**rLog** is a context based server-side logging framework for ROBLOX, designed to help organize and structure your +logging process. + +This guide will walk you through the basics of getting started, in just a few steps. + +## Installation + +First, install `rlog` with your preferred package manager: + + + + +```bash title="Terminal" +npm install @rbxts/rlog +``` + + + + +```bash title="Terminal" +pnpm add @rbxts/rlog +``` + + + + +```bash title="Terminal" +yarn add @rbxts/rlog +``` + + + + +```toml title="wally.toml" +[dependencies] +Reflex = "daymxn/rlog@1.0.0" +``` + + + + +## Start using rLog + +Once installed, you can immediately start with creating an **rLog** instance. + +```ts +import { rLog } from "@rbxts/rlog"; + +// Initialize the logger +const logger = new rLog(); +``` + +:::tip + +You can also use the default ("global") instance if you don't need (or want) to create your own. + +```ts +import { rLogger } from "@rbxts/rlog"; +``` + +::: + +### Logging your first message + +Logging messages is easy and straightforward with **rLog**. + +Just call the method for your intended `LogLevel`, and pass in a message. + +```ts +logger.info("Hello world!"); +``` + +```logs title="Console" +[INFO]: Hello world! +``` + +### Adding data to your message + +By passing a table as the second parameter to your logging method, you can optionally output data with your message. + +```ts +logger.info("Hello world!", { + user: "Daymon", + action: "start", +}); +``` + +```logs title="Console" +[INFO]: Hello world! +{ + data: { + user: "Daymon", + action: "start" + } +} +``` + +#### ROBLOX data types + +The table you pass is automatically encoded, and even supports ROBLOX data types! + +```ts +logger.info("Hello world!", { + position: new Vector3(1, 5, 10), + rotation: new CFrame(), +}); +``` + +```logs title="Console" +[INFO]: Hello world! +{ + data: { + position: { X: 1, Y: 5, Z: 10 }, + rotation: "CFrame(0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1)" + } +} +``` + +### Configuration + +If you need more control over your logging setup, you can configure **rLog** with enrichers, custom log levels, and +more: + +```ts +import { rLog, LogLevel } from "@rbxts/rlog"; + +// Advanced setup with custom serialization and enrichers +const logger = new rLog({ + minLogLevel: LogLevel.WARNING, + tag: "Main", + enrichers: [ + (entry) => { + entry.encoded_data.timestamp = DateTime.now().ToIsoDate(); + return entry; + }, + ], + serialization: { + encodeFunctions: true, + }, +}); +``` + +### Next Steps + +If you're wanting to learn more, feel free to check out any of the following resources: + +- [Fast Breakdown](fast-breakdown) +- [API Reference](#) +- [Basic Guides](basics/log-entries) +- [Advanced Guides](advanced/source-metadata) +- [Setting up Google Cloud Logging](advanced/google-cloud-logging) diff --git a/wiki/docs/sidebars.ts b/wiki/docs/sidebars.ts new file mode 100644 index 0000000..0ff3521 --- /dev/null +++ b/wiki/docs/sidebars.ts @@ -0,0 +1,45 @@ +import { SidebarsConfig } from "@docusaurus/plugin-content-docs"; + +const sidebars: SidebarsConfig = { + docs: [ + { + type: "category", + label: "Getting Started", + collapsed: false, + items: ["quick-start", "fast-breakdown", "faq"], + }, + { + type: "category", + label: "Guides", + link: { + type: "generated-index", + title: "rLog Guides", + description: "Learn about the basics of rLog.", + keywords: ["guides"], + }, + items: [ + "basics/log-entries", + "basics/log-levels", + "basics/tags", + "basics/default-instance", + "basics/serialization", + "basics/enrichers", + "basics/sinks", + "basics/log-context", + ], + }, + { + type: "category", + label: "Advanced Guides", + link: { + type: "generated-index", + title: "rLog Advanced Guides", + description: "Continue your learning journey with more advanced topics.", + keywords: ["guides", "advanced-guides"], + }, + items: ["advanced/source-metadata", "advanced/roblox-console-configuration", "advanced/google-cloud-logging"], + }, + ], +}; + +export default sidebars; diff --git a/wiki/docusaurus.config.ts b/wiki/docusaurus.config.ts new file mode 100644 index 0000000..144b45d --- /dev/null +++ b/wiki/docusaurus.config.ts @@ -0,0 +1,162 @@ +/* eslint-disable roblox-ts/no-regex */ +import type * as Preset from "@docusaurus/preset-classic"; +import type { Config } from "@docusaurus/types"; +import { themes as prismThemes } from "prism-react-renderer"; + +const config: Config = { + title: "rLog", + tagline: "Context based Server-Side logging for ROBLOX.", + favicon: "img/favicon.ico", + + // Set the production url of your site here + url: "https://your-docusaurus-site.example.com", + // Set the // pathname under which your site is served + // For GitHub pages deployment, it is often '//' + baseUrl: "/", + organizationName: "daymxn", + projectName: "rLog", + onBrokenLinks: "throw", + onBrokenMarkdownLinks: "warn", + i18n: { + defaultLocale: "en", + locales: ["en"], + }, + + headTags: [ + { + tagName: "link", + attributes: { + rel: "stylesheet", + href: "https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap", + }, + }, + { + tagName: "link", + attributes: { + rel: "preconnect", + href: "https://fonts.googleapis.com", + }, + }, + { + tagName: "link", + attributes: { + rel: "preconnect", + href: "https://fonts.gstatic.com", + crossorigin: "anonymous", + }, + }, + ], + + presets: [ + [ + "classic", + { + docs: { + sidebarPath: "./docs/sidebars.ts", + }, + theme: { + customCss: "./src/css/custom.css", + }, + } satisfies Preset.Options, + ], + ], + + themeConfig: { + // Replace with your project's social card + image: "img/social-card.jpg", + sidebar: { + hideable: true, + }, + navbar: { + title: "rLog", + logo: { + alt: "rLog logo", + src: "img/logo.svg", + }, + items: [ + { + type: "docSidebar", + sidebarId: "docs", + position: "left", + label: "Learn", + }, + ], + }, + footer: { + style: "dark", + links: [ + { + title: "Learn", + items: [ + { + label: "Quick Start", + to: "/docs/quick-start", + }, + { + label: "Fast Breakdown", + to: "/docs/fast-breakdown", + }, + { + label: "Guides", + to: "/docs/category/guides", + }, + { + label: "FAQ", + to: "/docs/faq", + }, + ], + }, + { + title: "API Reference", + items: [ + { + label: "rLog API", + to: "/docs/", + }, + ], + }, + { + title: "Community Discords", + items: [ + { + label: "roblox-ts", + href: "https://discord.roblox-ts.com/", + }, + ], + }, + { + title: "More", + items: [ + { + label: "GitHub", + href: "https://github.com/daymxn/rLog", + }, + ], + }, + ], + copyright: `Copyright © ${new Date().getFullYear()} Daymon LR`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.vsDark, + additionalLanguages: ["bash", "typescript", "lua", "powershell", "toml"], + magicComments: [ + { + className: "theme-code-block-highlighted-line", + line: "highlight-next-line", + block: { start: "highlight-start", end: "highlight-end" }, + }, + { + className: "theme-info-highlighted-line", + line: "info-next-line", + }, + { + className: "code-block-error-line", + line: "error-next-line", + }, + ], + }, + } satisfies Preset.ThemeConfig, +}; + +export default config; diff --git a/wiki/package-lock.json b/wiki/package-lock.json new file mode 100644 index 0000000..810a65f --- /dev/null +++ b/wiki/package-lock.json @@ -0,0 +1,14997 @@ +{ + "name": "rlog-wiki", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "rlog-wiki", + "version": "0.0.0", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/preset-classic": "3.5.2", + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", + "@iconify/react": "^5.0.2", + "@mdx-js/react": "^3.0.0", + "@mui/material": "^5.16.7", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/tsconfig": "3.5.2", + "@docusaurus/types": "3.5.2", + "prettier": "^3.3.3", + "typescript": "^5.4.2" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@algolia/autocomplete-core": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", + "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "dependencies": { + "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", + "@algolia/autocomplete-shared": "1.9.3" + } + }, + "node_modules/@algolia/autocomplete-plugin-algolia-insights": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", + "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "search-insights": ">= 1 < 3" + } + }, + "node_modules/@algolia/autocomplete-preset-algolia": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", + "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "dependencies": { + "@algolia/autocomplete-shared": "1.9.3" + }, + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/autocomplete-shared": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", + "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "peerDependencies": { + "@algolia/client-search": ">= 4.9.1 < 6", + "algoliasearch": ">= 4.9.1 < 6" + } + }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", + "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", + "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", + "dependencies": { + "@algolia/cache-common": "4.24.0" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", + "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", + "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", + "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", + "dependencies": { + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", + "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", + "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", + "dependencies": { + "@algolia/client-common": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + }, + "node_modules/@algolia/logger-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" + }, + "node_modules/@algolia/logger-console": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", + "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", + "dependencies": { + "@algolia/logger-common": "4.24.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", + "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", + "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" + }, + "node_modules/@algolia/requester-node-http": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", + "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", + "dependencies": { + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", + "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", + "dependencies": { + "@algolia/cache-common": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/requester-common": "4.24.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", + "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "dependencies": { + "@babel/types": "^7.25.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz", + "integrity": "sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "dependencies": { + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", + "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/traverse": "^7.25.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz", + "integrity": "sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", + "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", + "dependencies": { + "@babel/traverse": "^7.24.8", + "@babel/types": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz", + "integrity": "sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-wrap-function": "^7.25.0", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", + "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.24.8", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz", + "integrity": "sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==", + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", + "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", + "dependencies": { + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", + "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "dependencies": { + "@babel/types": "^7.25.2" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz", + "integrity": "sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz", + "integrity": "sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz", + "integrity": "sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz", + "integrity": "sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz", + "integrity": "sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz", + "integrity": "sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz", + "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", + "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz", + "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz", + "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz", + "integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz", + "integrity": "sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz", + "integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-replace-supers": "^7.25.0", + "@babel/traverse": "^7.25.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz", + "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/template": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz", + "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz", + "integrity": "sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz", + "integrity": "sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz", + "integrity": "sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz", + "integrity": "sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz", + "integrity": "sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz", + "integrity": "sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz", + "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz", + "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/traverse": "^7.25.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz", + "integrity": "sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz", + "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz", + "integrity": "sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz", + "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz", + "integrity": "sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz", + "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.8", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-simple-access": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz", + "integrity": "sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz", + "integrity": "sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==", + "dependencies": { + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz", + "integrity": "sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz", + "integrity": "sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz", + "integrity": "sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz", + "integrity": "sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz", + "integrity": "sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz", + "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz", + "integrity": "sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz", + "integrity": "sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz", + "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz", + "integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz", + "integrity": "sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz", + "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.25.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.1.tgz", + "integrity": "sha512-SLV/giH/V4SmloZ6Dt40HjTGTAIkxn33TVIHxNGNvo8ezMhrxBkzisj4op1KZYPIOHFLqhv60OHvX+YRu4xbmQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz", + "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz", + "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/types": "^7.25.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz", + "integrity": "sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz", + "integrity": "sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz", + "integrity": "sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz", + "integrity": "sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", + "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz", + "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz", + "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz", + "integrity": "sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz", + "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz", + "integrity": "sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", + "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.25.0", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz", + "integrity": "sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz", + "integrity": "sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz", + "integrity": "sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz", + "integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz", + "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==", + "dependencies": { + "@babel/compat-data": "^7.25.2", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.0", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.25.0", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.37.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.24.7.tgz", + "integrity": "sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-transform-react-display-name": "^7.24.7", + "@babel/plugin-transform-react-jsx": "^7.24.7", + "@babel/plugin-transform-react-jsx-development": "^7.24.7", + "@babel/plugin-transform-react-pure-annotations": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz", + "integrity": "sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.7", + "@babel/plugin-transform-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "node_modules/@babel/runtime": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.0.tgz", + "integrity": "sha512-BOehWE7MgQ8W8Qn0CQnMtg2tHPHPulcS/5AVpFvs2KCK1ET+0WqZqPvnpRpFN81gYoFopdIEJX9Sgjw3ZBccPg==", + "dependencies": { + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", + "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/parser": "^7.25.3", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.2", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", + "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "dependencies": { + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@docsearch/css": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.1.tgz", + "integrity": "sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==" + }, + "node_modules/@docsearch/react": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.1.tgz", + "integrity": "sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==", + "dependencies": { + "@algolia/autocomplete-core": "1.9.3", + "@algolia/autocomplete-preset-algolia": "1.9.3", + "@docsearch/css": "3.6.1", + "algoliasearch": "^4.19.1" + }, + "peerDependencies": { + "@types/react": ">= 16.8.0 < 19.0.0", + "react": ">= 16.8.0 < 19.0.0", + "react-dom": ">= 16.8.0 < 19.0.0", + "search-insights": ">= 1 < 3" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "search-insights": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.5.2.tgz", + "integrity": "sha512-4Z1WkhCSkX4KO0Fw5m/Vuc7Q3NxBG53NE5u59Rs96fWkMPZVSrzEPP16/Nk6cWb/shK7xXPndTmalJtw7twL/w==", + "dependencies": { + "@babel/core": "^7.23.3", + "@babel/generator": "^7.23.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-transform-runtime": "^7.22.9", + "@babel/preset-env": "^7.22.9", + "@babel/preset-react": "^7.22.5", + "@babel/preset-typescript": "^7.22.5", + "@babel/runtime": "^7.22.6", + "@babel/runtime-corejs3": "^7.22.6", + "@babel/traverse": "^7.22.8", + "@docusaurus/cssnano-preset": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.1.3", + "babel-plugin-dynamic-import-node": "^2.3.3", + "boxen": "^6.2.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "clean-css": "^5.3.2", + "cli-table3": "^0.6.3", + "combine-promises": "^1.1.0", + "commander": "^5.1.0", + "copy-webpack-plugin": "^11.0.0", + "core-js": "^3.31.1", + "css-loader": "^6.8.1", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "del": "^6.1.1", + "detect-port": "^1.5.1", + "escape-html": "^1.0.3", + "eta": "^2.2.0", + "eval": "^0.1.8", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "html-minifier-terser": "^7.2.0", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.5.3", + "leven": "^3.1.0", + "lodash": "^4.17.21", + "mini-css-extract-plugin": "^2.7.6", + "p-map": "^4.0.0", + "postcss": "^8.4.26", + "postcss-loader": "^7.3.3", + "prompts": "^2.4.2", + "react-dev-utils": "^12.0.1", + "react-helmet-async": "^1.3.0", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", + "react-loadable-ssr-addon-v5-slorber": "^1.0.1", + "react-router": "^5.3.4", + "react-router-config": "^5.1.1", + "react-router-dom": "^5.3.4", + "rtl-detect": "^1.0.4", + "semver": "^7.5.4", + "serve-handler": "^6.1.5", + "shelljs": "^0.8.5", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "url-loader": "^4.1.1", + "webpack": "^5.88.1", + "webpack-bundle-analyzer": "^4.9.0", + "webpack-dev-server": "^4.15.1", + "webpack-merge": "^5.9.0", + "webpackbar": "^5.0.2" + }, + "bin": { + "docusaurus": "bin/docusaurus.mjs" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/cssnano-preset": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.5.2.tgz", + "integrity": "sha512-D3KiQXOMA8+O0tqORBrTOEQyQxNIfPm9jEaJoALjjSjc2M/ZAWcUfPQEnwr2JB2TadHw2gqWgpZckQmrVWkytA==", + "dependencies": { + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.4.38", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/logger": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.5.2.tgz", + "integrity": "sha512-LHC540SGkeLfyT3RHK3gAMK6aS5TRqOD4R72BEU/DE2M/TY8WwEUAMY576UUc/oNJXv8pGhBmQB6N9p3pt8LQw==", + "dependencies": { + "chalk": "^4.1.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/mdx-loader": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.5.2.tgz", + "integrity": "sha512-ku3xO9vZdwpiMIVd8BzWV0DCqGEbCP5zs1iHfKX50vw6jX8vQo0ylYo1YJMZyz6e+JFJ17HYHT5FzVidz2IflA==", + "dependencies": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", + "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "image-size": "^1.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", + "stringify-object": "^3.3.0", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", + "url-loader": "^4.1.1", + "vfile": "^6.0.1", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/module-type-aliases": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.5.2.tgz", + "integrity": "sha512-Z+Xu3+2rvKef/YKTMxZHsEXp1y92ac0ngjDiExRdqGTmEKtCUpkbNYH8v5eXo5Ls+dnW88n6WTa+Q54kLOkwPg==", + "dependencies": { + "@docusaurus/types": "3.5.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "@types/react-router-dom": "*", + "react-helmet-async": "*", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/@docusaurus/plugin-content-blog": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.5.2.tgz", + "integrity": "sha512-R7ghWnMvjSf+aeNDH0K4fjyQnt5L0KzUEnUhmf1e3jZrv3wogeytZNN6n7X8yHcMsuZHPOrctQhXWnmxu+IRRg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "cheerio": "1.0.0-rc.12", + "feed": "^4.2.2", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "reading-time": "^1.5.0", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-docs": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.5.2.tgz", + "integrity": "sha512-Bt+OXn/CPtVqM3Di44vHjE7rPCEsRCB/DMo2qoOuozB9f7+lsdrHvD0QCHdBs0uhz6deYJDppAr2VgqybKPlVQ==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@types/react-router-config": "^5.0.7", + "combine-promises": "^1.1.0", + "fs-extra": "^11.1.1", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-content-pages": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.5.2.tgz", + "integrity": "sha512-WzhHjNpoQAUz/ueO10cnundRz+VUtkjFhhaQ9jApyv1a46FPURO4cef89pyNIOMny1fjDz/NUN2z6Yi+5WUrCw==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-debug": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.5.2.tgz", + "integrity": "sha512-kBK6GlN0itCkrmHuCS6aX1wmoWc5wpd5KJlqQ1FyrF0cLDnvsYSnh7+ftdwzt7G6lGBho8lrVwkkL9/iQvaSOA==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^1.2.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-analytics": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.5.2.tgz", + "integrity": "sha512-rjEkJH/tJ8OXRE9bwhV2mb/WP93V441rD6XnM6MIluu7rk8qg38iSxS43ga2V2Q/2ib53PcqbDEJDG/yWQRJhQ==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-gtag": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.5.2.tgz", + "integrity": "sha512-lm8XL3xLkTPHFKKjLjEEAHUrW0SZBSHBE1I+i/tmYMBsjCcUB5UJ52geS5PSiOCFVR74tbPGcPHEV/gaaxFeSA==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-google-tag-manager": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.5.2.tgz", + "integrity": "sha512-QkpX68PMOMu10Mvgvr5CfZAzZQFx8WLlOiUQ/Qmmcl6mjGK6H21WLT5x7xDmcpCoKA/3CegsqIqBR+nA137lQg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/plugin-sitemap": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.5.2.tgz", + "integrity": "sha512-DnlqYyRAdQ4NHY28TfHuVk414ft2uruP4QWCH//jzpHjqvKyXjj2fmDtI8RPUBh9K8iZKFMHRnLtzJKySPWvFA==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "fs-extra": "^11.1.1", + "sitemap": "^7.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/preset-classic": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.5.2.tgz", + "integrity": "sha512-3ihfXQ95aOHiLB5uCu+9PRy2gZCeSZoDcqpnDvf3B+sTrMvMTr8qRUzBvWkoIqc82yG5prCboRjk1SVILKx6sg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/plugin-content-blog": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/plugin-content-pages": "3.5.2", + "@docusaurus/plugin-debug": "3.5.2", + "@docusaurus/plugin-google-analytics": "3.5.2", + "@docusaurus/plugin-google-gtag": "3.5.2", + "@docusaurus/plugin-google-tag-manager": "3.5.2", + "@docusaurus/plugin-sitemap": "3.5.2", + "@docusaurus/theme-classic": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-search-algolia": "3.5.2", + "@docusaurus/types": "3.5.2" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-classic": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.5.2.tgz", + "integrity": "sha512-XRpinSix3NBv95Rk7xeMF9k4safMkwnpSgThn0UNQNumKvmcIYjfkwfh2BhwYh/BxMXQHJ/PdmNh22TQFpIaYg==", + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/plugin-content-blog": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/plugin-content-pages": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-translations": "3.5.2", + "@docusaurus/types": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", + "infima": "0.2.0-alpha.44", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "postcss": "^8.4.26", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-common": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.5.2.tgz", + "integrity": "sha512-QXqlm9S6x9Ibwjs7I2yEDgsCocp708DrCrgHgKwg2n2AY0YQ6IjU0gAK35lHRLOvAoJUfCKpQAwUykB0R7+Eew==", + "dependencies": { + "@docusaurus/mdx-loader": "3.5.2", + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router-config": "*", + "clsx": "^2.0.0", + "parse-numeric-range": "^1.3.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-search-algolia": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.5.2.tgz", + "integrity": "sha512-qW53kp3VzMnEqZGjakaV90sst3iN1o32PH+nawv1uepROO8aEGxptcq2R5rsv7aBShSRbZwIobdvSYKsZ5pqvA==", + "dependencies": { + "@docsearch/react": "^3.5.2", + "@docusaurus/core": "3.5.2", + "@docusaurus/logger": "3.5.2", + "@docusaurus/plugin-content-docs": "3.5.2", + "@docusaurus/theme-common": "3.5.2", + "@docusaurus/theme-translations": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-validation": "3.5.2", + "algoliasearch": "^4.18.0", + "algoliasearch-helper": "^3.13.3", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", + "lodash": "^4.17.21", + "tslib": "^2.6.0", + "utility-types": "^3.10.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/theme-translations": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.5.2.tgz", + "integrity": "sha512-GPZLcu4aT1EmqSTmbdpVrDENGR2yObFEX8ssEFYTCiAIVc0EihNSdOIBTazUvgNqwvnoU1A8vIs1xyzc3LITTw==", + "dependencies": { + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/tsconfig": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.5.2.tgz", + "integrity": "sha512-rQ7toURCFnWAIn8ubcquDs0ewhPwviMzxh6WpRjBW7sJVCXb6yzwUaY3HMNa0VXCFw+qkIbFywrMTf+Pb4uHWQ==", + "dev": true + }, + "node_modules/@docusaurus/types": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.5.2.tgz", + "integrity": "sha512-N6GntLXoLVUwkZw7zCxwy9QiuEXIcTVzA9AkmNw16oc0AP3SXLrMmDMMBIfgqwuKWa6Ox6epHol9kMtJqekACw==", + "dependencies": { + "@mdx-js/mdx": "^3.0.0", + "@types/history": "^4.7.11", + "@types/react": "*", + "commander": "^5.1.0", + "joi": "^17.9.2", + "react-helmet-async": "^1.3.0", + "utility-types": "^3.10.0", + "webpack": "^5.88.1", + "webpack-merge": "^5.9.0" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/utils": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.5.2.tgz", + "integrity": "sha512-33QvcNFh+Gv+C2dP9Y9xWEzMgf3JzrpL2nW9PopidiohS1nDcyknKRx2DWaFvyVTTYIkkABVSr073VTj/NITNA==", + "dependencies": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "@svgr/webpack": "^8.1.0", + "escape-string-regexp": "^4.0.0", + "file-loader": "^6.2.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", + "globby": "^11.1.0", + "gray-matter": "^4.0.3", + "jiti": "^1.20.0", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "micromatch": "^4.0.5", + "prompts": "^2.4.2", + "resolve-pathname": "^3.0.0", + "shelljs": "^0.8.5", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "utility-types": "^3.10.0", + "webpack": "^5.88.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/types": { + "optional": true + } + } + }, + "node_modules/@docusaurus/utils-common": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.5.2.tgz", + "integrity": "sha512-i0AZjHiRgJU6d7faQngIhuHKNrszpL/SHQPgF1zH4H+Ij6E9NBYGy6pkcGWToIv7IVPbs+pQLh1P3whn0gWXVg==", + "dependencies": { + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/types": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/types": { + "optional": true + } + } + }, + "node_modules/@docusaurus/utils-validation": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.5.2.tgz", + "integrity": "sha512-m+Foq7augzXqB6HufdS139PFxDC5d5q2QKZy8q0qYYvGdI6nnlNsGH4cIGsgBnV7smz+mopl3g4asbSDvMV0jA==", + "dependencies": { + "@docusaurus/logger": "3.5.2", + "@docusaurus/utils": "3.5.2", + "@docusaurus/utils-common": "3.5.2", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", + "js-yaml": "^4.1.0", + "lodash": "^4.17.21", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", + "integrity": "sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ==", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==" + }, + "node_modules/@emotion/react": { + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.1.tgz", + "integrity": "sha512-dEPNKzBPU+vFPGa+z3axPRn8XVDetYORmDC0wAiej+TNcOZE70ZMJa0X7JdeoM6q/nWTMZeLpN/fTnD9o8MQBA==", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==" + }, + "node_modules/@emotion/styled": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz", + "integrity": "sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==" + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + }, + "node_modules/@hapi/topo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", + "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@iconify/react": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@iconify/react/-/react-5.0.2.tgz", + "integrity": "sha512-wtmstbYlEbo4NDxFxBJkhkf9gJBDqMGr7FaqLrAUMneRV3Z+fVHLJjOhWbkAF8xDQNFC/wcTYdrWo1lnRhmagQ==", + "dependencies": { + "@iconify/types": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + }, + "peerDependencies": { + "react": ">=16" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==" + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" + }, + "node_modules/@mdx-js/mdx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", + "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-to-js": "^2.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@mdx-js/react": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", + "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz", + "integrity": "sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/material": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", + "integrity": "sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.16.7", + "@mui/system": "^5.16.7", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.3.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/@mui/private-theming": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", + "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.16.6", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", + "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.16.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz", + "integrity": "sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.16.6", + "@mui/styled-engine": "^5.16.6", + "@mui/types": "^7.2.15", + "@mui/utils": "^5.16.6", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.15", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz", + "integrity": "sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.16.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", + "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "^7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.25", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", + "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==" + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@sideway/address": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "dependencies": { + "@hapi/hoek": "^9.0.0" + } + }, + "node_modules/@sideway/formula": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", + "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + }, + "node_modules/@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.0.tgz", + "integrity": "sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg==", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.5", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz", + "integrity": "sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.2.0.tgz", + "integrity": "sha512-bm6EG6/pCpkxDf/0gDNDdtDILMOHgaQBVOJGdwsqClnxA3xL6jtMv76rLBc006RVMWbmaf0xbmom4Z/5o2nRkQ==", + "dependencies": { + "undici-types": "~6.13.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prismjs": { + "version": "1.26.4", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.4.tgz", + "integrity": "sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-router": { + "version": "5.1.20", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", + "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*" + } + }, + "node_modules/@types/react-router-config": { + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", + "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "^5.1.0" + } + }, + "node_modules/@types/react-router-dom": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", + "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "dependencies": { + "@types/history": "^4.7.11", + "@types/react": "*", + "@types/react-router": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", + "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", + "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + }, + "node_modules/@types/ws": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", + "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", + "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/algoliasearch": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", + "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.24.0", + "@algolia/cache-common": "4.24.0", + "@algolia/cache-in-memory": "4.24.0", + "@algolia/client-account": "4.24.0", + "@algolia/client-analytics": "4.24.0", + "@algolia/client-common": "4.24.0", + "@algolia/client-personalization": "4.24.0", + "@algolia/client-search": "4.24.0", + "@algolia/logger-common": "4.24.0", + "@algolia/logger-console": "4.24.0", + "@algolia/recommend": "4.24.0", + "@algolia/requester-browser-xhr": "4.24.0", + "@algolia/requester-common": "4.24.0", + "@algolia/requester-node-http": "4.24.0", + "@algolia/transporter": "4.24.0" + } + }, + "node_modules/algoliasearch-helper": { + "version": "3.22.3", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.3.tgz", + "integrity": "sha512-2eoEz8mG4KHE+DzfrBTrCmDPxVXv7aZZWPojAJFtARpxxMO6lkos1dJ+XDCXdPvq7q3tpYWRi6xXmVQikejtpA==", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/astring": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", + "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "bin": { + "astring": "bin/astring" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", + "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dependencies": { + "object.assign": "^4.1.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-macros/node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, + "node_modules/boxen": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", + "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.1.2", + "cli-boxes": "^3.0.0", + "string-width": "^5.0.1", + "type-fest": "^2.5.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "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.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001651", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", + "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", + "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "htmlparser2": "^8.0.1", + "parse5": "^7.0.0", + "parse5-htmlparser2-tree-adapter": "^7.0.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-table3/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/cli-table3/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "node_modules/combine-promises": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compressible/node_modules/mime-db": { + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/configstore": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "dependencies": { + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + }, + "node_modules/copy-text-to-clipboard": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", + "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", + "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "dependencies": { + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.1", + "globby": "^13.1.1", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/core-js": { + "version": "3.38.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.0.tgz", + "integrity": "sha512-XPpwqEodRljce9KswjZShh95qJ1URisBeKCjUdq27YdenkslVe7OO0ZJhlYXAChW7OhXaRLl8AAba7IBfoIHug==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.38.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.0.tgz", + "integrity": "sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==", + "dependencies": { + "browserslist": "^4.23.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.38.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.0.tgz", + "integrity": "sha512-8balb/HAXo06aHP58mZMtXgD8vcnXz9tUDePgqBgJgKdmTlMt+jw3ujqniuBDQXMvTzxnMpxHFeuSM3g1jWQuQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dependencies": { + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/css-loader": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-advanced": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", + "dependencies": { + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-preset-default": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/cssnano-utils": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, + "node_modules/debug": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "dependencies": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, + "node_modules/detect-port": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", + "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "4" + }, + "bin": { + "detect": "bin/detect-port.js", + "detect-port": "bin/detect-port.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/detect-port-alt": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", + "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.6.tgz", + "integrity": "sha512-jwXWsM5RPf6j9dPYzaorcBSUg6AiqocPEyMpkchkvntaH9HGfOOMZwxMJjDY/XEs3T5dM7uyH1VhRMkqUU9qVw==" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/emoticon": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", + "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-goat": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-value-to-estree": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.1.2.tgz", + "integrity": "sha512-S0gW2+XZkmsx00tU2uJ4L9hUT7IFabbml9pHh2WQqFmAbxit++YGZne0sKJbNwkj9Wvg9E4uqWl4nCIFQMmfag==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + }, + "node_modules/express/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==" + }, + "node_modules/fast-url-parser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", + "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "dependencies": { + "punycode": "^1.3.2" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/feed": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", + "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "dependencies": { + "xml-js": "^1.6.11" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/file-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/filesize": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", + "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", + "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "chokidar": "^3.4.2", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "glob": "^7.1.6", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "eslint": ">= 6", + "typescript": ">= 2.7", + "vue-template-compiler": "*", + "webpack": ">= 4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/github-slugger": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "node_modules/global-dirs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", + "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "dependencies": { + "ini": "2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "dependencies": { + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-yarn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.4.tgz", + "integrity": "sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", + "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.3.tgz", + "integrity": "sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==" + }, + "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.6.tgz", + "integrity": "sha512-khxq+Qm3xEyZfKd/y9L3oIWQimxuc4STrQKtQn8aSDRHb8mFgpukgX1hdzfrMEW6JCjyJ8p89x+IUMVnCBI1PA==", + "dependencies": { + "inline-style-parser": "0.2.3" + } + }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "bin": { + "he": "bin/he" + } + }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "node_modules/html-minifier-terser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.15.1" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", + "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", + "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/image-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "dependencies": { + "queue": "6.0.2" + }, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=16.x" + } + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/infima": { + "version": "0.2.0-alpha.44", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.44.tgz", + "integrity": "sha512-tuRkUSO/lB3rEhLJk25atwAjgLuzq070+pOW8XcvpHky/YbENnRRdPd85IBkyeTgttmOy5ah+yHYsK1HhUd4lQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "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.", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-installed-globally": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "dependencies": { + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-npm": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", + "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-root": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", + "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-yarn-global": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/joi": { + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", + "dependencies": { + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", + "@sideway/formula": "^3.0.1", + "@sideway/pinpoint": "^2.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "engines": { + "node": ">=6" + } + }, + "node_modules/latest-version": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "dependencies": { + "package-json": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/launch-editor": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.8.1.tgz", + "integrity": "sha512-elBx2l/tp9z99X5H/qev8uyDywVh0VXAwEbjk8kJhnc5grOFkGh7aW6q55me9xnYbss261XtnUrysZ+XvGbhQA==", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-table": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", + "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.1.tgz", + "integrity": "sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", + "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", + "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.2.tgz", + "integrity": "sha512-eKMQDeywY2wlHc97k5eD8VC+9ASMjN8ItEZQNGwJ6E0XWKiW/Z0V5/H8pvoXUf+y+Mj0VIgeRRbujBmFn4FTyA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^5.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", + "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-directive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.1.tgz", + "integrity": "sha512-VGV2uxUzhEZmaP7NSFo2vtq7M2nUD+WfmYQD+d8i/1nHbzE+rMy9uzTvUybBbNiVbrhOZibg3gbyoARGqgDWyg==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", + "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", + "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } + }, + "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", + "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-cancelable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "engines": { + "node": ">=12.20" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "dependencies": { + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" + }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", + "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "dependencies": { + "domhandler": "^5.0.2", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-colormin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-convert-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-comments": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-empty": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-discard-unused": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-loader": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", + "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", + "dependencies": { + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + } + }, + "node_modules/postcss-merge-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^6.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-merge-rules": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", + "dependencies": { + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-params": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", + "dependencies": { + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-string": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-url": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-ordered-values": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", + "dependencies": { + "cssnano-utils": "^4.0.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-idents": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sort-media-queries": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", + "dependencies": { + "sort-css-media-queries": "2.2.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.23" + } + }, + "node_modules/postcss-svgo": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^3.2.0" + }, + "engines": { + "node": "^14 || ^16 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", + "dependencies": { + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/postcss-zindex": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/prism-react-renderer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz", + "integrity": "sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + }, + "node_modules/pupa": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", + "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", + "dependencies": { + "escape-goat": "^4.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "dependencies": { + "inherits": "~2.0.3" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dev-utils": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", + "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "address": "^1.1.2", + "browserslist": "^4.18.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "detect-port-alt": "^1.1.6", + "escape-string-regexp": "^4.0.0", + "filesize": "^8.0.6", + "find-up": "^5.0.0", + "fork-ts-checker-webpack-plugin": "^6.5.0", + "global-modules": "^2.0.0", + "globby": "^11.0.4", + "gzip-size": "^6.0.0", + "immer": "^9.0.7", + "is-root": "^2.1.0", + "loader-utils": "^3.2.0", + "open": "^8.4.0", + "pkg-up": "^3.1.0", + "prompts": "^2.4.2", + "react-error-overlay": "^6.0.11", + "recursive-readdir": "^2.2.2", + "shell-quote": "^1.7.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/react-dev-utils/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/react-dev-utils/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dev-utils/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-error-overlay": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", + "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + }, + "node_modules/react-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "node_modules/react-helmet-async": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", + "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-json-view-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.4.0.tgz", + "integrity": "sha512-wh6F6uJyYAmQ4fK0e8dSQMEWuvTs2Wr3el3sLD9bambX1+pSWUVXIz1RFaoy3TI1mZ0FqdpKq9YgbgTTgyrmXA==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-loadable": { + "name": "@docusaurus/react-loadable", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", + "dependencies": { + "@types/react": "*" + }, + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-loadable-ssr-addon-v5-slorber": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", + "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "dependencies": { + "@babel/runtime": "^7.10.3" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "react-loadable": "*", + "webpack": ">=4.41.1 || 5.x" + } + }, + "node_modules/react-router": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", + "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-config": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", + "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "dependencies": { + "@babel/runtime": "^7.1.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router": ">=5" + } + }, + "node_modules/react-router-dom": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", + "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "dependencies": { + "@babel/runtime": "^7.12.13", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.3.4", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reading-time": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", + "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-mdx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", + "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", + "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/renderkid/node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/renderkid/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/renderkid/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "engines": { + "node": "*" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rtl-detect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", + "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" + }, + "node_modules/rtlcss": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.2.0.tgz", + "integrity": "sha512-AV+V3oOVvCrqyH5Q/6RuT1IDH1Xy5kJTkEWTWZPN5rdQ3HCFOd8SrbC7c6N5Y8bPpCfZSR6yYbUATXslvfvu5g==", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/search-insights": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.16.2.tgz", + "integrity": "sha512-+KrS5rnYlyWgzoCNJGsNPw7Vv+47Y7Ze7KZ+/9Xls+5BUugEbU2yv1n9JsQOqv+MLKYfg3bxI5K6tYJxXZY8FA==", + "peer": true + }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "dependencies": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/send/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-handler": { + "version": "6.1.5", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", + "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "fast-url-parser": "1.1.3", + "mime-types": "2.1.18", + "minimatch": "3.1.2", + "path-is-inside": "1.0.2", + "path-to-regexp": "2.2.1", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/path-to-regexp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", + "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "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" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "node_modules/sitemap": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", + "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sort-css-media-queries": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", + "engines": { + "node": ">= 6.3.0" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, + "node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/stylehacks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", + "dependencies": { + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", + "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unique-string": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "dependencies": { + "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-notifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", + "is-installed-globally": "^0.4.0", + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/boxen": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "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.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/url-loader/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/url-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.2.tgz", + "integrity": "sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", + "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.3", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-middleware/node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/serve-static": "^1.13.10", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.5", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "launch-editor": "^2.6.0", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.1.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.4", + "ws": "^8.13.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "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 + } + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpackbar": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", + "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", + "dependencies": { + "chalk": "^4.1.0", + "consola": "^2.15.3", + "pretty-time": "^1.1.0", + "std-env": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/wiki/package.json b/wiki/package.json new file mode 100644 index 0000000..4a8e929 --- /dev/null +++ b/wiki/package.json @@ -0,0 +1,52 @@ +{ + "name": "rlog-wiki", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc" + }, + "dependencies": { + "@docusaurus/core": "3.5.2", + "@docusaurus/preset-classic": "3.5.2", + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", + "@iconify/react": "^5.0.2", + "@mdx-js/react": "^3.0.0", + "@mui/material": "^5.16.7", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "3.5.2", + "@docusaurus/tsconfig": "3.5.2", + "@docusaurus/types": "3.5.2", + "prettier": "^3.3.3", + "typescript": "^5.4.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=18.0" + } +} diff --git a/wiki/src/components/HomepageFeatures/index.tsx b/wiki/src/components/HomepageFeatures/index.tsx new file mode 100644 index 0000000..50a9e6f --- /dev/null +++ b/wiki/src/components/HomepageFeatures/index.tsx @@ -0,0 +1,70 @@ +import clsx from 'clsx'; +import Heading from '@theme/Heading'; +import styles from './styles.module.css'; + +type FeatureItem = { + title: string; + Svg: React.ComponentType>; + description: JSX.Element; +}; + +const FeatureList: FeatureItem[] = [ + { + title: 'Easy to Use', + Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, + description: ( + <> + Docusaurus was designed from the ground up to be easily installed and + used to get your website up and running quickly. + + ), + }, + { + title: 'Focus on What Matters', + Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, + description: ( + <> + Docusaurus lets you focus on your docs, and we'll do the chores. Go + ahead and move your docs into the docs directory. + + ), + }, + { + title: 'Powered by React', + Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, + description: ( + <> + Extend or customize your website layout by reusing React. Docusaurus can + be extended while reusing the same header and footer. + + ), + }, +]; + +function Feature({title, Svg, description}: FeatureItem) { + return ( +

+
+ +
+
+ {title} +

{description}

+
+
+ ); +} + +export default function HomepageFeatures(): JSX.Element { + return ( +
+
+
+ {FeatureList.map((props, idx) => ( + + ))} +
+
+
+ ); +} diff --git a/wiki/src/components/HomepageFeatures/styles.module.css b/wiki/src/components/HomepageFeatures/styles.module.css new file mode 100644 index 0000000..b248eb2 --- /dev/null +++ b/wiki/src/components/HomepageFeatures/styles.module.css @@ -0,0 +1,11 @@ +.features { + display: flex; + align-items: center; + padding: 2rem 0; + width: 100%; +} + +.featureSvg { + height: 200px; + width: 200px; +} diff --git a/wiki/src/css/custom.css b/wiki/src/css/custom.css new file mode 100644 index 0000000..8c37777 --- /dev/null +++ b/wiki/src/css/custom.css @@ -0,0 +1,104 @@ +:root { + --ifm-color-primary: #2e8555; + --ifm-color-primary-dark: #29784c; + --ifm-color-primary-darker: #277148; + --ifm-color-primary-darkest: #205d3b; + --ifm-color-primary-light: #33925d; + --ifm-color-primary-lighter: #359962; + --ifm-color-primary-lightest: #3cad6e; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +td:has(svg) { + align-items: center; + justify-content: center; + text-align: center; +} + +code { + --ifm-code-border-radius: 0.5em; +} + +.theme-code-block { + --ifm-global-shadow-lw: rgba(0, 0, 0, 0.03) 0px 0.8px 2px 0px, rgba(0, 0, 0, 0.047) 0px 2.7px 6.7px 0px, + rgba(0, 0, 0, 0.08) 0px 12px 30px 0px; +} + +.theme-code-block-highlighted-line { + border-left: 3px solid rgba(52, 181, 148, 0.8); +} + +.theme-info-highlighted-line { + background-color: #3978ff1c; + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); +} + +.code-block-error-line { + background-color: #ff000020; + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); + border-left: 3px solid #ff000080; +} + +.token.info { + color: var(--ifm-color-info); + font-weight: bold; +} + +.token.warning { + color: var(--ifm-color-warning); + + stroke-width: 1rem; + font-weight: bold; +} + +.token.error { + color: var(--ifm-color-danger); + font-weight: bold; +} + +.token.debug { + color: var(--ifm-color-primary); + font-weight: bold; +} + +.token.verbose { + color: rgb(134, 134, 94) !important; + font-weight: bold; +} + +.language-logs .token.text { + color: var(--ifm-color-content-secondary); +} + +.language-logs .token.seperator { + color: #7e7e7eec !important; +} + +.language-logs .token.brackets { + color: #7e7e7eec !important; +} + +/* .language-logs .token.plain { + color: #7e7e7eec !important; +} */ + +[data-theme="dark"] .theme-code-block { + --ifm-global-shadow-lw: rgba(0, 0, 0, 0.06) 0px 0.8px 2px 0px, rgba(0, 0, 0, 0.1) 0px 2.7px 6.7px 0px, + rgba(0, 0, 0, 0.2) 0px 10px 26px 0px; +} + +[data-theme='dark'] { + --ifm-color-primary: #25c2a0; + --ifm-color-primary-dark: #21af90; + --ifm-color-primary-darker: #1fa588; + --ifm-color-primary-darkest: #1a8870; + --ifm-color-primary-light: #29d5b0; + --ifm-color-primary-lighter: #32d8b4; + --ifm-color-primary-lightest: #4fddbf; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.336); +} diff --git a/wiki/src/pages/index.module.css b/wiki/src/pages/index.module.css new file mode 100644 index 0000000..792888d --- /dev/null +++ b/wiki/src/pages/index.module.css @@ -0,0 +1,41 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} + +.button { + margin: 1rem; +} + +.invisibleButton { + background-color: transparent; +} + +.content { + display: flex; + align-items: center; + justify-content: center; + padding: 2rem 0; + width: 100%; + /* background-image: url('/img/social-card.png'); */ +} + diff --git a/wiki/src/pages/index.tsx b/wiki/src/pages/index.tsx new file mode 100644 index 0000000..6c6b00e --- /dev/null +++ b/wiki/src/pages/index.tsx @@ -0,0 +1,63 @@ +// eslint-disable-next-line prettier/prettier +import React from "react"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import Layout from "@theme/Layout"; + +import { Icon } from "@iconify/react/dist/iconify.js"; +import { Button, Grid, Typography } from "@mui/material"; +import Logo from "@site/static/img/logo.svg"; + +function HomePage() { + const { siteConfig } = useDocusaurusContext(); + + return ( + + + + + {siteConfig.title} + + + + {siteConfig.tagline} + + + + + + + + + + + ); +} + +export default function Home(): JSX.Element { + const { siteConfig } = useDocusaurusContext(); + return ( + + + + ); +} diff --git a/wiki/src/theme/MDXComponents.tsx b/wiki/src/theme/MDXComponents.tsx new file mode 100644 index 0000000..c3c6971 --- /dev/null +++ b/wiki/src/theme/MDXComponents.tsx @@ -0,0 +1,21 @@ +// eslint-disable-next-line prettier/prettier +import React from 'react'; +// Import the original mapper +import { Icon } from "@iconify/react"; // Import the entire Iconify library. +import MDXComponents from "@theme-original/MDXComponents"; + +function Yes() { + return ; +} + +function No() { + return ; +} + +export default { + // Re-use the default mapping + ...MDXComponents, + IIcon: Icon, // Make the iconify Icon component available in MDX as . + Yes: Yes, + No: No, +}; diff --git a/wiki/src/theme/prism-include-languages.ts b/wiki/src/theme/prism-include-languages.ts new file mode 100644 index 0000000..53964bc --- /dev/null +++ b/wiki/src/theme/prism-include-languages.ts @@ -0,0 +1,24 @@ +import siteConfig from "@generated/docusaurus.config"; +import type * as PrismNamespace from "prismjs"; +import type { Optional } from "utility-types"; + +export default function prismIncludeLanguages(PrismObject: typeof PrismNamespace): void { + const { + themeConfig: { prism }, + } = siteConfig; + const { additionalLanguages } = prism as { additionalLanguages: string[] }; + + // Prism components work on the Prism instance on the window, while prism- + // react-renderer uses its own Prism instance. We temporarily mount the + // instance onto window, import components to enhance it, then remove it to + // avoid polluting global namespace. + // You can mutate PrismObject: registering plugins, deleting languages... As + // long as you don't re-assign it + globalThis.Prism = PrismObject; + additionalLanguages.forEach((lang) => { + require(`prismjs/components/prism-${lang}`); + }); + require("./prism-logs"); + + delete (globalThis as Optional).Prism; +} diff --git a/wiki/src/theme/prism-logs.js b/wiki/src/theme/prism-logs.js new file mode 100644 index 0000000..965a962 --- /dev/null +++ b/wiki/src/theme/prism-logs.js @@ -0,0 +1,179 @@ +const levelInside = { + text: { + pattern: /(\[\w+\]: )([^\n]+)/, + lookbehind: true, + }, +}; + +Prism.languages.logs = { + string: { + pattern: /"(?:[^"\\\r\n]|\\.)*"|'(?![st] | \w)(?:[^'\\\r\n]|\\.)*'/, + greedy: true, + }, + + // text: { + // pattern: /(\[VERBOSE|DEBUG|INFO|WARNING|ERROR+\]: )([^\n]+)/, + // lookbehind: true, + // }, + + message: { + pattern: /(\[(VERBOSE|DEBUG|INFO|WARNING|ERROR)\]:\s[^\n]+)/, + inside: { + prefix: { + pattern: /(\[(VERBOSE|DEBUG|INFO|WARNING|ERROR)\]:)/, + inside: { + level: [ + { + pattern: /\b(ERROR)\b/, + alias: "error", + }, + { + pattern: /\b(WARNING)\b/, + alias: "warning", + }, + { + pattern: /\b(INFO)\b/, + alias: "info", + }, + { + pattern: /\b(DEBUG)\b/, + alias: "debug", + }, + { + pattern: /\b(VERBOSE)\b/, + alias: "verbose", + }, + ], + brackets: { + pattern: /(\[|\])/, + greedy: true, + alias: "text", + }, + seperator: { + pattern: /(:)/, + alias: "text", + }, + }, + }, + content: { + pattern: /([^\n]+)/, + inside: { + tag: { + pattern: /([^]+)(->)/, + inside: { + seperator: /(->)/, + }, + }, + text: { + pattern: /([^\n]+)/, + }, + }, + }, + }, + }, + + level: [ + { + pattern: /\b(?:ALERT|CRIT|CRITICAL|EMERG|EMERGENCY|ERR|ERROR|FAILURE|FATAL|SEVERE)\b/, + alias: ["error", "important"], + inside: levelInside, + }, + { + pattern: /\b(?:WARN|WARNING|WRN)\b/, + alias: ["warning", "important"], + inside: levelInside, + }, + { + pattern: /\b(?:DISPLAY|INF|INFO|NOTICE|STATUS)\b/, + alias: ["info", "keyword"], + inside: levelInside, + }, + { + pattern: /\b(?:DBG|DEBUG|FINE)\b/, + alias: ["debug", "keyword"], + inside: levelInside, + }, + { + pattern: /\b(?:FINER|FINEST|TRACE|TRC|VERBOSE|VRB)\b/, + alias: ["trace", "comment", "verbose"], + inside: levelInside, + }, + ], + + property: { + pattern: /((?:^|[\]|])[ \t]*)[a-z_](?:[\w-]|\b\/\b)*(?:[. ]\(?\w(?:[\w-]|\b\/\b)*\)?)*:(?=\s)/im, + lookbehind: true, + }, + + separator: { + pattern: /(^|[^-+])-{3,}|={3,}|\*{3,}|- - /m, + lookbehind: true, + alias: "comment", + }, + + url: /\b(?:file|ftp|https?):\/\/[^\s|,;'"]*[^\s|,;'">.]/, + email: { + pattern: /(^|\s)[-\w+.]+@[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)+(?=\s)/, + lookbehind: true, + alias: "url", + }, + + "ip-address": { + pattern: /\b(?:\d{1,3}(?:\.\d{1,3}){3})\b/, + alias: "constant", + }, + "mac-address": { + pattern: /\b[a-f0-9]{2}(?::[a-f0-9]{2}){5}\b/i, + alias: "constant", + }, + domain: { + pattern: /(^|\s)[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)*\.[a-z][a-z0-9-]+(?=\s)/, + lookbehind: true, + alias: "constant", + }, + + uuid: { + pattern: /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/i, + alias: "constant", + }, + hash: { + pattern: /\b(?:[a-f0-9]{32}){1,2}\b/i, + alias: "constant", + }, + + "file-path": { + pattern: /\b[a-z]:[\\/][^\s|,;:(){}\[\]"']+|(^|[\s:\[\](>|])\.{0,2}\/\w[^\s|,;:(){}\[\]"']*/i, + lookbehind: true, + greedy: true, + alias: "string", + }, + + date: { + pattern: RegExp( + /\b\d{4}[-/]\d{2}[-/]\d{2}(?:T(?=\d{1,2}:)|(?=\s\d{1,2}:))/.source + + "|" + + /\b\d{1,4}[-/ ](?:\d{1,2}|Apr|Aug|Dec|Feb|Jan|Jul|Jun|Mar|May|Nov|Oct|Sep)[-/ ]\d{2,4}T?\b/.source + + "|" + + /\b(?:(?:Fri|Mon|Sat|Sun|Thu|Tue|Wed)(?:\s{1,2}(?:Apr|Aug|Dec|Feb|Jan|Jul|Jun|Mar|May|Nov|Oct|Sep))?|Apr|Aug|Dec|Feb|Jan|Jul|Jun|Mar|May|Nov|Oct|Sep)\s{1,2}\d{1,2}\b/ + .source, + "i", + ), + alias: "number", + }, + time: { + pattern: /\b\d{1,2}:\d{1,2}:\d{1,2}(?:[.,:]\d+)?(?:\s?[+-]\d{2}:?\d{2}|Z)?\b/, + alias: "number", + }, + + boolean: /\b(?:false|null|true)\b/i, + number: { + pattern: /(^|[^.\w])(?:0x[a-f0-9]+|0o[0-7]+|0b[01]+|v?\d[\da-f]*(?:\.\d+)*(?:e[+-]?\d+)?[a-z]{0,3}\b)\b(?!\.\w)/i, + lookbehind: true, + }, + operator: /[;:?<=>~/@!$%&+\-|^(){}*#]/, + punctuation: /[\[\].,]/, + others: { + pattern: /\S+/, + alias: "property", + }, +}; diff --git a/wiki/static/.nojekyll b/wiki/static/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/wiki/static/img/docusaurus.png b/wiki/static/img/docusaurus.png new file mode 100644 index 0000000000000000000000000000000000000000..f458149e3c8f53335f28fbc162ae67f55575c881 GIT binary patch literal 5142 zcma)=cTf{R(}xj7f`AaDml%oxrAm_`5IRVc-jPtHML-0kDIiip57LWD@4bW~(nB|) z34|^sbOZqj<;8ct`Tl-)=Jw`pZtiw=e$UR_Mn2b8rM$y@hlq%XQe90+?|Mf68-Ux_ zzTBiDn~3P%oVt>{f$z+YC7A)8ak`PktoIXDkpXod+*gQW4fxTWh!EyR9`L|fi4YlH z{IyM;2-~t3s~J-KF~r-Z)FWquQCfG*TQy6w*9#k2zUWV-+tCNvjrtl9(o}V>-)N!) ziZgEgV>EG+b(j@ex!dx5@@nGZim*UfFe<+e;(xL|j-Pxg(PCsTL~f^br)4{n5?OU@ z*pjt{4tG{qBcDSa3;yKlopENd6Yth=+h9)*lkjQ0NwgOOP+5Xf?SEh$x6@l@ZoHoYGc5~d2>pO43s3R|*yZw9yX^kEyUV2Zw1%J4o`X!BX>CwJ zI8rh1-NLH^x1LnaPGki_t#4PEz$ad+hO^$MZ2 ziwt&AR}7_yq-9Pfn}k3`k~dKCbOsHjvWjnLsP1{)rzE8ERxayy?~{Qz zHneZ2gWT3P|H)fmp>vA78a{0&2kk3H1j|n59y{z@$?jmk9yptqCO%* zD2!3GHNEgPX=&Ibw?oU1>RSxw3;hhbOV77-BiL%qQb1(4J|k=Y{dani#g>=Mr?Uyd z)1v~ZXO_LT-*RcG%;i|Wy)MvnBrshlQoPxoO*82pKnFSGNKWrb?$S$4x+24tUdpb= zr$c3K25wQNUku5VG@A=`$K7%?N*K+NUJ(%%)m0Vhwis*iokN#atyu(BbK?+J+=H z!kaHkFGk+qz`uVgAc600d#i}WSs|mtlkuwPvFp) z1{Z%nt|NwDEKj1(dhQ}GRvIj4W?ipD76jZI!PGjd&~AXwLK*98QMwN&+dQN1ML(6< z@+{1`=aIc z9Buqm97vy3RML|NsM@A>Nw2=sY_3Ckk|s;tdn>rf-@Ke1m!%F(9(3>V%L?w#O&>yn z(*VIm;%bgezYB;xRq4?rY})aTRm>+RL&*%2-B%m; zLtxLTBS=G!bC$q;FQ|K3{nrj1fUp`43Qs&V!b%rTVfxlDGsIt3}n4p;1%Llj5ePpI^R} zl$Jhx@E}aetLO!;q+JH@hmelqg-f}8U=XnQ+~$9RHGUDOoR*fR{io*)KtYig%OR|08ygwX%UqtW81b@z0*`csGluzh_lBP=ls#1bwW4^BTl)hd|IIfa zhg|*M%$yt@AP{JD8y!7kCtTmu{`YWw7T1}Xlr;YJTU1mOdaAMD172T8Mw#UaJa1>V zQ6CD0wy9NEwUsor-+y)yc|Vv|H^WENyoa^fWWX zwJz@xTHtfdhF5>*T70(VFGX#8DU<^Z4Gez7vn&4E<1=rdNb_pj@0?Qz?}k;I6qz@| zYdWfcA4tmI@bL5JcXuoOWp?ROVe*&o-T!><4Ie9@ypDc!^X&41u(dFc$K$;Tv$c*o zT1#8mGWI8xj|Hq+)#h5JToW#jXJ73cpG-UE^tsRf4gKw>&%Z9A>q8eFGC zG@Iv(?40^HFuC_-%@u`HLx@*ReU5KC9NZ)bkS|ZWVy|_{BOnlK)(Gc+eYiFpMX>!# zG08xle)tntYZ9b!J8|4H&jaV3oO(-iFqB=d}hGKk0 z%j)johTZhTBE|B-xdinS&8MD=XE2ktMUX8z#eaqyU?jL~PXEKv!^) zeJ~h#R{@O93#A4KC`8@k8N$T3H8EV^E2 z+FWxb6opZnX-av5ojt@`l3TvSZtYLQqjps{v;ig5fDo^}{VP=L0|uiRB@4ww$Eh!CC;75L%7|4}xN+E)3K&^qwJizphcnn=#f<&Np$`Ny%S)1*YJ`#@b_n4q zi%3iZw8(I)Dzp0yY}&?<-`CzYM5Rp+@AZg?cn00DGhf=4|dBF8BO~2`M_My>pGtJwNt4OuQm+dkEVP4 z_f*)ZaG6@t4-!}fViGNd%E|2%ylnzr#x@C!CrZSitkHQ}?_;BKAIk|uW4Zv?_npjk z*f)ztC$Cj6O<_{K=dPwO)Z{I=o9z*lp?~wmeTTP^DMP*=<-CS z2FjPA5KC!wh2A)UzD-^v95}^^tT<4DG17#wa^C^Q`@f@=jLL_c3y8@>vXDJd6~KP( zurtqU1^(rnc=f5s($#IxlkpnU=ATr0jW`)TBlF5$sEwHLR_5VPTGiO?rSW9*ND`bYN*OX&?=>!@61{Z4)@E;VI9 zvz%NmR*tl>p-`xSPx$}4YcdRc{_9k)>4Jh&*TSISYu+Y!so!0JaFENVY3l1n*Fe3_ zRyPJ(CaQ-cNP^!3u-X6j&W5|vC1KU!-*8qCcT_rQN^&yqJ{C(T*`(!A=))=n%*-zp_ewRvYQoJBS7b~ zQlpFPqZXKCXUY3RT{%UFB`I-nJcW0M>1^*+v)AxD13~5#kfSkpWys^#*hu)tcd|VW zEbVTi`dbaM&U485c)8QG#2I#E#h)4Dz8zy8CLaq^W#kXdo0LH=ALhK{m_8N@Bj=Um zTmQOO*ID(;Xm}0kk`5nCInvbW9rs0pEw>zlO`ZzIGkB7e1Afs9<0Z(uS2g*BUMhp> z?XdMh^k}k<72>}p`Gxal3y7-QX&L{&Gf6-TKsE35Pv%1 z;bJcxPO+A9rPGsUs=rX(9^vydg2q`rU~otOJ37zb{Z{|)bAS!v3PQ5?l$+LkpGNJq zzXDLcS$vMy|9sIidXq$NE6A-^v@)Gs_x_3wYxF%y*_e{B6FvN-enGst&nq0z8Hl0< z*p6ZXC*su`M{y|Fv(Vih_F|83=)A6ay-v_&ph1Fqqcro{oeu99Y0*FVvRFmbFa@gs zJ*g%Gik{Sb+_zNNf?Qy7PTf@S*dTGt#O%a9WN1KVNj`q$1Qoiwd|y&_v?}bR#>fdP zSlMy2#KzRq4%?ywXh1w;U&=gKH%L~*m-l%D4Cl?*riF2~r*}ic9_{JYMAwcczTE`!Z z^KfriRf|_YcQ4b8NKi?9N7<4;PvvQQ}*4YxemKK3U-7i}ap8{T7=7`e>PN7BG-Ej;Uti2$o=4T#VPb zm1kISgGzj*b?Q^MSiLxj26ypcLY#RmTPp+1>9zDth7O?w9)onA%xqpXoKA-`Jh8cZ zGE(7763S3qHTKNOtXAUA$H;uhGv75UuBkyyD;eZxzIn6;Ye7JpRQ{-6>)ioiXj4Mr zUzfB1KxvI{ZsNj&UA`+|)~n}96q%_xKV~rs?k=#*r*7%Xs^Hm*0~x>VhuOJh<2tcb zKbO9e-w3zbekha5!N@JhQm7;_X+J!|P?WhssrMv5fnQh$v*986uWGGtS}^szWaJ*W z6fLVt?OpPMD+-_(3x8Ra^sX~PT1t5S6bfk@Jb~f-V)jHRul#Hqu;0(+ER7Z(Z4MTR z+iG>bu+BW2SNh|RAGR2-mN5D1sTcb-rLTha*@1@>P~u;|#2N{^AC1hxMQ|(sp3gTa zDO-E8Yn@S7u=a?iZ!&&Qf2KKKk7IT`HjO`U*j1~Df9Uxz$~@otSCK;)lbLSmBuIj% zPl&YEoRwsk$8~Az>>djrdtp`PX z`Pu#IITS7lw07vx>YE<4pQ!&Z^7L?{Uox`CJnGjYLh1XN^tt#zY*0}tA*a=V)rf=&-kLgD|;t1D|ORVY}8 F{0H{b<4^zq literal 0 HcmV?d00001 diff --git a/wiki/static/img/favicon.ico b/wiki/static/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..0b1e07199556e002f07217510bffc8bf37824f1a GIT binary patch literal 175554 zcmeEP1)NpI7k*1EqEeCyE+XCCEhR_^NC-$Ns3@S)0t=`hf&wBIjVLXG0)HfyTyhEN zT)JWDCGY?H=G}Qa@9vBHVhi^E_S=a!dCr+SGk31V5@318k~XacW)4f&WERT=i^Y;9 zi`6~i8H?pH{Bq>5x@RHWSE((QV#RcKZi}Tzki}B1n$?}JhQ+e4ro~dXt{%S`;(uka zv~RD6ACLHlEtcS5J$%XlOOYM{7Cy|sTWO2st-eVt`QS!Y@Ui;Cuvk!zSBqF7+=hQ; z%WkqbKpObH0n7*f08#=X9HUFS!At^o9-uq08n^*yz(t@q;4FT6{KmYd04D*)F=7z> z)cApL7XkVMo6D5hbQjPFxCNxUbZOzg4gMJbS@s#QpO<0l)Y+yrZoETl)M$rRwdxiT z|Ml0mYqe`{(?0p+fY!S8?t3Llgf>><&y#U!1_vL}=FK~=&7OTuYuk3W_W9?BwZH$q zsI6RiMf>;P%i0@nglQ-T^GvFzQ6J`Y#wB|9KB!HabXxoQ=TlnOuKTpbi!X}ueDJ|O zZO)wYTDfu}+!=(;53mm8&niH~@7{gCHg@a@?b~m|wRhh6Pg}U~f=0iuzB;B&nQ~gj zXV^~xNrR7N{DA`xYk&N4PW$b*vs$ZGyHJP!gni<~(^|uZVJcnMB2GFzjodH=zxwt) zq)nZAMw>kOwD#+-r?j7bIwj0se?6@Y7;soCUw*SFC&J$ZBpoR)lL77HkN0b1#)OOV zfA?LuMzAjQ>(%QZ;#=#mV_6=2>mnu%l}J7Z84y5}$S1 zMEbIfj)31H5oRke5GV!&8rncV_{sXI=4tp(2O0q{0J6-Y1uE{su%81Mm-JZ!^aSz& zQeJFv;b)AW0)D>%3jyYp7O)FXxB7&$>yS`?aA6O|Zvv=2`x$g~7IbH#|AApacj&U8 z5n&Af0s@joE2m!etS~zOl()}yKSONi&hq6qI!c#)MrmLe5C)L1r1>U*eUPP0naxfU z&6e$5M`_Y88}JT5xx50XGC=!Xfc=|@Z_I#s%HI_8S=g%p-vS4Khk!9%)jb8jvprc@ zclpq*AOQAPf%k!b0bBnAyPB3G`$>dh-)>h2-OawJ4)8N@40sGUO2eUF>C&OHf9Z~R z#`Jr^Zyj)3O_P0lsZybKkiRoM`5WyWJMPimdTST+2tk_{Rz>xvY$VE__oIW6M3=iz6Pl2w}YGfx7D3x;+XQ! zKbJ&5&v9bfv@=@u>RZJ)aO~I}EhOZswr$&W?e^`5qED?*!Pb9{m+2QPwvhQ`0k*5@ zv;57P?bJT|?4b7Prw4_}afD;pmMsz5`0*#jcu=d>Hf_U(YuXP#oD}rZ(>M$>2O#R8 zn?v;9L>*ZE!Gn)zJ9pmDcI>zz%%w{&fyO(vefw^SzPxzxjatc)p<+CoJNG=tK3RXt z#=C~}OTv9w=E3sUufJXE(BVI=eS0e~{%TdKY|;Mu>!P-H?Nu?xv3^I7-VtLh`7Pta zTnan`$U3myvv0JO|BEkI;Q0T)|6LY5J$UezHetd^t#aip zQa)uK*N|3uC4J`877%UJTK+I0ca%MXbAp;Rw~Dz1`Ov1#ZXuK8d8JA=-pcf8er-tq zCAjwilrwG6pd;G$?bn5jP)-QC!@{hl^dpbPj5%Q}KhysY$etw0Gm=I$M=^btpS9TIZ|#xvj^++ElY!IY>3djw^nM~?$yjPcHJxHJ)Bdy!jvgzMEgKInI_FUz(!zzgMPFN{2wz9*~hpu71=+5xRZc-fS5x$ zNdFc5b`(&{r~#cn*;9 zg;}m#s4Z=2QNq-M{T5)%<0}0A0XhLMgNC*=B@bPVzcLKsrUupkOrLVL3-}5s2dM2{ zFKZMXWLce=N*)|{HUR9aIKJD;D(&ghmv@$o&0n(wS{?%7fW?wjfw{?7Fk%oP3Yb>7 zrK%;uqKSD}4*XUP;5tw|SOB_O?^y$x`yWLQyEzJFh;xBHz&4-(An0Q*Ro9_%<{T1@ z)_VG!XHd2#07n4P-@@d)gJtrm3^KmKObT~?;8TF}5Jz%-9R9fgkMl2CvcI#szJT-^ z0n-7lBaCgy=>8C4(B`AJOGnf$U3!b7d{ZC|u5ShcT<^&Fu`w@4?iC1c>n9xL86`{6 z+EP};Z3WB&E&z_wcjtEl@u~t2c_952ll??_Uv-#NZ;JVIJrCu9er(Ext6fw2Jlb@uPk(q$TsU<@n6(4Tp~`Q{F- zZr$yS%XHfVj`9yRrlYz!$EsIvyB#ITtV0}fE^9s&JB?Ec6rlH8dB#%Jq>jz64R%j5xNhS@BR1pX%{cv)3`RE zo@3dv%i7($kF=XNA8H?cv|pXSGyN|Ck-ww?O6B4``Pz-52yEO^Jwz2O4FNX}|W`R*ma8*7y4L2Vz}Hx#t>8whuK;-QFLj7?Wt~ z;QVw7V9THJS%*=hj%%Ywhuc8?A9bOmEx|P~*X6^99~0~CMvcORzl;1gBOjsHp%Cc# z)8u^RE+ERl`0Qs|w%ipBY?p7pz1s%5WjOMI>o~pdv(-nYtLO0sOjQP%Kg-0ji8!nq z>3H?(eL-8&-7MJtsUvkDf3iH2kq;-Hcv7o0Aa88-r|z42Qm%_V1!>@d2jR%4kTrih z9#A$ZqarT*nRe~|6a6{+bWgzXz(xKXlY$-O&$h`nDriR?Gv%7}^aRw;Q19-7{-p74 znLkaqCD=#ZXW6M^rw++eP!B+vbWnflS&jl+>(zIXKl^C*)gnIY;0+9Y&vm4?9Ow$< z1jM{t&A(*HZLddaBksWr~{GY=lAaNa`wBDZcW&?0|S8q0LMwYJn8oK(H>f=YT=e3E!YzD&|(RSuvpRr14xgG z2??p7kje>~c26)|5+Se?;R=v$0Mm}NSgJ-^0<=g=pvXEO!W0AA12#QHF8}E%kgVy4 zZPLm5H#KNn7oeQa1w=pMFJ7B2po4(Plc%%Ef?Q*weDtH7Q1|cwz<&1{KsjcgRt^yH z93&YlUKJ~D5PNE}9EzD1cGCJ6fbEUr70az+INY{+$4Y_qOw@c8JNuu40Cj`wf!lyu zUZZ_Cey483v|h%SI#MnSvLR`g5oLH2_zgG%7|ZF*eIH?40wUe#pD*Z3@f^mjQe};$ ze*Jl}oT?d!d`kks0Q<#Az*#w6`OiT->a|4L4h!Lhr%aE1gS6`=_i5Sy3xJD&tFoE- z?L5+;PR{4@v#bpoh&@ANnNuPCioi%<58w}7m|C~bk*3Jgo4!=WRZZw0IInyKcn??# z$bL`F*I)K6NdE=EQlY{IQ_{k)PTC^Jn3}*3z+u4MyvrYTxQl!m0&ZnUhB3%Bb>R5` z>MlZnn}9#cPt#!8sS{MrZLtiW0HXYFys_9}JHYQ#0QOm?%gnso!C880JQ;>M!us{Y#QBO5 zBaR8Zk^b8nm}vl~>oWW{T@P!j{5+S&{d}Gkq#no!`cqe}>!xjKa?Q-LbN^rJvzZpp zOi=H=di52J&zUokT8kFDq<)XO(^@P);pl-s`1(Z;GhE>68jF+JG1OOpR#}dEm2^~ z2G1r@cSW5j&wt2=XE_~|oq4icU06=J4pQZa{s6~S)-zgpjeevJb>Tek;|%9MjXEMA)lWDX4 zQSVGy=2=xE=+CoX>iBr zowL0=EIa*Ke)e-`&qj(eIs3=9P5Gw|U&_vqAxA`Cqoyz0HTPh+*T6j|7kbT6h%3rZ zQ$9tD?v#G)XW8GnEI<1d?klWWb5-;+>}yoe|M%a|2|kerJlDjBa&Igf-JLq^5qlJD zztkZ+p+C#C7kCM<<3Z)hYt?yMPgmuazp*GQ%>m?5rRAP(Ivm zl6#yoAA`v`dRsu0KUJz%B?~0|X>z{da^Ax|74E&L`xH5Ls?Gld9dH% zvuDpup|9rt2=_*Lj`6{R#{%3FqdXyhSNIdZbG~D@K33+>EHhl_PXwgIy`#xSm^yJ?|fK(o*5@E7}iWGW9h z?{+wcWBMHX*(UGYc_`$TW2TBbcOGfGcHOXzUwXb`AB^V|+4gVTcqsPkSkIwDkD4vJ ztlJP-ewy-8c)&R{*FQ46oyomn%7l7WQ=ZwR$+NPQA?5t4h)-E!T<$w@--m61eKGw_ z&|NJ<7|JH}(JZrk%9OD?-@^5$8pqDg{3xr=z~3FUZ>A~Z$}+3rT;-|!Mty!$z)pr( z59tS!>;GtTYUas4oqM!PmRu6^U7jiS2YBw1?VtQW-tI6HVUhuo{K8b$kkr4-F{Z=v zn;E}E!}RbU=YkH-ML4Smbz+5#102&hXC+@fC_l&I`HsrZbq;=$=m@(_=SKYo*N|LS z@jQvY!2Nu#7bLBmm~t<77=GtGB9)`^8)WEZggdCFM?N?kyS(*x({|4y|383cfEasW z3i`S$zs`%X2=9(I{{HI(fRqVgI?_j|^-;oChy4cN?=m_{FC6(y1nL9n z0J}2NZCnGZWmfGYy0c3FHz5ubwir| zD633^eZnDN96(V;@RY@~9?BuP?-&>QqzJGvDK#;;?$c6RHzB{>g zTvErr$V1YEJpC2$rrexIaV|0fC=YO4k?9Ik*28freDhWEss}s!1+#UyfUt9cRzOz3 zuFTTyTj|`#mb5{B><=~quF4;Y-?st-f#N_4z^>fvlV5zXq5F*e6rxF!1!_C)gYq~k zKle+f0gZqRfL)pC_O&hgQXQo{TsLt2z&fzsTLXLouZ4#$|>xevukfw9aBPO4cf8cq#a%?O+#qC3QDK1MO<#vvnNhFDE{TLxP! zICmt>5Z$DKSEa0vG=p@v(d20;KGNi=C_YA0KTRuM=i=`;B^B(*gkK2#@q~!~*0WNy zhU;!tgOAY^^?<+8#Mv$JNK@1s;t&ZX|_(DgnNW^-v>k+hz%L2 zR&BMQHRmU?eKUW6a!6jVJpThC08i@TZCK_-ddKKmis?H6`(XA%KLV6T^2FP^coUCw zrmXpW9N;+ubxz7Wba3v)`3J{fjzjE=y(zoD;*92c9AyyjwI7t}804F2X9OApoPTl- z=CAVmnhyJz?10xY(6HfOc(;F@jfPB1Mnmnz0QOCS`vn`4uf0N-^_jr!qx`H0SAGHfY)V; zt+=c=?>6PRR=%@sINQN_HP;rVWB}n-`C4wt2eYP`{M5A6@bu@IF5V}>{c)aMGrYIX zH3ipIqW-VFw!&pMfNx_O zM(OcP)z=u7Wib1&>^zgAo`>MxKJP8z9mDe6x-mV*<9UAhyR19UjX616M16{=KTT(k z9;PzPYk*hv=UG^u*W|q;uE2X>PM^MOcOHagZ{B>TxC2G4Gtd2=KYvf0=~Vq`=NX&% z^UsSjb582cdTa!!Pjk5@;_m?0PFzEIRezpcX#io@^_eB0k76=Y|A_+W(Jgd z*;modyRCUG`4$^Rx zuALwIbn=5|VBLY|lhpG>vu2$Wb>ctTdG1uwM=cBGoc9>XhcaV4i>rp$?cp%<08Z;K z=l%#o-38b0c6Br3=DnP3t32=J4(!7y+vFX`vdx>V?_uy=3s>hn8J=x{cf0W6xM1R3 z-(!^jV?eCoc~6A#DNUU@!s_RY%3h^c=r<@*2~p<4&*=k1Jaof>B#wk zBUwQmR337Eml|-oE>>iKdK~I9)c9`gzx;Aa++W3eq}+jb^zt5E@>6{ehi#g796M{% z^rzf#T;Rj`frD}1QCV-GJ~dc>g1Q{zV>n|@eU77aoceJL=J{uyKXeE3jAvb$2YEMR z##vDx{^Pd-I5#x%RJu7X$cJ+z!#kZ$%ZI$iVIIgep3{Cn{sxmeEsyj%-uC~D$9I!> z#+47pfsrGRi++v#=I=DwCvsfi*vN;n!uyP!$qLGEqy^V@IRLlyM_Zs?kGd^m8cyAu zm-1d{u0z~`@7Qp?AbCnz`18-G`6KV4;=4nu~PeJ@MYAC;~^b^*ez^n)1?j(R?08V=pw^#8K{%tO+E>BzRA z)|qy`Kg4wq=gJIkwrol`>U7EjPTPP|e});T#C4e;*PpyEo@;S;;JZzZ#yQrBZGrs( z*;=P`nD|=aYS^g2KKHHHHNczC!89P%tPtIdF2ABcgGjTONBa+H6sJmc~kFeOe31xlm4Ic9@fPST!m$xX3Ay=LtSnw zK&%NJ%>}40Qe=c--RghYCb_2Pdm6C?&Y|Qy!ca$dbRkd4Tc+ebbZ|v8-b@RShev8VB`m-+V+nv^* z{i6IGW(C0IegNle9KZPulGp&p2F{t}T@WarOa3_cont%4ct=Bk@GD+COwxdJ2JVSC z&4c|p`|H>Q+dk*TuFB=&H_q*NM%ZcnxmH%%0q2fR_eMPJ|IO%$+=Wr+PcG`|iat{j zFPT#U;0Mx2M-G@=LpV&2^K`z8&Tpv12ACK1VRCNZtXyvVPvG~WChO0&<2YyO@!khM z)XT;O_)akOA6#>L+5eG`)O8MXRe!^ph&lx75~9gK0_^`~9rn7ezg-)k4$0wOA@3mJ zccc9AzPgz-_>MgH98BteWL>36onSaX-Eb2R>d(G_x$-jG^5gv3GjvnjJFVI2V~dZlM!`R#u;CW8YA(QcYRXobue3hzQfNpGZZKd zFusk?w6p(?$v)g41YtS(j+b8ccVN1Ew}%1d!Tz0(G;hZbs2HoIisv!UQ{5(4@KvZ^0fIH0e!~Tq7d}TTS5&E(`B` zh+Y>M1K7Uj1Fcwmzb694b@*^>E>R-tU2CNsrhvU9Fap>B6aqvWb(qi-<|*ea4#r;2 z)_2YW2GVl$s2XHqR zR%!G-+N03TCd4+@pur*=O$;)_b^EJ8S6~_7?Ykw^-M<0|nM^1GWWCGBT4t7A0rfbw zfeFB2;1Qt8gQs@Rx5c?mnDLrMd?(o;Ba$xE=TWcs2@nF@1U#jKtMLCIy=Q@VNgoH} zv7`&nr|^u%RNy4ws*b+=b_Hoy1Vp~^p^Z^ic%P9hlVVcOPksOAz-HhM;7i@j#{F8( z72fn7jM>FQNF zIJ4hJ{%-?9cOBDXz1q)~FCW#8^tnb3l%o@{7`O~LD|2l7&qG<*z6Bp+q93YU+2P$D z%r7-i9T*E7064D3cKzMucOGTp`qi)FSl6!OZSBS|79~Yqd4P|A6~J}CT^Zy0_d%=! z<=ux50>L@b;qHdnHG18)Vahu-XCO1frx^3#X z`vBCfQ1@-7Jn=2eU6i{C;IaHLjyf*W4N$kjJ&&2d86dvZ*PHT8M?J(IyeH!r;z)Us zx)tt$In%9pQ?6K#Bj43A@bwhj+yn5ajUjvvfV!1Gfr~(_*T-LZ@=Pwzr+@Ov0dZ%C zgLid4LtbL8XjX<0p6j^yI4*m{C(?%R3w-xoxcEL8zp?4yJ&v`gYdX@1F!LZB+mo;Q z1W^~3(aifCzu%7iYO8ZTKFneE$0Df_S%rVRTSOP!|wmeTo#B+>!`k zivY&~nTA&;%gXPh@$MzF;CCnaJymD#YcWlN_XqL)$1lG;D&&J^*RK17Kk3W&y(u>; zZLVFruLTDmar7?8PiR|7NF$Eh?jD3=pFY`F`cNjm{We^(&a}yUf%yKUlm%H1zVFF< z9{6ofzVpwz^ZY*_nsoD>Q~u8Hcd4}Doiu|7A92R#qsSu{V5*Jj;Tpp9N#{WNkcXZ= zth*_kXguk#MJl2*w6ACck077$a{5ohYjDYqd92MVbQ+SaJ+wjeVMVX zI;a=*{#60DZA^xNSq$(=hsAQSZFmB;E|fvOqfR-H&!$Zg;*KA-U#2VbpquxyY}sPH z$A;lAUc4vngD^8DqORZaER~cGXKjr0B%Maw$DR$Sa_EuWoA(vfv5WQMop18tym!u)WwgkM=_pwa;4!0-ovGRRXervW` zHS4!#d4~(zh( zNNyP3`|;}*-q*5@@1#>$SkyPpCr>`@Ru$b0De?%FS563;GqxNeq>T?OdmC@_%Onihtzfq!xD+kkK z{W1C2wd-DSrw#87FazHI!8s-0cV&Gz59T|7^4YTGy4~21a@p~Xad_vB+DBXOPqGhZ zjAw8UWB*Bi+6*hcwIzMLoXUM0RWOn(_hHR;d$ zl;qr*@wm2e7G903*u!AY0=T4)q#?rr9RZKm^rQ{@X-|Q?MExm){8l>eDw7ZAklniN z6Th?GOk38UcYAO?DxdK1J7UadIx z8&l}RvomA#xW=>`y2;bw!;gu(rFb8e8SuO8yx)TN@sPgEk0$#R-a{(enWPiHLC^cJ z8xYL@pl zN?I6A@`3XJV;U&Ckp}ME{U{&Y|8ezxlspfK^q&W~zvV7n@jL0mzLmT+d)E!`tKq#@ zj_O7laXwDH&!R;aHTEr(9roFz8T%dH2glzTPRgIz@;V5&5q>WKF8k?u^O~yr8Ql=x z)IJx>$NSvaXPO23U9PuSKL_O%e(aC=JJ<9bI_wej=+NOm;if--cNW(}f9_qq0f;sh z7?{;rHzdb-nt6a@fT=Q&MwBB@V77itTaH~c{U9%n>NE*;<^HhCeu%&8VAx*(M`=a# zlXYPE;}T}e>mXb>{PF^#{>}tQ8OIood&+M2O-UQd{f|GMj5F{aV(RErodC)njgKz; z*q3|^*w*aMXv8o&xbMCmaG8&{Kh) z^x3t`XZmnX^O|07XW}FLWf+(|qi`B(<6 z)mnoDQs~2T9KX4u4}W93=UgT(LEVq4&vsX4C%+$re-6N<{225?O%a}JIcGE%V=mW* z?5pDfGH+L9H2E9X=A8hS^fAZ~&%A7Nl|JQ%YpJ*d+m;{Xhcd7jc+MSxl=TMN+Yo2; zVgJ*=f86&!T&Mb>{~>*-Tdd)ZJ_Z>og*Xn+z{HpF-4ElJ+J8(kL!SZ#_Q<}PXQ&nc zY8t{GU+Ck9`H!p{=Zf3S&_}tGfOKjLaBoDWBTVc3d5`#(2IsMHfuDc&dH&40aBua0 zKvy828TuI7ST@Al1K81rZqg_&*Im}UqnFE3Sq*;V_g-K$P!)I%5N*a&`V=m_oAJH@ zqR}S-`mqn@9@slT_L3!|_POL5)GU1rGE^DqT?G;%jW~x31BLmu_JZlu6X+*sY^`?D+ zB0vg2&_TV+g?|2eWco030*8V4MjwvL$AO7JeSrEIn|w&SyS1mc^pbiH^j|#V_yZ7M z=tI54O5kH4FXV%|PhD1QXLwxd-o2%X8c+7?dfv5Q^2}^p(TM9vuC>PjHGtHBA}iK2 z1uS!HK1vzVz#am`Hhr!j&%c4rKn{TWnSw6L7!sQ#vCE5PQOeO1?%1FY-<8}2i~uSC zsQ{a-P)69N#FzW19kPtzTQb~{cPX><~4OamGN839`!N_&p$ zs+-PVDL>DbZw9=f568c?z^6a~fbwXg3+-%Ev2l;A>57{SXsE~MaGRwM=iNtuAAveR zTEIpVIk)v@4P>(Du@+3JS8>?S0j_AI>Q-JwSk5s8T{!+o(C_cY*M*66_ zl`8n%rdwe=t`pgQ_zvuo_^{tpXw(9A<~)Tox&SNy+5y>>^Rf8WV$`=~0|H!rYUYU` znKCB<9mM|i1elcpyEz=(f|fj|mQWsX9v~!uDiDjX)6ng>V$o&~;Wdl8KMZL{5L~Kh z^$%Cz{i=LGh>}57S&EomQFXJ)pBHKy7G=sqg~$dNq=W{jX&y-ojq9k+W06uLdwTD~nEWf7PS$AnC4aNPSIv;hrkO$pvl{ZmgUABcC_qZ~ysBn;ChvZ9t z1QB*t7(r}yScM(`#6_bF4?BZM|G_qUu=Ordgy9B8dmsd`-9w5?NfYWlq^O3^kL)Me zuPS{j*E7@;a9+|4SO>HLY-@F&Gk(ew;2g#}_l;UtlfJ<70OvlVfZc#R2QmwGvG(K~ zA@T8?0-OsN&e@3hsIEWF4f?(hECa3r#TtQY<%-she&Ze?^>>1&iEV)N z*KD+qbWzNdu$Ke|0-FHR&kywmw<`Gl^ibSln|rhF>ReqvKS5ntMPLN56Oi*pPwDF}Jo~MlfS^CkC;5?d z<~)XVRrfZ~4^U^D6X4z|_gHxb${qdu@%w7zlMZ-d+kn)Ca*UJpR7~!r*967^2LS4g z{Xti=X=U!Ou zg#3&e)d%kqQx9M->!nKzH}@kO026^@z#||g=;>*iT(9KJne+&viP>DEoIqzs`NLvcNE4J8&29l`gRr{|d@VU8$&Fks`a|6$`3Y4>69R zqMYdKsap>M+5>+A7lGKKnZNV-2JM*j5p|7g2Cy6w205pHYM?4G8rTEK{dIrSBsSCI z9s&2lMZM#K{>_`u!5FkrfaPF6Bg+Gmb2RGKKLDKR)?<@i{?6+j>eUtyb*@!wd91R4 zv{uJamP40&sayXEeun|h7yMoK_>$gy)a@C-!Z}?`Kg`Do_|67(>z@Ih>ek~6Exjqn zdDOQIAm|bk>oLl-BVDg9`%&Jam|zWd~_hx7F}-dHO86jkn1 zB0uWZ2LYRbJ3xG*M{Jj6E9##G5H#|I{!GKzr_)dG*R#P+-8#?d`&+jj+cfiMew4pv zfS{eVzwnL=Ov32H@ZM^Y_HvybjvIO{7&15cK!vT_?nS z8K5rGY59HqjeRKZhT?Z$d;z});-WvcD?e$)yK`7}-h0Gv@$mZ^HEV7YclT4yNpD#< zx*gG;Jh*V-p4Ows0UoWFbey!6s(^6m>IJzJUl;YT{K&b%L;_t1HJ z{~hDbnPct_DbkXB?%DHzHe<$F@$H3u`)-MEv@m~u3*r0kPl!9Gd3PB3r1m*d?rBo? z`}A?z|BzNkfV_Yh2l&kdPaeht$^kK=7bg9Af4A&U)w+3V=bgjqH*rvAJ6T~~q-UQ# zhs53ZckbYVY8MZ`^YQ1O7sNM}4jr=g_iAtxv}gX@Bkcy*_V>J?e=5ZP3$Uw?Kirc3 z2Mx|(r&NPF_&8c>7uCp|sU$uW+O95D9*lBa$#NgK-S zxN#@6*|X1S{Pu=7m^0^`_RTlPjoH&Yw6Q4Hcinli9ib}F6GyAXZ#LKg9c&v#?4NjP``ed-TI64A3OGh zN;>h)A$})VuDwtfm$Fp8{3g*>)I>NhW!qr-?&2GM=N!H~An57IIIQdeF zVR*_cWpUlQYeJX8Z&i8&>S2~Hy=3>T8S<5L9`)fmi)&qDTX9w&@`-C(b*;c}X!83} zW_f5x`%A9D;3r^e5I`X6F7!A&!|<~qO^38K6NYr)c;{$+qteZco!@X%`-RGtw}7wq zeZQG+1FGewjJIg9%dQXN9M+5Pbx9h9A^jHtkLaHx$8kx2n$#&#wv7C>ZEj#JYZ|-u=FCWsMb6qd`ALbhgv;@Q$;K^M(9J3h@piXryV7ea8 z!p0Q+nIGv)daDn=1F3#j%UQXkKl>Q!-PHLj=TH33vzPr3X*LV}Irq#xng=nwg5I$E zOn;`q?;P?wy!;LqzkBEn7?*k-Rkq1nuBp_A-?-)Xl+4nOGR`qvT{rXlXxxACQvOM^ zvp{h`(BEtuV0Z=GTRRE(g$Jw)Y2piv^k7=t8!>(tj(Sq^iTrU@ex}E7YjMn0p92SO zY5c~syZEls#%}`v8$HdA!%7_PEpw0AWgX)3chZM+;rb-0r)QY7kxUvg-u=E(W6n{Kb7&w3+f5Y?y;Gm z%VdN}4hVXh?Sqtg5aR`#$j2!^NFT0;!oqF{y*%d`-hev&HEXWg&HrV&DBo?{?iTx7 zl9sB;v6btqn>Qb7j&%JD%P?#Yp3I$O{w~bp_^kjS=+Cp`W}botZQmtfywU*AoI0hk ztKUd}uD|>-|2M9`)O?u_zgf@yMNc2DcNZ+U06Fn_%r(-8dYqnspuZ<~Datr7dDfa| zu8nD%a{H71uJ*rJKITOo6TdZN)X6#H3BQNRwU)ZB_O`B0;;n*zIzWs8X3wlMe5Fcj z1m9riI|p8!LnKWoSKL46x`yrF8!#@vS?rEZ)Om6bnBQdQeh=r8*RI_c-?rsEmEQ#C zc?R;5d+_{DH0tJbp2XjL#C6244G3CN&t~?KabRW#`0kBYWg$I2_+Xz{KlSc?Q1b>{ zdvQ(V>YKJ|`8XzU9Oao4ehasI_XA?Bz;EbM-y{2ZcRFe{O&{#zL3iraaDT`ev*Z`; zg>f(*2f!TZL;lg`fZnXbNK;SC!1iaHf6`5VPt)=t{6WNh6%cK}>^UvITcFH^DkJ_C zAIcD$^^I?N@qH}u{x;>`leK`dFTiu@UY`{;%Ahy$ADeMvpnZ^bq@id7W;-F$zjp0q zavUZP$xDyqi+W9ne}C*h#sr<6r5Qu?=NgJ@De)Z_v*R$sDf1w% z<+!FZO@Hcts5`iEIpnDk(b~R z^`EU;?GpP^9Xk96Gya3?Hna8fFdTJh)Twzi29Q@W4ovFwjsvF4$i6fo!OwFaBb|at zPfv6aYy%4Ysne!z+n8>m+Z;`}r^3AzlGXIX@Jc__2=3c}DVkIEV{`rFYhE!d|J+mL z-lA#RGoZZNit&Jq0QWfE(x2~NaX)ta_!C0sNWEix2X%Ha%!BEm9Y62k(WA&edB8n> zm-J7Ze>$bl3DB;jN5n^9#8FWkZk}~<$^%LN#PwG+8gc&km8bM)ctt12GhVaI&_8kg z6^;Is*?r#7zeI`cY8&8LN1l0f*aj&7d^d}G=ci8H)lQs97#KSANKEJ-NTbI9`<|&l z3vcMpIEX93v%Wh3hxDgE&x!M$o<@y!Bp7gi%vGJd`0WPbtO0mmSRwQw;#`Wi^k*ML z)UN$M^5ILsWqH{S5*pmq$;9u})gK0a1YQTyg9cJ=VVd6yHu8!4_()HpJnR<%mppii ze!q&kE(6{Nasy)T7bezER+{nMm@;L2yUUyD>EJt0e*sT3{rT?nUSKp(4Y0kB4ZENd z=kA2R9;U14h4}6t-vNBucyIxA{u5{q1ffs1?XOtBgJpdWgMGEXzoFE!Rg1Z z`HOb`NQeDD%cvtS%%ebT(ahI;IA=Qmj0I`}Y3*g*S})d-{_*uu%1oL08Ss@ZF&+OB z%E-G;I|DgUe$F3+3`u$7IZfIV!o#x5a>HI9@XPz#NXMUi;Q5bTzzCosz;&Z+x5CVt z^{oD#uY^E#`!Xu@=lk310DscXm$bM?F$Z`X$fmSao6JZ*`x+%I7j+t}ht7xIs4I1? zzR=B=xZIoG3=9NH0x1DS)~#a}%gQo8DUVXeBCwwVe4(MIaiwm38uD!dWK!CsrE+E4 z9V3DdPYTV|dRX;(LN}cP^`8+-^q0EzPmy0C$TRa6G?x8J$&%LZ)Od48s#?GJZYTW- zz5dN$@~nlYa%?8N)U8iI`gMWyfXr8Xr%t-52YZ?xDRZcQ7GNu2hMs1_Tt#{gb?a(h zWA+`NCy_65-mL4VhWLU0)UEFUq;CCr*ln_|+C6#4_DQ5Y>!ivdXj29_515s2H5_&8 z3xIckm-TPy+33!8MjkW2ELq-pQpxF6y+AKXr)OZF52$o?WjE^98DFL)OxeGARj{Wd zlAH(Wv}*^GYfo2nKaJmK0&f9Xix-bNZ!O!Cd>6`M8TXV>(YI=Xj#6&3!_IeajP$3D zLh9Cw!X8bx4nL8GKfkl(TdfjKY}rqMhTIb!36TEOHy#0g0p0*!kn#0nN_r~b-WbnI4+6M0P7dh(xm`H_6(9kmq`!X_ZW(NQ6D>H({?KBnD*eM1d$7e4 zr28X?&5j^8JAz0%gILm7!-p&OVA=zPzX+n+Bj{~OD*QvD?2m=j>TeBV31Ap&5MkGY z2)iBxV}_=MTcZlQw4#!cirp3j{x)w^-n~6Y36sWzJx~eb%$`&UquK)${{Su6Ryfse zkrd&t&g_H3ZE-ECy{h70)kZ>aQng3X%@U;8)2MbULq#Tms$H@OzXU4wq^e!1q*{5^ zZeQVGk&pPN5XEWbwQwc8GrLk@O|>hPR0PPPDV20;kE&##7G+PP*deU4Y-||P&c+k0 zI|fJDMH|umMf(b|hG7t$^VVh*F8r-c&}y&BAl8bBR;1glt{hN)*Vt_{z@uL6+R2P6=-lUFHH z+!OmBZ0E{8h}21PkD@lfvo1UDK3U+^Z-7^aIub*8yj|HS0eUX^8g=m`9>sGWG=l z^w;NccI!1M2h=TR16lyT0VjY*fLZ>!3wIJ}@%)s?k1~+>#0~}6kCWb3nro8Z(&Sx^ zoSzQ`wgBv_-SN_!-ziJ|xc*}~N|o9gJC%QGbI}Bi+0RPd3+OL-E_E~=;K%hj*J$4G z)YCW|OELqZ9Gqh&KK`Wu=W~1?n>03_lZ0Pdpaw7+*abuap7PL_@HdcOBfxg9&A+vO zI#VlBWS8huxo&gN*112K7x(~J0$c)o;i0c_xsI@%E3I31>C?$HA8QR73ZCc8c|i8* zHdB{@30ZYk)s^ z=Fc>!Kj^{vpR9{#6nOeV%QJAK8E9t*oYCdFEi2Frm;xLFc&6N+Jo9&2|Dt@e6Vk2$t8*=Yh$otdyzK5Lu&{X$WNfSWbTVDjXqrLUm;8RTH!9C;m*#236noq++ zUF^7VAIWxYXOae>3Fk$g?5)QXe_|tD$~Dgo3I4MUJgE=sCePB8E*)(iFZb4afEL_a zzY4?#{o^_h_Gui~p2)SJoXfF(dfT?O_d#VE^Bjb~ z_tyQ%kJwI&Yne8rnWSMtngis`d%#w1{SIlhtv`>t$-Q-+fs3iV_1NZ_zw?_7-aiZa z2-@-eg82OKdvjc`s^_L;*b}nd+V{uFMsDn9p)gcjRQzaPrhv()BQy5+|l<}DW^KPx1JC95Lg0S0{l&zrzO2m z(C$S*(6(sNoiWW?r|DA$3E97^-#XCG#ml|*A5q@;w6~s+Wrh1!P04?~KXuBVnEIho zrFC}wx|BuTlzZ#F;9d>H$G!E0%zu`BD#lgPS@0n?&W7+l66V9b7b$nlUkBH1?31{+ zJ{33)#P_}Rge(K3Z&5(-g8Yc7hj~co@449A@aI~jEHDV*xRj9g))O-S*|t8DdtouL zFO2kUe72v%Z%Tr9TZ8a>TVOVjkoVRTvJ9*S?K!^^eBw9i{P~nD8MXJK_xHxV^}EPB zA=58jmYv^Bl)G{z{_Z7>$n%;tw`pCv z?A7=UVG}aIbrsjvmg2?3{Mr1;d%3s14|aF&ttax_OP+(af_CKfYp-q9X3RLNUA%Zt z8$0%dR=KiU8Q_|ldKKHAxxa(}Y0i~pOEhD)&r^9H8Tm-u-gM)}Lo+gPAH4aH{lA=} z`H}zakhVYGXHM)JT=Wep@9*8S@?Ho4{z)0AQe}%P8ZHH&s8bj7K!5ECA-!zC2EbL` zvGN;f6jShL{T!9iRr;=YFJ&Mi;(_+*rw1`7bjk{zYhL zg!b8I2i?&&THR$k=UlyO*L~W!aVNCD|Gp^7w|niuaP{^T8vY zqY`TYUj=~a=m>(zvxhRDSTo}b|H*rfgjJ5vh;4apQqU{PZNSkGz+>8HWC! z^LBA2!~(3wh8@+e zUw6%W_U#PA{^9J|NX!fFYxnQFnHcB-^61fHWv=H@pD+0?P2Nkzb-S1c3>-Mr7ZI@O zl#m|ZJ>ok^GM`v8t5@HuwP~|ktOK|f@F&`~-Ho}NbzbhMZj`@Ho%U!aPu_Lfl-W0N z9>{)#dixeFc4=?DwM)dK+;9y**>&}7-+okb{dtpx`k(Q4J&Ci)PLSH^O3AE$fw{bD`n zY@M)Y&rPjSBl16bIUJSEjo)who$tT0kyfFA$AZPof|BNZr8An~vum zJ9pmD+PDADrk8X^11Y~;_feKO=P*7TJ2<~^mWGG^d}oI5O^G=G*Mz=2JXgT9kPi2P zd5^Wf${BCdA%$cHIySxnQ%S(?`N6LVvLBYKlp9LGFXG5KVv+}y~ zXS&_HA86DOPdSJPWe7&NJtMoX2Hf_37YuBh?Y*K7-&JMYyF9JnRs;GBp16YR$a4?f~h|4&{xdZtf5t8qs zk23Wu;57}*#wDHOLjTXb+-1w6&;8^W?JNH|_E1M;e7JAOy<C@`|`+sgmVd`*$?1aGsa|qV`ayVd$b)pZfFM&-WKyf&ISDe zrnhh3EiunG(wpw_<4-!=*Z=FU3t~UW7{@FfsNykGE+%DTBB_62FN# zoIm)_v;gXusB4Nb{xfavy-`Qcaglwazv1X?CEF-beW^o~P5 z@r=GV?UZ%keu1O)49^j9TwtH)s7yZiiTfiF-!^{x(g!dd>s(Nz*8*L_w=~t=RC&I!?R@63B?fa$s3;C zr~-&FfbG|phigivp`Q^S>TlYs>5(QJk7EkXXik6X;+*vX^K^F2qr z;JcgyahI34Ka%%3`SNfcSh%q5-p3k9`;r;Hnhit#TlN1A4$XN=d?(=@>Hl4ok8=gK zTb}jh+JHJDM|wh;9oKd|N3>+gC9PMlgF?UWYQEtrZ$JIE5$R+F#2An--+o_2Kpg}4 z4*C*5l~Kqp>D0RQZt-p<-X{kG)4cpiPdzQ${gG_H9K(Hikfx9$-TV+H@1$_l_ju*UckbBU zVhUWh`%+%YDEle$m1%Lmf}ov#{4JjFU9IO7@IEDZCfD-b%7A*l0O|2A8s15x=H;`U zbc`v)R9XFyJx z?~jz<0zx{xhh`A)7;wsCSHC6l-#fawqN$VLM&Vp=QtE&pv^ISBF^%`#u-@L%%*%M(yXPLh=)bF1U*+vIP<>C7 zY4NPVY#_GllbD}pH0RkJp5d{L-(Cvb*+0x{1nf2f27X>fCQAafLHfNavsdP6lcynE6&&R zjQx{}`SZ_MVcs7( z&Q0ESvY5#KIN?9<4I1e${ww!}aSY&HBv;JJz|+S6IN1NQYi|l)_W6td{BAhXmEc`O zypzaTzIOgR^TT%|`JOG`q2yWmCl!2mkaxhw^8UX{Z{Fo|0^pq9Wud<%!YzBa!~oCSTlV=U(gA0QX#|cenApY+36VU#HG8!GB-A4dacx7{&n3HM!n+ z+IZye`tp1o&sfa{+5$lU_grm!C*5T~|JrLSykVVR;&4w;_BkjY*BM-E`kNk4OM16J zyN$pgfamOZ*2>278Z}nh?4)_JWY7DBhrTAlvMBvPOO*MEygw54iU~R7y6reH1>pJm z7tyA~em(4HTh{kDxR&$vZWmwq>@0r&{$HwnKsJ6}7NDIBUY#+AwYGwO(MAL-khdSEo2YUyAG>C6}iOKSC-F6nB z>~{oS0eFv|po^T#Nq4bgI}#d;U6z;cn8>=p%n9rUVv^qRC2g*EIOiP-aO`^yu+c*4 z7lmI!n9sRnw2L2=x>D}h_r(_;`MVtI-a5}$W&>Ys>o(GX^C8aVs3R>{aE}YBJvl#7 z?yFQ;BW0iC9_K#(rhQzd$2~6Yb5Pf9+gpcS)LD^#pYPvDs8XTOfbXC$1>%xl{>YnW zTX?>Kd)y6y%(ZK8kTPzY_g1R3R`?}UzWJ-%vhUO7fNLJEd;P(O*iPdL%Do)m-g-eG z1t56Lxtz4qWFMdSSSi5yjY1o)cd7G;ZQgmCAKz!N+gn%aVr%O)YyK<7_e7pMrhvRN z0<@#9<43?-e#BNhxwrl<%9haAGx>A zcUi^Wx{=TD*Y7{zeVUqG9TOeSDUd(^K6MPp2s*BgC;X?5<`lra^)^6I`SPJjV2bh@ z<}Q}pxeqz7Wa2L_DNwxlb}>d4FCIqP_5!%qX|`?pI~?yVlY8r>VSg5|$!N)vVWO;T z{{-bA@$roUhCLzfaUKW!%~x0HQQnRLQvmL*X9ZuQ>1epm#{J90$G;R%_k=)q?r%>8 zT=C0azeOOQRluh}w7qq8jE}EpD*VfdxJym;rQiem+GYUzVSn*iO@}%LyS;V8I#l%a z)vK@3`}V}STx>{%1~P*$5--B;)BTYSWakq6xVQcRkQaIxyS;Vz+14SHhr}oLDL@|R zeBjtS2;dxCZM&Y@?;^h3Tdxj#T4SFMKige3v0vlF990UC7YfS2&a=&)@|@x2-g*bv zUjb};>zuE{EkId_%QMkx-4pHB_rw(baNWhVw^{z*Mp)iqGz_Q!U~fH&*Yf;~oM$AY zGjmUqY=CcKT}>09-i3X*GZ~P3>oX9h1&~c$x4|vid6g;~u*bU9(y7zLr-_savaWnT zN%9S55WshujQr=``dXkbPy%zgXOwmFZuyt0fyfLRB2+IXl^@s!0!h4V58eW(5lhg!FtiGMs$LP*!}J)0o@bSo?y`l zX#cyX1oWAp?j<?9IBlSEy0YaoIv1Qo#*cMyXs1hYDA1l5Dv2v$}9Jw#7lcgo*o za7`yzko;YD54LyP1`nNJQG=D0fHJgB(5T>6f<*IkC-|GII*I?tzik@vtp|9ah;Zz3&N11u?1z-aTytoP{Z{z=1T0XwGm z`32tq&hvWB>dpEdy0Wt0_%>(y{rO>ipjD%+5WtM_lX}UNks!aNZ$pt5tYVen*xC$N$cMzDMB+ue@44u<^)lAAelC z(vH3xALfqOADQM+mCs-4oA$tq_5Nt|`)jW>OV(uOyEo5HUALs=jg6^7`aQfjdB9J1 z?i?O*v1a?q3&U4@cgs?7NS%Ivv>1~lZSzW?EJCgUu`lJw4CeN{{CkT z8~zmBWn1Nt9YgM?iJX;Wc<|_u7u(N0wS0Kn(Calb?(f<4;`#7x2mUH_a9Q#5TNkxF zmbsv1Sl8|!hdq8V>7XQ^zY_Xqp5V$Mr$YKSIr_}{y;&OP&X{`f=?$4b>hyNK)B_r& z?l{KMW?0pIQzoB#B}2K?e<%Gg?ZHBmm+mOJF?r*3c_vrdeCNYI&-^#HMc}~yW%?## z@S1L|mW^pvZq%ve$CEt{EtclT6zu{gHyhh)#EJ~B=UV>Xw6v3pTmD|MG;rYN2?at^ zRr~6rXETjSH9X*#n!O75cr75!;1mav%u71C#n}BddrfU&dF#1CYuXP@J+)c6a!0RS z`Q~E!@Ht6>1{GSEKC(;r{^|F3gv<|Fb|ElL&NP>D}>QroUokjyIkDfHC%&DCv3e9O}$x!ufkhVrE z+y3*N#V6HCb>N#Roo|g8dHKz;FQ4j{Wk=G5uO;0&W_JGo@UC{P8q@D*4}Yn8=%?u# zS`J?ykbKAR-51L4o;Ie=d-?zRch%%y%XC{fxLN(MW{*~mOBbAV`tp~Tl{nw`ll2=K zmFSo-Lu03$BoLg^q=I}XUu$V)&~Ju#@~OCJG@S{T<3rKDy00wqhF_) zv+2JDr&gq|_ea|%*$>P)vf|zPJBzojH-1jW;Od>U3J?F%LWh0({!hz7-j4kDh5Z4) zzF4thBYf%kiLJ~rk=|BN~OSUSzlo02g!3Req6Oxt(TLZ4b0vsUET1!Su2lR{oAto%^vK@5>aXQ ziDKWB{dnH7m!{X7y=C>?shd|H4;YkUPm1hK({1jbsoREY8CT?+^PqC4N~ikGN?H1P zxh|oj{>nPMd9}UIgp}Mmp~(y1y*j6Kfg4q?*P7b;^;3DXeq?z$-QMhzi%&Y(FUi8K zU;oe$;a(_veA}!AMVfVs`XySGratw8r^(s)FV0?FIo4H|E0{)*+-)~zjTr{Av}-e}mj zf21lOTCrj69bfLg&|>$r#xE{Bvp4DQ1(M|`ne3kG> z7kAp&a`3v~S$zZ0FKj>7X7Cs9{G2z#XK!Q*xm)N!z`Vf8Va=K~eDC{Fqs|?iI5cPD zT}gHxJ2G*5r$1Ya)hr*UsgP&ugHKYfZm}>$*FK}mpPbeI6eC__tvLQ={ej7S2 zbLf!X8Cxa&` z7Yoif?BT4s0h^XT4u5;#qwe8Xr*>MDAw!zJN&BW={qowk_V*0?V)y&m_Sb6m(YPkx zHv7#|Y0#zlqpI{to$>v2djo^>Gr{7^BPu`pa=_%?ZTfuI<&Ao^x>f!n8?!2IkLvS#qD2RSi9NMZ!cb~aOmKHSqIxyZ&0aWmrgV0e_d?E$QOdU zZ3xQv^O)Ip`?TFzyw%8t*^Xbnl`g#O#+$wSZp;;Ox9qJ^e>JR~wLn8lnRzX%x9whZ zdjB*LpH8iE{-;7iKKZH7#8G7`E*KEfD_hZj1E(!m`s3BFzM69-W3%y=Ztecg_wSXm zDIR8tT#3q!e=a{dv+t6onY$_Vj6-vCPOVoV!<;Q^^JVO{a#*tP7a#t;J1Z)c|MiCB z+BVG4uX?3x&+qst;MrRr6d2Xk{ImJ#2O+7Z z=Fgb=zo2iL9Nu5{K%GS$XaDqa$kczdJP&J*eQD^oo8NqE;=1FLmNjfPCH>wOl{yuu zvUyg=WYvbue>U^Utcz1cCSR2nL)FO>12V11G3UeJk1jMm|HY~0xu!R|)B*na8TH9%#RY?B0&5%pw-d)|lak?Z6 z`&@0aeBjn=1tYe$+McRHp8B<>g;Z}}@^Qo`GkP9fy0UTI26+zmcsRRhwkf4%U#|3Q zff|-}EmveYmHGF`PT|9wg`fU?X6L$=0m)u&I=0S+UVY{i?`b*JukXgR_5RrUUeOu{ zpAGqa!i0HeS_~Um$#Mjp(u6rD@;$EdMd^@dr+wD{oeCLlgaqY8**|!2zh3L-wmfcd z@aWEJ8|y5{I{4A?j`=hFXqg-QU`T0Haj+$*`Pka~dydHUeXdv2p?brJax>h_|H!G*z&3aP72n)Udli0crQmPLjJUJhImey!n= zmWTKEnfK?Cw@yqd@OtAF^VThzlNVaHT`s9 zo|l6n3Z3uPt@GudOTM~jV#_5-#^k?WTp!TB+wi7kTx7%AjV#~I-Bc#@X8%f^((ZUQ zW9rOD7EdjdJjbcKX$G~p*d_An>P+=>_e^yl#k}gL`(0mA7UNly>u4WuR z$?{x*JFSLk5rd1My-Y}#YxFx=&XoT=?~M7I>z?jbYHXI44YP%P_1mHsf-`3>nx|>T zvlSk8{^os>E5p|fAMQCdJot~cq5byuJX&f@ueDnaU;g{@TLC3D1SMPc%!7!x=X_JU zeffy*LjKIY|54V*H}0;Vux;4!eTRN&aj|Es+m^|#mW(>Is)`uH9^d$S!<*Z0q4SyF zV(cI34!*MB*Jd}v{(V$q< zvyUJ2_L^J~lSWNWHYjPgUfJ_rT~;LgL8d}mMpQePQV!P@ABe3+rk$cuwA_FOZi+;hpZw_ULQ z{)3*`14DatPgbSWxN~zJMGXJB@6y8g+PweS$H%t){QOHHQ|ipglqaB1fqBW=H5uC_ zqH^k`wO{yp!J@Rm+rP;)ZF8>ahi2sr>hi^aBEM|jyrfyC=8yY4pY&#ls;i&vR=;-6 z@5X;=8C8D3gp!>?r{|pi^Ro+E7J9AAbE|qCo4Dww3l&QCE)HmH^$3Eos z`)LNRoHZ!hmM(kOcFf;lT;!e3D{~)BdZ6s5d49g~-Tr`QG3Iofo%Wbz@|Wq4KX>cI z(qlQZrz#)WN&C8bXs5rLrTi}Ij*8FaJ~lH`^R=`0bk5kS`JS682A-IZZq4Ji0mr+Z z?zz9`?$A7qinQgBGHcW5kass!T6%8zvg>_!HfWze$H{ViH|J{Br$pM2`jd;lZK-lS zeAvwVmXYs#)x6dRwQhH+Hm_^m%+o&oFHgIw{Y#yHZ()Y?>2^<=v~1_(|GZ86 zNvD<{om@O+?n=obMy=_4tkTr;U+x{3x8ay_y$hYsvoOPp>DK?5yUF~^fs@}F8}ME5 zxD3JDw{QQVY5r3c!nTKupB~tL)X~)4X4jnDBYT(Q;UjD2&Tp|SI5jHi)#oat{$^&4 z^Ol!;wJDo_*xBm!u9jZfZ&$UkQ)Y%toOsdyfJCSu*mu=a?XIKdq82m?_UcEYmEv{KG ze?Z-uGir`|Jvd|JzgnS8TO<0d>3Ot8_Wjvs1&x{6nKQ$TO>$@by3~mQlUiKqIDf;N z)%pkby3lym>JRtK3Mjd=Q0`YPox&z>f4n@)vI6J(7MhUiM8@#sP2NSXaqZre+>4*< z`|+)=!6|!G+?kx&Z`hHelLkQ5M+lx~pj5_qJ$loV+g zx|E?yI;A@YhWGM+zs-j`zkANvXYak%UhBr-iak+bBKg8^6fw#YHiMh~M^QjL$l1mOW~i_8pu(QoK) z#1(2TUj4_7rqcIj6W^bg7d$&To^*k%LVp#OgKk!15T-z7fPWsr(I9m>iz!8u4mzJC z{B+)eWgr+M`<5%!!;@17oSyn8gXeY?j**+!LXDvK;&|hyr0HzH1?gLl+oMaN(U(BW zLU%IufTG$1qI>y$M?mpDeT54&XS8Ta81s|kYukULxzMe#iMm4*b_a+n#L8EWnvHaY z!AJb}jn81@fo(uJd>(A08oSqCQp+5Pow5yhy(Dc9hsRb!^%}#Z@q2 znPN#=e^^OAzO+cz$h`j_%+x2yz)<;+&lxY@f=i_*-R{>IzRr<|FqCWf^zj~^?__r9 zx`IXiPRj8UCw_oBlV~R4UVT$vFV=n?ZvI^G>&=Rd*O0&#ffj9Rm%COJ2MF)eiG;=d zy`^s9&leq>Nb4G1vMjjwx>qC+JFkv=`w>&FT@HAa)W!4hyk{IP=uTFN)Pojfx+YjJ z%W>Wn$ZuZs=3jv3GcpnzmgRK|viUqfu`mbb=pya6dyR*-GtLIJ&Xy*oT!+u3F(6Ge zjWy}p^#&a2U*I}TmB<{8u`p1+*zCo&Y_C{VulDLsuuu5yWWGb^a??2$%zrdFbgQVzM}#V(*}d!EIf(E5uvBX`fK4@qeL6l- zGACt@26vO5Yt@GJbSMocSoHs>j1KAUDOSy^DGKci#V_kPRqnFvH~EPT>^R&@9Ly z*F&xnPW=2tX(FM%-0tVvc22xKKmX6?KxkZ2(!F%$jP>~YiA1W@+3)J7g867pW_O-6 zh|k8B4q#SDO;8x@ZA(A-Fwz9#O!JYaBa?49mCwBwFF(x~I8RK`*0QoZ|3l;5?GdZ4 zERXRvJMt1buaL?#ldgl^@=LnT0)UCz_q&C+WxvWt%Y`;VlY_*gW?rTe^`Awke(Sk@ zQ$gW@Jm@J_ryZLJrJ}YqY);XdF;Ur0eUWL<_U&-7<-YBHYKB^*2-*?JoV)|;{&#Cb z$p@bGyuU!bPuO)?IkoteU=?yK!Aw~8hSG;W9^ zv71hi@T#3>#q%f~*m7m>+4VUL!Y92S2qhv41i1d??FeT*$0;9!-km$Z#NKpS_VJzo zV?fWVMRdzc2Ap{6ewL0apUHP#EDHXY0^XO0FP28x42;cwl)86^a-uedB5v>yHjrV9%qWhahXp;q)(Rvq-zD$F0UXzwliEz1(XbP|Mbz0)+ljdTAw^iw7GQ zZu#93wD0=)&u#}0i=emQ#9>>S7Ct%I%f9_r_-}ZNa|Nzfi&=~B$LJHqK8KB5 zUY;V6e!O_!e;n=X4D=rhkmGTH)VH=srbOWi(NkiWu#jv?9}%GEVbKmISZL6QzibsW zd!x$SRfzCUEiO_Cr%m#v8(i<-k@8L7h$Law$m%-Sqc+g~eMl1V&INa@Ovm|SxIQbC z-x;dYac4!W5H}j|PqT>m2`xtU?vDz~(h(_OE10=ezfupwu;ks`et?R}Yl85Umops4 zk$u#!!}*x8w5`H#FLkWWlUP*mHrT?2{^lI+=KE}`i8C&IoKik`9dS9D2d+fsx4q$KYD^b{z z5#=AO1rl+?Bh|Bir)M}=+?BuSDORI4r1A6HM?i?9JU40tvu)@VgpR+?aBEB zrle=*Ey>Jx!`_gI5&)>8CHe$?g9@iur7N=c6e4`XoEsMS3v0aY;NYhZ8*DVlnSi3J zSmC9%qAMB4)foCf3iNXSBl9Z9$dp{dnHT!MJc!`2q%FFzN~Nl1Cg!k1U~Rm5x)0jFXmzco8lkt>L&e)Fxt;l*_) z{Pj*6Wn7VT#5(WgRt9h;nO7c&`udt9@#PcxpJ)y<5KE_)W|7-yQ>SYb zQfYg~m#L5U^4H%8)l7rRvaWELo2+2ss4t%Xmh9`e+x=Rr!h76;P5AG%`uHLSPrAoI z3hphpeP#d?sf14$l1{wd5>oZfirdl1j(zi~7+~m1m4DiyF^57N{uu07r+uMVG293#C^r-WH z0?#`C5fZ7SCY~}1!iCwj9!pVm0^&%hv=_tBwFnDtv}Xb zT?GY(VY}^@4uwA3BdzT^QjT=i6o*Z)t;VQ3ET=thABA(d?j$)amO3G4QKz?K-)usN zEQdT~Beypj=%qt$D=LTf4rc3Y2p7fOuiu9E%7?h>liOr_2KVh%4$pn5-WpelR83zg z!A|p6hr2`Ouo4D7?+BQNae)s0{AuSa{FoKBfSVHAYLcMJvA==vtE6#A@nD3y9?f+p z<~-0ev>?|`Du_RR`fYcrAsG+kS|K6}|EHh#)#Ci$7Z}; zU&U?BvPv&Y2O``b%qh^GsWI2?x)Nx5s}prI@H@~DoNZ&%_9ZwWk)QoD?E1Di1-)HI z`Zcm%sUfl@{kG73HwixUo2tB9+)}|ZPK4W^774%t}CLBOH zn`R8R)DTgF@5uyBLOn+)4UAWM-_2fN%0o)>z$KO3+f~eQG>nTAB-h7^fhgJV<5L4D zemvbl2}xQdJcnqi{|)oS