diff --git a/README.md b/README.md index fb4f93dca..bbbe49fba 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,27 @@ import '@patternfly/chatbot/dist/css/main.css'; If you are using React 17, ChatBot currently has a dependency on [react-markdown](https://github.com/remarkjs/react-markdown) that relies on React 18 and 19. There is an older version of react-markdown (8.0.7) that supports 17, but it does not have support for 19. You should be able to add `"react"` and `"react-dom"` of the appropriate version to the `overrides` section of your `package.json` file if you need to use ChatBot with 17. +### Tree-shaking + +Import each component from its dynamic entry point to keep bundle size minimal: + +```tsx +import ChatbotToggle from '@patternfly/chatbot/dist/dynamic/ChatbotToggle'; +``` + +Named imports from the root barrel also tree-shake with modern bundlers that respect the package `sideEffects` field. + +`CodeModal`, `PreviewAttachment`, `AttachmentEdit`, and `tracking` are not exported from the root barrel — import them from `dist/dynamic/` instead. See `packages/module/patternfly-docs/content/extensions/chatbot/tree-shaking.md` for migration details. + +To verify tree-shaking in this repo: + +```bash +npm run build -w @patternfly/chatbot +npm run analyze:tree-shaking +``` + +See `packages/tree-shaking-demo/README.md` for full results and best practices. + ## Contribution guide ### AI-assisted development guidelines diff --git a/config/setupTests.js b/config/setupTests.js index 0b274b258..d648f0976 100644 --- a/config/setupTests.js +++ b/config/setupTests.js @@ -2,6 +2,9 @@ import 'whatwg-fetch'; import 'babel-polyfill'; import '@testing-library/jest-dom'; +beforeAll(async () => { + await import('../packages/module/src/MarkdownContent/MarkdownRenderer'); +}); global.SVGPathElement = function () {}; diff --git a/jest.config.js b/jest.config.js index 7cc261832..1272b04d6 100644 --- a/jest.config.js +++ b/jest.config.js @@ -30,7 +30,8 @@ module.exports = { modulePathIgnorePatterns: [ '/packages/*.*/dist/*.*', '/packages/*.*/public/*.*', - '/packages/*.*/.cache/*.*' + '/packages/*.*/.cache/*.*', + '/packages/tree-shaking-demo/*.*' ], moduleNameMapper: { '\\.(css|scss)$': 'identity-obj-proxy', diff --git a/package-lock.json b/package-lock.json index 52342b947..8ae85e1a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2161,890 +2161,1332 @@ "tslib": "^2.4.0" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "dev": true, - "license": "MIT", - "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.10.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "dev": true, - "license": "MIT", - "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/argparse": { - "version": "2.0.1", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@eslint/js": { - "version": "8.57.0", + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@img/colour": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", - "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { "node": ">=18" } }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" + "node": ">=18" } }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" + "node": ">=18" } }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", "cpu": [ "arm64" ], "dev": true, - "license": "LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ - "darwin" + "freebsd" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=18" } }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", "cpu": [ "x64" ], "dev": true, - "license": "LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ - "darwin" + "freebsd" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=18" } }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", "cpu": [ "arm" ], "dev": true, - "license": "LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "linux" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=18" } }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", "cpu": [ "arm64" ], "dev": true, - "license": "LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "linux" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=18" } }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", "cpu": [ - "ppc64" + "ia32" ], "dev": true, - "license": "LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "linux" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=18" } }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", "cpu": [ - "riscv64" + "loong64" ], "dev": true, - "license": "LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "linux" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=18" } }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", "cpu": [ - "s390x" + "mips64el" ], "dev": true, - "license": "LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "linux" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=18" } }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", "cpu": [ - "arm64" + "ppc64" ], "dev": true, - "license": "LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "linux" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=18" } }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", "cpu": [ - "x64" + "riscv64" ], "dev": true, - "license": "LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "linux" ], - "funding": { - "url": "https://opencollective.com/libvips" + "engines": { + "node": ">=18" } }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", "cpu": [ - "arm" + "s390x" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" + "node": ">=18" } }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", "cpu": [ - "arm64" + "x64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" + "node": ">=18" } }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", "cpu": [ - "ppc64" + "arm64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "linux" + "netbsd" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" + "node": ">=18" } }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", "cpu": [ - "riscv64" + "x64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "linux" + "netbsd" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" + "node": ">=18" } }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "cpu": [ - "s390x" + "arm64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "linux" + "openbsd" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" + "node": ">=18" } }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "linux" + "openbsd" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" + "node": ">=18" } }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "linux" + "openharmony" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + "node": ">=18" } }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", "optional": true, "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", - "cpu": [ - "wasm32" + "sunos" ], - "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.7.0" - }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "node": ">=18" } }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", "cpu": [ "arm64" ], "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "node": ">=18" } }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", "cpu": [ "ia32" ], "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "node": ">=18" } }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", "cpu": [ "x64" ], "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later", + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" + "node": ">=18" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", "dev": true, "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", "dev": true, "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "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" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } + "license": "Python-2.0" }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" + "type-fest": "^0.20.2" }, "engines": { "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/console/node_modules/ansi-styles": { - "version": "4.3.0", + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" + "argparse": "^2.0.1" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/console/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==", + "node_modules/@eslint/js": { + "version": "8.57.0", "dev": true, "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@jest/console/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/@hapi/hoek": { + "version": "9.3.0", "dev": true, - "license": "MIT" + "license": "BSD-3-Clause" }, - "node_modules/@jest/console/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==", + "node_modules/@hapi/topo": { + "version": "5.1.0", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "^9.0.0" } }, - "node_modules/@jest/console/node_modules/supports-color": { - "version": "7.2.0", + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "has-flag": "^4.0.0" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { - "node": ">=8" + "node": ">=10.10.0" } }, - "node_modules/@jest/core": { - "version": "29.7.0", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, + "license": "Apache-2.0", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "node": ">=12.22" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@jest/core/node_modules/ansi-escapes": { - "version": "4.3.2", + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", "dev": true, "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@jest/core/node_modules/ansi-styles": { - "version": "4.3.0", + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" } }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "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/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "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/@jest/console/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, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/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, + "license": "MIT" + }, + "node_modules/@jest/console/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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-escapes": { + "version": "4.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "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/@jest/core/node_modules/color-convert": { @@ -3662,16 +4104,241 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", "dev": true, - "license": "MIT", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/buffers": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", + "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/codegen": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", + "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-core": { + "version": "4.57.7", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.7.tgz", + "integrity": "sha512-GDKuYHjP7vAI1kjBo73V+STKr9XIMZknW/xirpRW/EcShX0IKSev/ALafeRfC8Q331nodrXUFu04PugPB0MAhw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.7", + "@jsonjoy.com/fs-node-utils": "4.57.7", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-fsa": { + "version": "4.57.7", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.7.tgz", + "integrity": "sha512-1rWsah2nZtRbNeP+c61QcfGfVrJXBmBD0Hm7Akvv4C9MKEasXnbiOS//iH3T3HwUSSBATGrfSp0Xi8nlNhATeQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.7", + "@jsonjoy.com/fs-node-builtins": "4.57.7", + "@jsonjoy.com/fs-node-utils": "4.57.7", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node": { + "version": "4.57.7", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.7.tgz", + "integrity": "sha512-xhnyeyEVTiIOibFvda/5n89nChMLCPKHHM2WQ+GGDf6+U/IrQBW3Qx6x+Uq1bkDbxBkybLOdIGoBtVBrE8Nngg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-core": "4.57.7", + "@jsonjoy.com/fs-node-builtins": "4.57.7", + "@jsonjoy.com/fs-node-utils": "4.57.7", + "@jsonjoy.com/fs-print": "4.57.7", + "@jsonjoy.com/fs-snapshot": "4.57.7", + "glob-to-regex.js": "^1.0.0", + "thingies": "^2.5.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-builtins": { + "version": "4.57.7", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.7.tgz", + "integrity": "sha512-LWqfY1m+uAosjwM1RrKhMkUnP9jcq1RUczHsNO779ovm1E9v8I/pmj04eBAcoBjhC7ltcPbNFGyRJ5JqSJ7Jdg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-to-fsa": { + "version": "4.57.7", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.7.tgz", + "integrity": "sha512-9T0zC9LKcAWXDoTLRdLMoJ0seOvJ5bgDKq1tSBoQAFQpPDstQUeV1Oe7PLypdu7F2D3ddRstmwgeNUEN/VaZ4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-fsa": "4.57.7", + "@jsonjoy.com/fs-node-builtins": "4.57.7", + "@jsonjoy.com/fs-node-utils": "4.57.7" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-node-utils": { + "version": "4.57.7", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.7.tgz", + "integrity": "sha512-jjWSDOsfcog2cZnUCwX5AHmlIq6b6wx5Pz/2LAcNjJ62Rajwg89Fy7ubN+lDHew0/1reLDa9Z5urybYadhh37g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-builtins": "4.57.7" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-print": { + "version": "4.57.7", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.7.tgz", + "integrity": "sha512-mFM4P4Gjq0QQHkLnXzPYPEMFrAoe6a5Myedgb6+CmL+nGd3MKvTxYPuD7N1dLIH9RBy1fLdzxd80qvuK8xrx3Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/fs-node-utils": "4.57.7", + "tree-dump": "^1.1.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/fs-snapshot": { + "version": "4.57.7", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.7.tgz", + "integrity": "sha512-1GS3+plfm2giB3PqokiqyydyqYTPLcCQIKSkp0TdMNRh3KVk7rqRM6U785FLlVRG7XLmkc0KWr215OY+22K3QA==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@jsonjoy.com/buffers": "^17.65.0", + "@jsonjoy.com/fs-node-utils": "4.57.7", + "@jsonjoy.com/json-pack": "^17.65.0", + "@jsonjoy.com/util": "^17.65.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", + "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3685,10 +4352,10 @@ "tslib": "2" } }, - "node_modules/@jsonjoy.com/buffers": { + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", - "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", + "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3702,12 +4369,22 @@ "tslib": "2" } }, - "node_modules/@jsonjoy.com/codegen": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", - "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", + "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "17.67.0", + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0", + "@jsonjoy.com/json-pointer": "17.67.0", + "@jsonjoy.com/util": "17.67.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" + }, "engines": { "node": ">=10.0" }, @@ -3719,16 +4396,14 @@ "tslib": "2" } }, - "node_modules/@jsonjoy.com/fs-core": { - "version": "4.57.7", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.7.tgz", - "integrity": "sha512-GDKuYHjP7vAI1kjBo73V+STKr9XIMZknW/xirpRW/EcShX0IKSev/ALafeRfC8Q331nodrXUFu04PugPB0MAhw==", + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", + "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.57.7", - "@jsonjoy.com/fs-node-utils": "4.57.7", - "thingies": "^2.5.0" + "@jsonjoy.com/util": "17.67.0" }, "engines": { "node": ">=10.0" @@ -3741,17 +4416,15 @@ "tslib": "2" } }, - "node_modules/@jsonjoy.com/fs-fsa": { - "version": "4.57.7", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.7.tgz", - "integrity": "sha512-1rWsah2nZtRbNeP+c61QcfGfVrJXBmBD0Hm7Akvv4C9MKEasXnbiOS//iH3T3HwUSSBATGrfSp0Xi8nlNhATeQ==", + "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { + "version": "17.67.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", + "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.57.7", - "@jsonjoy.com/fs-node-builtins": "4.57.7", - "@jsonjoy.com/fs-node-utils": "4.57.7", - "thingies": "^2.5.0" + "@jsonjoy.com/buffers": "17.67.0", + "@jsonjoy.com/codegen": "17.67.0" }, "engines": { "node": ">=10.0" @@ -3764,20 +4437,21 @@ "tslib": "2" } }, - "node_modules/@jsonjoy.com/fs-node": { - "version": "4.57.7", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.7.tgz", - "integrity": "sha512-xhnyeyEVTiIOibFvda/5n89nChMLCPKHHM2WQ+GGDf6+U/IrQBW3Qx6x+Uq1bkDbxBkybLOdIGoBtVBrE8Nngg==", + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", + "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.57.7", - "@jsonjoy.com/fs-node-builtins": "4.57.7", - "@jsonjoy.com/fs-node-utils": "4.57.7", - "@jsonjoy.com/fs-print": "4.57.7", - "@jsonjoy.com/fs-snapshot": "4.57.7", - "glob-to-regex.js": "^1.0.0", - "thingies": "^2.5.0" + "@jsonjoy.com/base64": "^1.1.2", + "@jsonjoy.com/buffers": "^1.2.0", + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/json-pointer": "^1.0.2", + "@jsonjoy.com/util": "^1.9.0", + "hyperdyperid": "^1.2.0", + "thingies": "^2.5.0", + "tree-dump": "^1.1.0" }, "engines": { "node": ">=10.0" @@ -3790,10 +4464,10 @@ "tslib": "2" } }, - "node_modules/@jsonjoy.com/fs-node-builtins": { - "version": "4.57.7", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.7.tgz", - "integrity": "sha512-LWqfY1m+uAosjwM1RrKhMkUnP9jcq1RUczHsNO779ovm1E9v8I/pmj04eBAcoBjhC7ltcPbNFGyRJ5JqSJ7Jdg==", + "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3807,17 +4481,54 @@ "tslib": "2" } }, - "node_modules/@jsonjoy.com/fs-node-to-fsa": { - "version": "4.57.7", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.7.tgz", - "integrity": "sha512-9T0zC9LKcAWXDoTLRdLMoJ0seOvJ5bgDKq1tSBoQAFQpPDstQUeV1Oe7PLypdu7F2D3ddRstmwgeNUEN/VaZ4Q==", + "node_modules/@jsonjoy.com/json-pointer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", + "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-fsa": "4.57.7", - "@jsonjoy.com/fs-node-builtins": "4.57.7", - "@jsonjoy.com/fs-node-utils": "4.57.7" + "@jsonjoy.com/codegen": "^1.0.0", + "@jsonjoy.com/util": "^1.9.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", + "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/buffers": "^1.0.0", + "@jsonjoy.com/codegen": "^1.0.0" + }, + "engines": { + "node": ">=10.0" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", + "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.0" }, @@ -3829,1330 +4540,1474 @@ "tslib": "2" } }, - "node_modules/@jsonjoy.com/fs-node-utils": { - "version": "4.57.7", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.7.tgz", - "integrity": "sha512-jjWSDOsfcog2cZnUCwX5AHmlIq6b6wx5Pz/2LAcNjJ62Rajwg89Fy7ubN+lDHew0/1reLDa9Z5urybYadhh37g==", - "dev": true, - "license": "Apache-2.0", + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@lukeed/csprng": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@lukeed/uuid": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "@lukeed/csprng": "^1.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@mdx-js/util": { + "version": "1.6.22", + "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", + "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@module-federation/error-codes": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz", + "integrity": "sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@module-federation/runtime": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.22.0.tgz", + "integrity": "sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.22.0", + "@module-federation/runtime-core": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@module-federation/runtime-core": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.22.0.tgz", + "integrity": "sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.22.0.tgz", + "integrity": "sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.22.0", + "@module-federation/webpack-bundler-runtime": "0.22.0" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.22.0.tgz", + "integrity": "sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.22.0.tgz", + "integrity": "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.22.0", + "@module-federation/sdk": "0.22.0" + } + }, + "node_modules/@monaco-editor/loader": { + "version": "1.5.0", + "license": "MIT", + "dependencies": { + "state-local": "^1.0.6" + } + }, + "node_modules/@monaco-editor/react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", + "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "license": "MIT", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.57.7" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "@monaco-editor/loader": "^1.5.0" }, "peerDependencies": { - "tslib": "2" + "monaco-editor": ">= 0.25.0 < 1", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/@jsonjoy.com/fs-print": { - "version": "4.57.7", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.7.tgz", - "integrity": "sha512-mFM4P4Gjq0QQHkLnXzPYPEMFrAoe6a5Myedgb6+CmL+nGd3MKvTxYPuD7N1dLIH9RBy1fLdzxd80qvuK8xrx3Q==", + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-node-utils": "4.57.7", - "tree-dump": "^1.1.0" - }, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": "^22.20 || ^24.12 || >=25" } }, - "node_modules/@jsonjoy.com/fs-snapshot": { - "version": "4.57.7", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.7.tgz", - "integrity": "sha512-1GS3+plfm2giB3PqokiqyydyqYTPLcCQIKSkp0TdMNRh3KVk7rqRM6U785FLlVRG7XLmkc0KWr215OY+22K3QA==", + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz", + "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, "dependencies": { - "@jsonjoy.com/buffers": "^17.65.0", - "@jsonjoy.com/fs-node-utils": "4.57.7", - "@jsonjoy.com/json-pack": "^17.65.0", - "@jsonjoy.com/util": "^17.65.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@tybys/wasm-util": "^0.10.1" } }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", - "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": ">=10.0" + "node": ">= 16" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, - "peerDependencies": { - "tslib": "2" + "engines": { + "node": ">= 8" } }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/codegen": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", - "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 8" } }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pack": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", - "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@jsonjoy.com/base64": "17.67.0", - "@jsonjoy.com/buffers": "17.67.0", - "@jsonjoy.com/codegen": "17.67.0", - "@jsonjoy.com/json-pointer": "17.67.0", - "@jsonjoy.com/util": "17.67.0", - "hyperdyperid": "^1.2.0", - "thingies": "^2.5.0", - "tree-dump": "^1.1.0" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 8" } }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/json-pointer": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", - "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", + "node_modules/@octokit/auth-token": { + "version": "2.5.0", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@jsonjoy.com/util": "17.67.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "@octokit/types": "^6.0.3" } }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/util": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", - "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", + "node_modules/@octokit/core": { + "version": "3.6.0", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@jsonjoy.com/buffers": "17.67.0", - "@jsonjoy.com/codegen": "17.67.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.3", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" } }, - "node_modules/@jsonjoy.com/json-pack": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", - "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", + "node_modules/@octokit/endpoint": { + "version": "6.0.12", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@jsonjoy.com/base64": "^1.1.2", - "@jsonjoy.com/buffers": "^1.2.0", - "@jsonjoy.com/codegen": "^1.0.0", - "@jsonjoy.com/json-pointer": "^1.0.2", - "@jsonjoy.com/util": "^1.9.0", - "hyperdyperid": "^1.2.0", - "thingies": "^2.5.0", - "tree-dump": "^1.1.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" } }, - "node_modules/@jsonjoy.com/json-pack/node_modules/@jsonjoy.com/buffers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "node_modules/@octokit/endpoint/node_modules/is-plain-object": { + "version": "5.0.0", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">=0.10.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" } }, - "node_modules/@jsonjoy.com/json-pointer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", - "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", + "node_modules/@octokit/openapi-types": { + "version": "12.11.0", "dev": true, - "license": "Apache-2.0", + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.21.3", + "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/codegen": "^1.0.0", - "@jsonjoy.com/util": "^1.9.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "@octokit/types": "^6.40.0" }, "peerDependencies": { - "tslib": "2" + "@octokit/core": ">=2" } }, - "node_modules/@jsonjoy.com/util": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", - "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/buffers": "^1.0.0", - "@jsonjoy.com/codegen": "^1.0.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, + "license": "MIT", "peerDependencies": { - "tslib": "2" + "@octokit/core": ">=3" } }, - "node_modules/@jsonjoy.com/util/node_modules/@jsonjoy.com/buffers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.16.2", "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "license": "MIT", + "dependencies": { + "@octokit/types": "^6.39.0", + "deprecation": "^2.3.1" }, "peerDependencies": { - "tslib": "2" + "@octokit/core": ">=3" } }, - "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/@octokit/request": { + "version": "5.6.3", "dev": true, - "license": "MIT" - }, - "node_modules/@lukeed/csprng": { - "version": "1.1.0", "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.7", + "universal-user-agent": "^6.0.0" } }, - "node_modules/@lukeed/uuid": { - "version": "2.0.1", + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "dev": true, "license": "MIT", "dependencies": { - "@lukeed/csprng": "^1.1.0" - }, - "engines": { - "node": ">=8" + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" } }, - "node_modules/@mdx-js/util": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", - "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", + "node_modules/@octokit/request/node_modules/is-plain-object": { + "version": "5.0.0", "dev": true, "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@module-federation/error-codes": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.22.0.tgz", - "integrity": "sha512-xF9SjnEy7vTdx+xekjPCV5cIHOGCkdn3pIxo9vU7gEZMIw0SvAEdsy6Uh17xaCpm8V0FWvR0SZoK9Ik6jGOaug==", - "dev": true, - "license": "MIT" - }, - "node_modules/@module-federation/runtime": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.22.0.tgz", - "integrity": "sha512-38g5iPju2tPC3KHMPxRKmy4k4onNp6ypFPS1eKGsNLUkXgHsPMBFqAjDw96iEcjri91BrahG4XcdyKi97xZzlA==", + "node_modules/@octokit/rest": { + "version": "18.12.0", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/error-codes": "0.22.0", - "@module-federation/runtime-core": "0.22.0", - "@module-federation/sdk": "0.22.0" + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" } }, - "node_modules/@module-federation/runtime-core": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.22.0.tgz", - "integrity": "sha512-GR1TcD6/s7zqItfhC87zAp30PqzvceoeDGYTgF3Vx2TXvsfDrhP6Qw9T4vudDQL3uJRne6t7CzdT29YyVxlgIA==", + "node_modules/@octokit/types": { + "version": "6.41.0", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/error-codes": "0.22.0", - "@module-federation/sdk": "0.22.0" + "@octokit/openapi-types": "^12.11.0" } }, - "node_modules/@module-federation/runtime-tools": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.22.0.tgz", - "integrity": "sha512-4ScUJ/aUfEernb+4PbLdhM/c60VHl698Gn1gY21m9vyC1Ucn69fPCA1y2EwcCB7IItseRMoNhdcWQnzt/OPCNA==", + "node_modules/@patternfly/ast-helpers": { + "version": "1.26.2", + "resolved": "https://registry.npmjs.org/@patternfly/ast-helpers/-/ast-helpers-1.26.2.tgz", + "integrity": "sha512-oN8pYX2Ekep0m6uFbTe4j+YjQhubWqDR0Yoj4jJSKp3gnbi+SknOEzvzMMqjCi1bWODjfmaerKBxN2WaW7c7dA==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/runtime": "0.22.0", - "@module-federation/webpack-bundler-runtime": "0.22.0" + "acorn": "^8.4.1", + "acorn-class-fields": "^1.0.0", + "acorn-jsx": "^5.3.2", + "acorn-static-class-features": "^1.0.0", + "astring": "^1.7.5" } }, - "node_modules/@module-federation/sdk": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.22.0.tgz", - "integrity": "sha512-x4aFNBKn2KVQRuNVC5A7SnrSCSqyfIWmm1DvubjbO9iKFe7ith5niw8dqSFBekYBg2Fwy+eMg4sEFNVvCAdo6g==", - "dev": true, - "license": "MIT" + "node_modules/@patternfly/chatbot": { + "resolved": "packages/module", + "link": true }, - "node_modules/@module-federation/webpack-bundler-runtime": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.22.0.tgz", - "integrity": "sha512-aM8gCqXu+/4wBmJtVeMeeMN5guw3chf+2i6HajKtQv7SJfxV/f4IyNQJUeUQu9HfiAZHjqtMV5Lvq/Lvh8LdyA==", + "node_modules/@patternfly/chatbot-tree-shaking-demo": { + "resolved": "packages/tree-shaking-demo", + "link": true + }, + "node_modules/@patternfly/documentation-framework": { + "version": "6.47.0", + "resolved": "https://registry.npmjs.org/@patternfly/documentation-framework/-/documentation-framework-6.47.0.tgz", + "integrity": "sha512-IO2cBZtohrQCElX4UugBAS0ChdxuaGDSeQPWPtN0AUIus0V+n+CO6aIDQRL1cGjqJI7A4E9LPvhA92+ndOkDMw==", "dev": true, "license": "MIT", "dependencies": { - "@module-federation/runtime": "0.22.0", - "@module-federation/sdk": "0.22.0" + "@babel/core": "^7.29.0", + "@babel/preset-env": "7.29.0", + "@babel/preset-react": "^7.28.5", + "@mdx-js/util": "1.6.22", + "@patternfly/ast-helpers": "^1.26.2", + "@reach/router": "npm:@gatsbyjs/reach-router@1.3.9", + "@rspack/core": "^1.7.7", + "@rspack/dev-server": "^1.2.1", + "autoprefixer": "10.4.27", + "babel-loader": "^10.0.0", + "camelcase-css": "2.0.1", + "chokidar": "4.0.3", + "codesandbox": "2.2.3", + "commander": "4.1.1", + "css-loader": "6.11.0", + "detab": "2.0.4", + "express": "4.22.1", + "file-loader": "6.2.0", + "file-saver": "1.3.8", + "fs-extra": "9.1.0", + "glob": "12.0.0", + "handlebars": "4.7.8", + "hast-to-hyperscript": "9.0.1", + "hast-util-to-text": "2.0.1", + "html-formatter": "0.1.9", + "html-webpack-plugin": "5.6.6", + "js-yaml": "4.1.1", + "mdast-util-to-hast": "9.1.2", + "mdurl": "1.0.1", + "null-loader": "4.0.1", + "parse-entities": "2.0.0", + "path-browserify": "1.0.1", + "postcss": "^8.5.8", + "postcss-loader": "7.3.4", + "process": "^0.11.10", + "puppeteer": "^24.37.5", + "puppeteer-cluster": "^0.25.0", + "react-docgen": "6.0.4", + "react-ssr-prepass": "1.6.0", + "remark-footnotes": "1.0.0", + "remark-frontmatter": "2.0.0", + "remark-mdx": "2.0.0-next.8", + "remark-mdxjs": "2.0.0-next.8", + "remark-parse": "8.0.3", + "remark-squeeze-paragraphs": "4.0.0", + "sharp": "0.34.5", + "style-to-object": "0.4.4", + "to-vfile": "6.1.0", + "typedoc": "0.23.28", + "typescript": "4.9.5", + "unified": "9.2.2", + "unist-util-remove": "2.1.0", + "unist-util-visit": "2.0.3", + "url-loader": "4.1.1", + "vfile-reporter": "6.0.2", + "webpack-bundle-analyzer": "5.2.0", + "webpack-dev-server": "5.2.3", + "webpack-merge": "5.10.0" + }, + "bin": { + "pf-docs-framework": "scripts/cli/cli.js" + }, + "peerDependencies": { + "@patternfly/patternfly": "^6.6.0", + "@patternfly/react-code-editor": "^6.6.0", + "@patternfly/react-core": "^6.6.0", + "@patternfly/react-icons": "^6.6.0", + "@patternfly/react-table": "^6.6.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" } }, - "node_modules/@monaco-editor/loader": { - "version": "1.5.0", - "license": "MIT", - "dependencies": { - "state-local": "^1.0.6" + "node_modules/@patternfly/documentation-framework/node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, - "node_modules/@monaco-editor/react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.7.0.tgz", - "integrity": "sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==", + "node_modules/@patternfly/documentation-framework/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, + "license": "Python-2.0" + }, + "node_modules/@patternfly/documentation-framework/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, "license": "MIT", - "dependencies": { - "@monaco-editor/loader": "^1.5.0" - }, - "peerDependencies": { - "monaco-editor": ">= 0.25.0 < 1", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz", - "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==", + "node_modules/@patternfly/documentation-framework/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/core": "^1.5.0", - "@emnapi/runtime": "^1.5.0", - "@tybys/wasm-util": "^0.10.1" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, - "node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "node_modules/@patternfly/documentation-framework/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, "engines": { - "node": ">= 16" + "node": ">= 14.16.0" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", + "node_modules/@patternfly/documentation-framework/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "ms": "^2.1.3" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", + "node_modules/@patternfly/documentation-framework/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==", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">= 8" + "node": ">=10" } }, - "node_modules/@octokit/auth-token": { - "version": "2.5.0", + "node_modules/@patternfly/documentation-framework/node_modules/glob": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-12.0.0.tgz", + "integrity": "sha512-5Qcll1z7IKgHr5g485ePDdHcNQY0k2dtv/bjYy0iuyGxQw2qSOiiXUXJ+AYQpg3HNoUMHqAruX478Jeev7UULw==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "@octokit/types": "^6.0.3" + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@octokit/core": { - "version": "3.6.0", + "node_modules/@patternfly/documentation-framework/node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" + "@isaacs/cliui": "^9.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@octokit/endpoint": { - "version": "6.0.12", + "node_modules/@patternfly/documentation-framework/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@octokit/endpoint/node_modules/is-plain-object": { - "version": "5.0.0", + "node_modules/@patternfly/documentation-framework/node_modules/lru-cache": { + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", + "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=0.10.0" + "node": "20 || >=22" } }, - "node_modules/@octokit/graphql": { - "version": "4.8.0", + "node_modules/@patternfly/documentation-framework/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@octokit/openapi-types": { - "version": "12.11.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "2.21.3", + "node_modules/@patternfly/documentation-framework/node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", "dependencies": { - "@octokit/types": "^6.40.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, - "peerDependencies": { - "@octokit/core": ">=2" + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@octokit/plugin-request-log": { - "version": "1.0.4", + "node_modules/@patternfly/documentation-framework/node_modules/puppeteer-cluster": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/puppeteer-cluster/-/puppeteer-cluster-0.25.0.tgz", + "integrity": "sha512-WEqR6ccYoEMOqW5HAnzs8TJ40xfEaaiZ0LJG1IM8poMGdAgAQBmrZX4n+LLNvVY6G90R22rYZjuPDrw0ho5t+A==", "dev": true, "license": "MIT", + "dependencies": { + "debug": "^4.4.3" + }, "peerDependencies": { - "@octokit/core": ">=3" + "puppeteer": ">=24.0.0" } }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "5.16.2", + "node_modules/@patternfly/documentation-framework/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "license": "MIT", - "dependencies": { - "@octokit/types": "^6.39.0", - "deprecation": "^2.3.1" + "engines": { + "node": ">= 14.18.0" }, - "peerDependencies": { - "@octokit/core": ">=3" + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@octokit/request": { - "version": "5.6.3", + "node_modules/@patternfly/documentation-framework/node_modules/unist-util-visit": { + "version": "2.0.3", "dev": true, "license": "MIT", "dependencies": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/@octokit/request-error": { - "version": "2.1.0", + "node_modules/@patternfly/documentation-framework/node_modules/unist-util-visit-parents": { + "version": "3.1.1", "dev": true, "license": "MIT", "dependencies": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/@octokit/request/node_modules/is-plain-object": { - "version": "5.0.0", + "node_modules/@patternfly/patternfly": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-6.6.0.tgz", + "integrity": "sha512-drZ4wYFQdhYY+VxLIl8PqbYnJoEa0UrNhiUkMCKkgMVNPxmCfNa1d2eEA97tnp2aYew15jQp+MaZcQIQIG8wVg==", "dev": true, + "license": "MIT" + }, + "node_modules/@patternfly/react-code-editor": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-code-editor/-/react-code-editor-6.6.0.tgz", + "integrity": "sha512-WzR2tRI/KeAz2XZNgR2FmO8E06+n652bga0Bt/vDoNuWK3nTTCyO+1KYKRH06huGk3aIEjXDcBGCJQNt7LUJkA==", "license": "MIT", - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@monaco-editor/react": "^4.7.0", + "@patternfly/react-core": "^6.6.0", + "@patternfly/react-icons": "^6.6.0", + "@patternfly/react-styles": "^6.6.0", + "react-dropzone": "14.3.5", + "tslib": "^2.8.1" + }, + "peerDependencies": { + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" } }, - "node_modules/@octokit/rest": { - "version": "18.12.0", - "dev": true, + "node_modules/@patternfly/react-code-editor/node_modules/react-dropzone": { + "version": "14.3.5", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.5.tgz", + "integrity": "sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ==", "license": "MIT", "dependencies": { - "@octokit/core": "^3.5.1", - "@octokit/plugin-paginate-rest": "^2.16.8", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + "attr-accept": "^2.2.4", + "file-selector": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8 || 18.0.0" } }, - "node_modules/@octokit/types": { - "version": "6.41.0", - "dev": true, + "node_modules/@patternfly/react-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-6.6.0.tgz", + "integrity": "sha512-MLYPcJvdDWHZqWcvEH2QhKtCg6APRfrDJ4o192/wc2LUaf4ViGVsVLKDMbaKCamhbGauv7KpffNCSy3fjRy4Bw==", "license": "MIT", "dependencies": { - "@octokit/openapi-types": "^12.11.0" + "@patternfly/react-icons": "^6.6.0", + "@patternfly/react-styles": "^6.6.0", + "@patternfly/react-tokens": "^6.6.0", + "focus-trap": "7.6.6", + "react-dropzone": "^14.3.5", + "tslib": "^2.8.1" + }, + "peerDependencies": { + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" } }, - "node_modules/@patternfly/ast-helpers": { - "version": "1.26.2", - "resolved": "https://registry.npmjs.org/@patternfly/ast-helpers/-/ast-helpers-1.26.2.tgz", - "integrity": "sha512-oN8pYX2Ekep0m6uFbTe4j+YjQhubWqDR0Yoj4jJSKp3gnbi+SknOEzvzMMqjCi1bWODjfmaerKBxN2WaW7c7dA==", - "dev": true, + "node_modules/@patternfly/react-icons": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-6.6.0.tgz", + "integrity": "sha512-cDDUm4PFxqeBo4PS08xO1eFd6CMTOppn5RS4fs2hAgu/vRFkPXuL0zZCkxgRg5asd/W4olEN7WrIAbvjKbHKiQ==", "license": "MIT", "dependencies": { - "acorn": "^8.4.1", - "acorn-class-fields": "^1.0.0", - "acorn-jsx": "^5.3.2", - "acorn-static-class-features": "^1.0.0", - "astring": "^1.7.5" + "tslib": "^2.8.1" + }, + "peerDependencies": { + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" } }, - "node_modules/@patternfly/chatbot": { - "resolved": "packages/module", - "link": true + "node_modules/@patternfly/react-styles": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-6.6.0.tgz", + "integrity": "sha512-u/HzJ48Cg6Nb12dIVbj4g31lMDVHPHVKRXkRuPBcuK6MQyAsxSfcyWVivW7Lga8TsNhFW26JWB5ay+IW5xpZ8A==", + "license": "MIT" }, - "node_modules/@patternfly/documentation-framework": { - "version": "6.47.0", - "resolved": "https://registry.npmjs.org/@patternfly/documentation-framework/-/documentation-framework-6.47.0.tgz", - "integrity": "sha512-IO2cBZtohrQCElX4UugBAS0ChdxuaGDSeQPWPtN0AUIus0V+n+CO6aIDQRL1cGjqJI7A4E9LPvhA92+ndOkDMw==", - "dev": true, + "node_modules/@patternfly/react-table": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-6.6.0.tgz", + "integrity": "sha512-aOVSAbtXagey1xRI8oIkK3I/csh6S00p42qqOkh6G1s5vMZM7oVQH/Nvvq8gIwx4lZ3f1m7IkdD7My8nml0Bsw==", "license": "MIT", "dependencies": { - "@babel/core": "^7.29.0", - "@babel/preset-env": "7.29.0", - "@babel/preset-react": "^7.28.5", - "@mdx-js/util": "1.6.22", - "@patternfly/ast-helpers": "^1.26.2", - "@reach/router": "npm:@gatsbyjs/reach-router@1.3.9", - "@rspack/core": "^1.7.7", - "@rspack/dev-server": "^1.2.1", - "autoprefixer": "10.4.27", - "babel-loader": "^10.0.0", - "camelcase-css": "2.0.1", - "chokidar": "4.0.3", - "codesandbox": "2.2.3", - "commander": "4.1.1", - "css-loader": "6.11.0", - "detab": "2.0.4", - "express": "4.22.1", - "file-loader": "6.2.0", - "file-saver": "1.3.8", - "fs-extra": "9.1.0", - "glob": "12.0.0", - "handlebars": "4.7.8", - "hast-to-hyperscript": "9.0.1", - "hast-util-to-text": "2.0.1", - "html-formatter": "0.1.9", - "html-webpack-plugin": "5.6.6", - "js-yaml": "4.1.1", - "mdast-util-to-hast": "9.1.2", - "mdurl": "1.0.1", - "null-loader": "4.0.1", - "parse-entities": "2.0.0", - "path-browserify": "1.0.1", - "postcss": "^8.5.8", - "postcss-loader": "7.3.4", - "process": "^0.11.10", - "puppeteer": "^24.37.5", - "puppeteer-cluster": "^0.25.0", - "react-docgen": "6.0.4", - "react-ssr-prepass": "1.6.0", - "remark-footnotes": "1.0.0", - "remark-frontmatter": "2.0.0", - "remark-mdx": "2.0.0-next.8", - "remark-mdxjs": "2.0.0-next.8", - "remark-parse": "8.0.3", - "remark-squeeze-paragraphs": "4.0.0", - "sharp": "0.34.5", - "style-to-object": "0.4.4", - "to-vfile": "6.1.0", - "typedoc": "0.23.28", - "typescript": "4.9.5", - "unified": "9.2.2", - "unist-util-remove": "2.1.0", - "unist-util-visit": "2.0.3", - "url-loader": "4.1.1", - "vfile-reporter": "6.0.2", - "webpack-bundle-analyzer": "5.2.0", - "webpack-dev-server": "5.2.3", - "webpack-merge": "5.10.0" - }, - "bin": { - "pf-docs-framework": "scripts/cli/cli.js" - }, - "peerDependencies": { - "@patternfly/patternfly": "^6.6.0", - "@patternfly/react-code-editor": "^6.6.0", "@patternfly/react-core": "^6.6.0", "@patternfly/react-icons": "^6.6.0", - "@patternfly/react-table": "^6.6.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "@patternfly/react-styles": "^6.6.0", + "@patternfly/react-tokens": "^6.6.0", + "lodash": "^4.18.1", + "tslib": "^2.8.1" + }, + "peerDependencies": { + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" } }, - "node_modules/@patternfly/documentation-framework/node_modules/@isaacs/cliui": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", - "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } + "node_modules/@patternfly/react-tokens": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-6.6.0.tgz", + "integrity": "sha512-oRUFYJAM9LKYTM9YRnd7rz3wB6ZoaBWit/Eu+EK22J4o5AhZRjLt0+ewXQ7I99dBP4c8BbnPEUFnxQYAroqNLg==", + "license": "MIT" }, - "node_modules/@patternfly/documentation-framework/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/@peculiar/asn1-cms": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.8.0.tgz", + "integrity": "sha512-NgekZOrSJFSBFLFoLfwePguAWAx7z1+f2TEsWFUMyiqqfntZ4+S/S5hzqME3q4pCA0iOsFKdwiQ35dwY24eVqA==", "dev": true, - "license": "Python-2.0" + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "@peculiar/asn1-x509-attr": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + } }, - "node_modules/@patternfly/documentation-framework/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "node_modules/@peculiar/asn1-csr": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.8.0.tgz", + "integrity": "sha512-akbF8+uvleHs8sejNPQxwmVFuInAg6FMNHOwMILXfP518YfFJwdR3jr6oNUPOaEJfuEhn/vkNOCIT6ASUd4mbg==", "dev": true, "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "node_modules/@peculiar/asn1-ecc": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.8.0.tgz", + "integrity": "sha512-ohwlk+u9Rv2NOAY1c6MfHj45ATVF8R1DUN/WCgABiRtLi2ZftlZWZX7KvpAbU8v9xPcmoILfELeEABj/rn18AQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "node_modules/@peculiar/asn1-pfx": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.8.0.tgz", + "integrity": "sha512-5yof1ytoB++RQtaFbqSUJ8pxDJtZT6vbVqZ8XoJ61ph7UjNVvfFwAilnCodqkNsAodpy13gDhoxZXw00pghnyg==", "dev": true, "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "dependencies": { + "@peculiar/asn1-cms": "^2.8.0", + "@peculiar/asn1-pkcs8": "^2.8.0", + "@peculiar/asn1-rsa": "^2.8.0", + "@peculiar/asn1-schema": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.8.0.tgz", + "integrity": "sha512-qAKXtLpBEw9LqhKpjw3ajZSXlBur+ipW+y2ivVBQAG6F6qRx94yO+1ZR4mvw+YaCfKSaOzLeYEzsPaBp4SJELA==", "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/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==", + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.8.0.tgz", + "integrity": "sha512-b5nDWCnkV60+cQ141D6sVVwK9nz64R5n3zSVnklGd+ECdkW2Ol3U1a6yYFlalpSOaD557yuJB64A+q42jG7lUQ==", "dev": true, "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" + "@peculiar/asn1-cms": "^2.8.0", + "@peculiar/asn1-pfx": "^2.8.0", + "@peculiar/asn1-pkcs8": "^2.8.0", + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "@peculiar/asn1-x509-attr": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/node_modules/glob": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-12.0.0.tgz", - "integrity": "sha512-5Qcll1z7IKgHr5g485ePDdHcNQY0k2dtv/bjYy0iuyGxQw2qSOiiXUXJ+AYQpg3HNoUMHqAruX478Jeev7UULw==", + "node_modules/@peculiar/asn1-rsa": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.8.0.tgz", + "integrity": "sha512-zHEUlCqB2mk7x2lxDwHHJy7hWZOPdGHVlsmITWKB5/PbQo61atbu9PJ/0r9dQNMwFzbKPXZ8uK8/91eUhRznSg==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "foreground-child": "^3.3.1", - "jackspeak": "^4.1.1", - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^2.0.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/node_modules/jackspeak": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", - "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", + "node_modules/@peculiar/asn1-schema": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.8.0.tgz", + "integrity": "sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "@isaacs/cliui": "^9.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "node_modules/@peculiar/asn1-x509": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.8.0.tgz", + "integrity": "sha512-N0CMuhWUzsWEVq6F1q9X6+VKUnWzSW+cSVg+aPaGGwDdbFoFWTYgin5MHwXgpWd6y9COMBxnfy/Qc+Xc7F0Zwg==", "dev": true, "license": "MIT", "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/node_modules/lru-cache": { - "version": "11.5.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz", - "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==", + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.8.0.tgz", + "integrity": "sha512-tHjkfS/qhMnmrlB2J9NhflQlQ7In3khO3CfmVrriOlpTeErY9ZIKOso1hQ5JQiyrJ7ShvqVPk7E5fQmbclkSKA==", "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.8.0", + "@peculiar/asn1-x509": "^2.8.0", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/node_modules/minimatch": { - "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "node_modules/@peculiar/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "brace-expansion": "^5.0.5" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "tslib": "^2.8.1" } }, - "node_modules/@patternfly/documentation-framework/node_modules/path-scurry": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", - "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "node_modules/@peculiar/x509": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", + "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-csr": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.0", + "@peculiar/asn1-pkcs9": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" }, "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=20.0.0" } }, - "node_modules/@patternfly/documentation-framework/node_modules/puppeteer-cluster": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/puppeteer-cluster/-/puppeteer-cluster-0.25.0.tgz", - "integrity": "sha512-WEqR6ccYoEMOqW5HAnzs8TJ40xfEaaiZ0LJG1IM8poMGdAgAQBmrZX4n+LLNvVY6G90R22rYZjuPDrw0ho5t+A==", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", "dev": true, "license": "MIT", - "dependencies": { - "debug": "^4.4.3" - }, - "peerDependencies": { - "puppeteer": ">=24.0.0" + "optional": true, + "engines": { + "node": ">=14" } }, - "node_modules/@patternfly/documentation-framework/node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "node_modules/@pkgr/core": { + "version": "0.1.1", "dev": true, "license": "MIT", "engines": { - "node": ">= 14.18.0" + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://opencollective.com/unts" } }, - "node_modules/@patternfly/documentation-framework/node_modules/unist-util-visit": { - "version": "2.0.3", + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/@puppeteer/browsers": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", + "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" + "debug": "^4.4.3", + "extract-zip": "^2.0.1", + "progress": "^2.0.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.4", + "tar-fs": "^3.1.1", + "yargs": "^17.7.2" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" } }, - "node_modules/@patternfly/documentation-framework/node_modules/unist-util-visit-parents": { - "version": "3.1.1", + "node_modules/@puppeteer/browsers/node_modules/b4a": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz", + "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } } }, - "node_modules/@patternfly/patternfly": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-6.6.0.tgz", - "integrity": "sha512-drZ4wYFQdhYY+VxLIl8PqbYnJoEa0UrNhiUkMCKkgMVNPxmCfNa1d2eEA97tnp2aYew15jQp+MaZcQIQIG8wVg==", + "node_modules/@puppeteer/browsers/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, - "license": "MIT" - }, - "node_modules/@patternfly/react-code-editor": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-code-editor/-/react-code-editor-6.6.0.tgz", - "integrity": "sha512-WzR2tRI/KeAz2XZNgR2FmO8E06+n652bga0Bt/vDoNuWK3nTTCyO+1KYKRH06huGk3aIEjXDcBGCJQNt7LUJkA==", "license": "MIT", "dependencies": { - "@monaco-editor/react": "^4.7.0", - "@patternfly/react-core": "^6.6.0", - "@patternfly/react-icons": "^6.6.0", - "@patternfly/react-styles": "^6.6.0", - "react-dropzone": "14.3.5", - "tslib": "^2.8.1" + "ms": "^2.1.3" }, - "peerDependencies": { - "react": "^17 || ^18 || ^19", - "react-dom": "^17 || ^18 || ^19" + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@patternfly/react-code-editor/node_modules/react-dropzone": { - "version": "14.3.5", - "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.5.tgz", - "integrity": "sha512-9nDUaEEpqZLOz5v5SUcFA0CjM4vq8YbqO0WRls+EYT7+DvxUdzDPKNCPLqGfj3YL9MsniCLCD4RFA6M95V6KMQ==", - "license": "MIT", - "dependencies": { - "attr-accept": "^2.2.4", - "file-selector": "^2.1.0", - "prop-types": "^15.8.1" + "node_modules/@puppeteer/browsers/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 10.13" - }, - "peerDependencies": { - "react": ">= 16.8 || 18.0.0" + "node": ">=10" } }, - "node_modules/@patternfly/react-core": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-6.6.0.tgz", - "integrity": "sha512-MLYPcJvdDWHZqWcvEH2QhKtCg6APRfrDJ4o192/wc2LUaf4ViGVsVLKDMbaKCamhbGauv7KpffNCSy3fjRy4Bw==", + "node_modules/@puppeteer/browsers/node_modules/tar-fs": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.3.tgz", + "integrity": "sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ==", + "dev": true, "license": "MIT", "dependencies": { - "@patternfly/react-icons": "^6.6.0", - "@patternfly/react-styles": "^6.6.0", - "@patternfly/react-tokens": "^6.6.0", - "focus-trap": "7.6.6", - "react-dropzone": "^14.3.5", - "tslib": "^2.8.1" + "pump": "^3.0.0", + "tar-stream": "^3.1.5" }, - "peerDependencies": { - "react": "^17 || ^18 || ^19", - "react-dom": "^17 || ^18 || ^19" + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" } }, - "node_modules/@patternfly/react-icons": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-6.6.0.tgz", - "integrity": "sha512-cDDUm4PFxqeBo4PS08xO1eFd6CMTOppn5RS4fs2hAgu/vRFkPXuL0zZCkxgRg5asd/W4olEN7WrIAbvjKbHKiQ==", + "node_modules/@puppeteer/browsers/node_modules/tar-stream": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", + "integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==", + "dev": true, "license": "MIT", "dependencies": { - "tslib": "^2.8.1" - }, - "peerDependencies": { - "react": "^17 || ^18 || ^19", - "react-dom": "^17 || ^18 || ^19" + "b4a": "^1.6.4", + "bare-fs": "^4.5.5", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, - "node_modules/@patternfly/react-styles": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-6.6.0.tgz", - "integrity": "sha512-u/HzJ48Cg6Nb12dIVbj4g31lMDVHPHVKRXkRuPBcuK6MQyAsxSfcyWVivW7Lga8TsNhFW26JWB5ay+IW5xpZ8A==", - "license": "MIT" - }, - "node_modules/@patternfly/react-table": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-6.6.0.tgz", - "integrity": "sha512-aOVSAbtXagey1xRI8oIkK3I/csh6S00p42qqOkh6G1s5vMZM7oVQH/Nvvq8gIwx4lZ3f1m7IkdD7My8nml0Bsw==", + "node_modules/@reach/router": { + "name": "@gatsbyjs/reach-router", + "version": "1.3.9", + "dev": true, "license": "MIT", "dependencies": { - "@patternfly/react-core": "^6.6.0", - "@patternfly/react-icons": "^6.6.0", - "@patternfly/react-styles": "^6.6.0", - "@patternfly/react-tokens": "^6.6.0", - "lodash": "^4.18.1", - "tslib": "^2.8.1" + "invariant": "^2.2.3", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4" }, "peerDependencies": { - "react": "^17 || ^18 || ^19", - "react-dom": "^17 || ^18 || ^19" + "react": "15.x || 16.x || 17.x || 18.x", + "react-dom": "15.x || 16.x || 17.x || 18.x" } }, - "node_modules/@patternfly/react-tokens": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-6.6.0.tgz", - "integrity": "sha512-oRUFYJAM9LKYTM9YRnd7rz3wB6ZoaBWit/Eu+EK22J4o5AhZRjLt0+ewXQ7I99dBP4c8BbnPEUFnxQYAroqNLg==", - "license": "MIT" + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.4.tgz", + "integrity": "sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@peculiar/asn1-cms": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.8.0.tgz", - "integrity": "sha512-NgekZOrSJFSBFLFoLfwePguAWAx7z1+f2TEsWFUMyiqqfntZ4+S/S5hzqME3q4pCA0iOsFKdwiQ35dwY24eVqA==", + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.4.tgz", + "integrity": "sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.8.0", - "@peculiar/asn1-x509": "^2.8.0", - "@peculiar/asn1-x509-attr": "^2.8.0", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@peculiar/asn1-csr": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.8.0.tgz", - "integrity": "sha512-akbF8+uvleHs8sejNPQxwmVFuInAg6FMNHOwMILXfP518YfFJwdR3jr6oNUPOaEJfuEhn/vkNOCIT6ASUd4mbg==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.4.tgz", + "integrity": "sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.8.0", - "@peculiar/asn1-x509": "^2.8.0", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@peculiar/asn1-ecc": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.8.0.tgz", - "integrity": "sha512-ohwlk+u9Rv2NOAY1c6MfHj45ATVF8R1DUN/WCgABiRtLi2ZftlZWZX7KvpAbU8v9xPcmoILfELeEABj/rn18AQ==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.4.tgz", + "integrity": "sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.8.0", - "@peculiar/asn1-x509": "^2.8.0", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@peculiar/asn1-pfx": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.8.0.tgz", - "integrity": "sha512-5yof1ytoB++RQtaFbqSUJ8pxDJtZT6vbVqZ8XoJ61ph7UjNVvfFwAilnCodqkNsAodpy13gDhoxZXw00pghnyg==", + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.4.tgz", + "integrity": "sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-cms": "^2.8.0", - "@peculiar/asn1-pkcs8": "^2.8.0", - "@peculiar/asn1-rsa": "^2.8.0", - "@peculiar/asn1-schema": "^2.8.0", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/@peculiar/asn1-pkcs8": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.8.0.tgz", - "integrity": "sha512-qAKXtLpBEw9LqhKpjw3ajZSXlBur+ipW+y2ivVBQAG6F6qRx94yO+1ZR4mvw+YaCfKSaOzLeYEzsPaBp4SJELA==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.4.tgz", + "integrity": "sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.8.0", - "@peculiar/asn1-x509": "^2.8.0", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/@peculiar/asn1-pkcs9": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.8.0.tgz", - "integrity": "sha512-b5nDWCnkV60+cQ141D6sVVwK9nz64R5n3zSVnklGd+ECdkW2Ol3U1a6yYFlalpSOaD557yuJB64A+q42jG7lUQ==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.4.tgz", + "integrity": "sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==", + "cpu": [ + "arm" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "dependencies": { - "@peculiar/asn1-cms": "^2.8.0", - "@peculiar/asn1-pfx": "^2.8.0", - "@peculiar/asn1-pkcs8": "^2.8.0", - "@peculiar/asn1-schema": "^2.8.0", - "@peculiar/asn1-x509": "^2.8.0", - "@peculiar/asn1-x509-attr": "^2.8.0", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.4.tgz", + "integrity": "sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.4.tgz", + "integrity": "sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@peculiar/asn1-rsa": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.8.0.tgz", - "integrity": "sha512-zHEUlCqB2mk7x2lxDwHHJy7hWZOPdGHVlsmITWKB5/PbQo61atbu9PJ/0r9dQNMwFzbKPXZ8uK8/91eUhRznSg==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.4.tgz", + "integrity": "sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==", + "cpu": [ + "arm64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.8.0", - "@peculiar/asn1-x509": "^2.8.0", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@peculiar/asn1-schema": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.8.0.tgz", - "integrity": "sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.4.tgz", + "integrity": "sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==", + "cpu": [ + "loong64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "dependencies": { - "@peculiar/utils": "^2.0.2", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@peculiar/asn1-x509": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.8.0.tgz", - "integrity": "sha512-N0CMuhWUzsWEVq6F1q9X6+VKUnWzSW+cSVg+aPaGGwDdbFoFWTYgin5MHwXgpWd6y9COMBxnfy/Qc+Xc7F0Zwg==", + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.4.tgz", + "integrity": "sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==", + "cpu": [ + "loong64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.8.0", - "@peculiar/utils": "^2.0.2", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@peculiar/asn1-x509-attr": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.8.0.tgz", - "integrity": "sha512-tHjkfS/qhMnmrlB2J9NhflQlQ7In3khO3CfmVrriOlpTeErY9ZIKOso1hQ5JQiyrJ7ShvqVPk7E5fQmbclkSKA==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.4.tgz", + "integrity": "sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==", + "cpu": [ + "ppc64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.8.0", - "@peculiar/asn1-x509": "^2.8.0", - "asn1js": "^3.0.10", - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@peculiar/utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", - "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.4.tgz", + "integrity": "sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==", + "cpu": [ + "ppc64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "dependencies": { - "tslib": "^2.8.1" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@peculiar/x509": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", - "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.4.tgz", + "integrity": "sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==", + "cpu": [ + "riscv64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "dependencies": { - "@peculiar/asn1-cms": "^2.6.0", - "@peculiar/asn1-csr": "^2.6.0", - "@peculiar/asn1-ecc": "^2.6.0", - "@peculiar/asn1-pkcs9": "^2.6.0", - "@peculiar/asn1-rsa": "^2.6.0", - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.0", - "pvtsutils": "^1.3.6", - "reflect-metadata": "^0.2.2", - "tslib": "^2.8.1", - "tsyringe": "^4.10.0" - }, - "engines": { - "node": ">=20.0.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.4.tgz", + "integrity": "sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==", + "cpu": [ + "riscv64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, - "engines": { - "node": ">=14" - } + "os": [ + "linux" + ] }, - "node_modules/@pkgr/core": { - "version": "0.1.1", + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.4.tgz", + "integrity": "sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==", + "cpu": [ + "s390x" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@polka/url": { - "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.4.tgz", + "integrity": "sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@puppeteer/browsers": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz", - "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.4.tgz", + "integrity": "sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.4.3", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.5.0", - "semver": "^7.7.4", - "tar-fs": "^3.1.1", - "yargs": "^17.7.2" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=18" - } + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@puppeteer/browsers/node_modules/b4a": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz", - "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==", + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.4.tgz", + "integrity": "sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "peerDependencies": { - "react-native-b4a": "*" - }, - "peerDependenciesMeta": { - "react-native-b4a": { - "optional": true - } - } + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] }, - "node_modules/@puppeteer/browsers/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.4.tgz", + "integrity": "sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } + "optional": true, + "os": [ + "openharmony" + ] }, - "node_modules/@puppeteer/browsers/node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.4.tgz", + "integrity": "sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@puppeteer/browsers/node_modules/tar-fs": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.3.tgz", - "integrity": "sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.4.tgz", + "integrity": "sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@puppeteer/browsers/node_modules/tar-stream": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", - "integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==", + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.4.tgz", + "integrity": "sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "b4a": "^1.6.4", - "bare-fs": "^4.5.5", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@reach/router": { - "name": "@gatsbyjs/reach-router", - "version": "1.3.9", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.4.tgz", + "integrity": "sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "invariant": "^2.2.3", - "prop-types": "^15.6.1", - "react-lifecycles-compat": "^3.0.4" - }, - "peerDependencies": { - "react": "15.x || 16.x || 17.x || 18.x", - "react-dom": "15.x || 16.x || 17.x || 18.x" - } + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@rspack/binding": { "version": "1.7.12", @@ -6213,9 +7068,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "license": "MIT" }, "node_modules/@types/express": { @@ -11655,6 +12510,48 @@ "es6-promise": "^4.0.3" } }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -13378,8 +14275,11 @@ "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.2", + "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, "license": "MIT", "optional": true, "os": [ @@ -23478,6 +24378,147 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rollup": { + "version": "4.62.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.4.tgz", + "integrity": "sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.62.4", + "@rollup/rollup-android-arm64": "4.62.4", + "@rollup/rollup-darwin-arm64": "4.62.4", + "@rollup/rollup-darwin-x64": "4.62.4", + "@rollup/rollup-freebsd-arm64": "4.62.4", + "@rollup/rollup-freebsd-x64": "4.62.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.4", + "@rollup/rollup-linux-arm-musleabihf": "4.62.4", + "@rollup/rollup-linux-arm64-gnu": "4.62.4", + "@rollup/rollup-linux-arm64-musl": "4.62.4", + "@rollup/rollup-linux-loong64-gnu": "4.62.4", + "@rollup/rollup-linux-loong64-musl": "4.62.4", + "@rollup/rollup-linux-ppc64-gnu": "4.62.4", + "@rollup/rollup-linux-ppc64-musl": "4.62.4", + "@rollup/rollup-linux-riscv64-gnu": "4.62.4", + "@rollup/rollup-linux-riscv64-musl": "4.62.4", + "@rollup/rollup-linux-s390x-gnu": "4.62.4", + "@rollup/rollup-linux-x64-gnu": "4.62.4", + "@rollup/rollup-linux-x64-musl": "4.62.4", + "@rollup/rollup-openbsd-x64": "4.62.4", + "@rollup/rollup-openharmony-arm64": "4.62.4", + "@rollup/rollup-win32-arm64-msvc": "4.62.4", + "@rollup/rollup-win32-ia32-msvc": "4.62.4", + "@rollup/rollup-win32-x64-gnu": "4.62.4", + "@rollup/rollup-win32-x64-msvc": "4.62.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-visualizer": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.14.0.tgz", + "integrity": "sha512-VlDXneTDaKsHIw8yzJAFWtrzguoJ/LnQ+lMpoVfYJ3jJF4Ihe5oYLAqLklIK/35lgUY+1yEzCkHyZ1j4A5w5fA==", + "dev": true, + "license": "MIT", + "dependencies": { + "open": "^8.4.0", + "picomatch": "^4.0.2", + "source-map": "^0.7.4", + "yargs": "^17.5.1" + }, + "bin": { + "rollup-plugin-visualizer": "dist/bin/cli.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "rolldown": "1.x", + "rollup": "2.x || 3.x || 4.x" + }, + "peerDependenciesMeta": { + "rolldown": { + "optional": true + }, + "rollup": { + "optional": true + } + } + }, + "node_modules/rollup-plugin-visualizer/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-visualizer/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup-plugin-visualizer/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==", + "dev": true, + "license": "MIT", + "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/rollup-plugin-visualizer/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/rollup-plugin-visualizer/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, "node_modules/run-applescript": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", @@ -25551,6 +26592,54 @@ "node": ">=0.10.0" } }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmp": { "version": "0.0.33", "dev": true, @@ -27170,6 +28259,112 @@ "react": ">=16.6.0" } }, + "node_modules/vite": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/vscode-oniguruma": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", @@ -28646,6 +29841,38 @@ "engines": { "node": ">=12.0.0" } + }, + "packages/tree-shaking-demo": { + "name": "@patternfly/chatbot-tree-shaking-demo", + "version": "0.0.0", + "dependencies": { + "@patternfly/chatbot": "*", + "@patternfly/react-core": "^6.6.0", + "@patternfly/react-icons": "^6.6.0", + "react": "^18", + "react-dom": "^18" + }, + "devDependencies": { + "@types/react": "^18.2.61", + "@types/react-dom": "^18.2.19", + "rollup-plugin-visualizer": "^5.14.0", + "typescript": "^5.3.3", + "vite": "^6.2.0" + } + }, + "packages/tree-shaking-demo/node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } } } } diff --git a/package.json b/package.json index a605e2629..e3163e373 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "lint:fix": "npm run lint:js:fix && npm run lint:md:fix", "test": "TZ=EST jest packages --passWithNoTests", "test:a11y": "npm run test:a11y -w @patternfly/chatbot", - "serve:a11y": "npm run serve:a11y -w @patternfly/chatbot" + "serve:a11y": "npm run serve:a11y -w @patternfly/chatbot", + "analyze:tree-shaking": "npm run analyze -w @patternfly/chatbot-tree-shaking-demo" }, "devDependencies": { "@babel/core": "^7.24.0", diff --git a/packages/module/generate-index.js b/packages/module/generate-index.js index 2f97bc2aa..43aa23558 100644 --- a/packages/module/generate-index.js +++ b/packages/module/generate-index.js @@ -2,36 +2,51 @@ const fse = require('fs-extra'); const glob = require('glob'); const path = require('path'); +const BARREL_EXCLUDE = new Set(['AttachmentEdit', 'CodeModal', 'PreviewAttachment', 'tracking']); + const root = process.cwd(); const ENV_AGNOSTIC_ROOT = `${root}/src`; -const sourceFiles = glob.sync(path.resolve(__dirname, './src/*/index.ts')); +function getModuleName(file) { + return file.replace('/index.ts', '').split('/').pop(); +} -async function generateIndex(files) { - // ensure the dynamic root exists - fse.ensureDirSync(path.resolve(ENV_AGNOSTIC_ROOT)); +function filterBarrelFiles(files) { + return files.filter((file) => !BARREL_EXCLUDE.has(getModuleName(file))); +} - const destFile = `${ENV_AGNOSTIC_ROOT}/index.ts`; +async function generateIndex(files, destRoot = ENV_AGNOSTIC_ROOT) { + fse.ensureDirSync(path.resolve(destRoot)); + + const destFile = `${destRoot}/index.ts`; const stream = fse.createWriteStream(destFile); - stream.once('open', () => { - stream.write('// this file is autogenerated by generate-index.js, modifying it manually will have no effect\n'); - files.forEach((file) => { - const name = file.replace('/index.ts', '').split('/').pop(); - stream.write(`\nexport { default as ${name} } from './${name}';\n`); - stream.write(`export * from './${name}';\n`); + return new Promise((resolve, reject) => { + stream.once('open', () => { + stream.write('// this file is autogenerated by generate-index.js, modifying it manually will have no effect\n'); + + files.forEach((file) => { + const name = getModuleName(file); + + if (BARREL_EXCLUDE.has(name)) { + return; + } + + stream.write(`\nexport { default as ${name} } from './${name}';\n`); + stream.write(`export * from './${name}';\n`); + }); + stream.end(); }); - stream.end(); + stream.once('close', resolve); + stream.once('error', reject); }); - - return Promise.resolve(); } async function run(files) { try { - await generateIndex(files); + await generateIndex(filterBarrelFiles(files)); } catch (error) { // eslint-disable-next-line no-console console.error(error); @@ -39,4 +54,14 @@ async function run(files) { } } -run(sourceFiles); +if (require.main === module) { + const sourceFiles = glob.sync(path.resolve(__dirname, './src/*/index.ts')); + run(sourceFiles); +} + +module.exports = { + BARREL_EXCLUDE, + getModuleName, + filterBarrelFiles, + generateIndex +}; diff --git a/packages/module/generate-index.test.js b/packages/module/generate-index.test.js new file mode 100644 index 000000000..87753760f --- /dev/null +++ b/packages/module/generate-index.test.js @@ -0,0 +1,68 @@ +/* eslint-env jest */ +const fse = require('fs-extra'); +const os = require('os'); +const path = require('path'); + +const { BARREL_EXCLUDE, getModuleName, filterBarrelFiles, generateIndex } = require('./generate-index'); + +describe('generate-index', () => { + describe('BARREL_EXCLUDE', () => { + it('excludes internal modules from the barrel', () => { + expect(BARREL_EXCLUDE).toEqual(new Set(['AttachmentEdit', 'CodeModal', 'PreviewAttachment', 'tracking'])); + }); + }); + + describe('getModuleName', () => { + it('extracts the module name from an index.ts path', () => { + expect(getModuleName('/project/src/Chatbot/index.ts')).toBe('Chatbot'); + expect(getModuleName('/project/src/tracking/index.ts')).toBe('tracking'); + }); + }); + + describe('filterBarrelFiles', () => { + const files = [ + '/project/src/AttachmentEdit/index.ts', + '/project/src/Chatbot/index.ts', + '/project/src/CodeModal/index.ts', + '/project/src/PreviewAttachment/index.ts', + '/project/src/tracking/index.ts' + ]; + + it('removes excluded modules from the file list', () => { + expect(filterBarrelFiles(files)).toEqual(['/project/src/Chatbot/index.ts']); + }); + }); + + describe('generateIndex', () => { + let tempDir; + + beforeEach(async () => { + tempDir = await fse.mkdtemp(path.join(os.tmpdir(), 'generate-index-test-')); + }); + + afterEach(async () => { + await fse.remove(tempDir); + }); + + it('writes exports for included modules and skips excluded ones', async () => { + const files = [ + '/project/src/AttachmentEdit/index.ts', + '/project/src/Chatbot/index.ts', + '/project/src/CodeModal/index.ts', + '/project/src/PreviewAttachment/index.ts', + '/project/src/tracking/index.ts' + ]; + + await generateIndex(files, tempDir); + + const indexContents = await fse.readFile(path.join(tempDir, 'index.ts'), 'utf8'); + + expect(indexContents).toContain("export { default as Chatbot } from './Chatbot';"); + expect(indexContents).toContain("export * from './Chatbot';"); + expect(indexContents).not.toContain('AttachmentEdit'); + expect(indexContents).not.toContain('CodeModal'); + expect(indexContents).not.toContain('PreviewAttachment'); + expect(indexContents).not.toContain('tracking'); + }); + }); +}); diff --git a/packages/module/monaco-environment.js b/packages/module/monaco-environment.js new file mode 100644 index 000000000..544660032 --- /dev/null +++ b/packages/module/monaco-environment.js @@ -0,0 +1,45 @@ +/* global globalThis */ +// Monaco worker setup for webpack/rspack apps using CodeModal, PreviewAttachment, or AttachmentEdit. +// Import once at app startup: import '@patternfly/chatbot/monaco-environment'; +// Paths assume npm layout: node_modules/@patternfly/chatbot -> node_modules/monaco-editor. +// Each branch must use inline new Worker(new URL(...)) so the bundler emits worker chunks. +const workerOptions = { type: 'module' }; + +if (typeof globalThis !== 'undefined' && !globalThis.MonacoEnvironment?.getWorker) { + globalThis.MonacoEnvironment = { + getWorker(_workerId, label) { + switch (label) { + case 'json': + return new Worker( + new URL('../../monaco-editor/esm/vs/language/json/json.worker.js', import.meta.url), + workerOptions + ); + case 'css': + case 'scss': + case 'less': + return new Worker( + new URL('../../monaco-editor/esm/vs/language/css/css.worker.js', import.meta.url), + workerOptions + ); + case 'html': + case 'handlebars': + case 'razor': + return new Worker( + new URL('../../monaco-editor/esm/vs/language/html/html.worker.js', import.meta.url), + workerOptions + ); + case 'typescript': + case 'javascript': + return new Worker( + new URL('../../monaco-editor/esm/vs/language/typescript/ts.worker.js', import.meta.url), + workerOptions + ); + default: + return new Worker( + new URL('../../monaco-editor/esm/vs/editor/editor.worker.js', import.meta.url), + workerOptions + ); + } + } + }; +} diff --git a/packages/module/package.json b/packages/module/package.json index d55656838..fef04e148 100644 --- a/packages/module/package.json +++ b/packages/module/package.json @@ -88,5 +88,23 @@ "victory-stack": "^37.1.1", "victory-tooltip": "^37.1.1", "victory-voronoi-container": "^37.1.1" - } -} + }, + "exports": { + ".": { + "types": "./dist/esm/index.d.ts", + "import": "./dist/esm/index.js", + "require": "./dist/cjs/index.js" + }, + "./dist/css/main.css": "./dist/css/main.css", + "./dist/dynamic/*": { + "import": "./dist/esm/*/index.js", + "require": "./dist/cjs/*/index.js" + }, + "./monaco-environment": "./monaco-environment.js" + }, + "sideEffects": [ + "**/*.css", + "**/*.scss", + "patternfly-docs/**" + ] +} \ No newline at end of file diff --git a/packages/module/patternfly-docs/content/extensions/chatbot/chatbot.md b/packages/module/patternfly-docs/content/extensions/chatbot/chatbot.md index d20936f88..ff4f4fc42 100644 --- a/packages/module/patternfly-docs/content/extensions/chatbot/chatbot.md +++ b/packages/module/patternfly-docs/content/extensions/chatbot/chatbot.md @@ -51,6 +51,7 @@ Explore our documentation, which covers both the components you'll need to build - [Chat transcripts](/extensions/chatbot/overview/demo#chat-transcripts) - [Analytics](/extensions/chatbot/analytics): Tracking for ChatBot interactions - [Customizing messages](/extensions/chatbot/customizing-messages): Details for the implementation of custom messages +- [Tree-shaking](/extensions/chatbot/tree-shaking): Bundle size optimization and import best practices --- diff --git a/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx index 78198441c..86933fe27 100644 --- a/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx +++ b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/BotMessage.tsx @@ -17,7 +17,7 @@ import { SelectList, SelectOption } from '@patternfly/react-core'; -import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle'; +import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/dynamic/Message'; export const BotMessageExample: FunctionComponent = () => { const [variant, setVariant] = useState('Code'); diff --git a/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx index 4d21dc9f1..cf7678de9 100644 --- a/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx +++ b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/MessageWithQuickStart.tsx @@ -1,8 +1,8 @@ import { FunctionComponent } from 'react'; import Message from '@patternfly/chatbot/dist/dynamic/Message'; import { explorePipelinesQuickStart } from './explore-pipeline-quickstart.ts'; -import { monitorSampleAppQuickStart } from '@patternfly/chatbot/src/Message/QuickStarts/monitor-sampleapp-quickstart.ts'; -import { QuickStart } from '@patternfly/chatbot/dist/esm/Message/QuickStarts/types'; +import { monitorSampleAppQuickStart } from './monitor-sampleapp-quickstart.ts'; +import { QuickStart } from '@patternfly/chatbot/dist/dynamic/Message'; export const MessageWithQuickStartExample: FunctionComponent = () => ( <> diff --git a/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md index fe3db8f6f..8dea8bb2b 100644 --- a/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md +++ b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/Messages.md @@ -48,7 +48,7 @@ import MessageDivider from '@patternfly/chatbot/dist/dynamic/MessageDivider'; import ToolCall from '@patternfly/chatbot/dist/dynamic/ToolCall'; import ResponseActions, { ResponseActionsGroups } from '@patternfly/chatbot/dist/dynamic/ResponseActions'; import ToolResponse from '@patternfly/chatbot/dist/dynamic/ToolResponse'; -import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle'; +import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/dynamic/Message'; import SourcesCard from '@patternfly/chatbot/dist/dynamic/SourcesCard'; import { RhUiArrowCircleDownFillIcon, RhUiArrowRightIcon, RhUiCheckCircleFillIcon, RhUiCopyFillIcon, RhUiExportIcon, RhMicronsInformationFillIcon, OutlinedQuestionCircleIcon, RhUiRedoIcon, RhUiBuildFillIcon, RhUiQuestionMarkCircleIcon } from '@patternfly/react-icons'; import patternflyAvatar from './patternfly_avatar.jpg'; @@ -59,7 +59,7 @@ import FileDropZone from '@patternfly/chatbot/dist/dynamic/FileDropZone'; import { PreviewAttachment } from '@patternfly/chatbot/dist/dynamic/PreviewAttachment'; import ChatbotAlert from '@patternfly/chatbot/dist/dynamic/ChatbotAlert'; import { explorePipelinesQuickStart } from './explore-pipeline-quickstart.ts'; -import { monitorSampleAppQuickStart } from '@patternfly/chatbot/src/Message/QuickStarts/monitor-sampleapp-quickstart.ts'; +import { monitorSampleAppQuickStart } from './monitor-sampleapp-quickstart.ts'; import userAvatar from './user_avatar.svg'; import squareImg from './PF-social-color-square.svg'; import { CSSProperties, useState, Fragment, FunctionComponent, MouseEvent as ReactMouseEvent, KeyboardEvent as ReactKeyboardEvent, Ref, isValidElement, cloneElement, Children, ReactNode, useRef, useEffect } from 'react'; diff --git a/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx index 75e43389f..445b05288 100644 --- a/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx +++ b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/UserMessage.tsx @@ -19,7 +19,7 @@ import { SelectList, SelectOption } from '@patternfly/react-core'; -import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/esm/Message/Plugins/rehypeCodeBlockToggle'; +import { rehypeCodeBlockToggle } from '@patternfly/chatbot/dist/dynamic/Message'; export const UserMessageExample: FunctionComponent = () => { const messageInputRef = useRef(null); diff --git a/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/monitor-sampleapp-quickstart.ts b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/monitor-sampleapp-quickstart.ts new file mode 100644 index 000000000..b6c7049ae --- /dev/null +++ b/packages/module/patternfly-docs/content/extensions/chatbot/examples/Messages/monitor-sampleapp-quickstart.ts @@ -0,0 +1 @@ +export { monitorSampleAppQuickStart } from '../../../../../../src/Message/QuickStarts/monitor-sampleapp-quickstart.ts'; diff --git a/packages/module/patternfly-docs/content/extensions/chatbot/tree-shaking.md b/packages/module/patternfly-docs/content/extensions/chatbot/tree-shaking.md new file mode 100644 index 000000000..85d9fc20b --- /dev/null +++ b/packages/module/patternfly-docs/content/extensions/chatbot/tree-shaking.md @@ -0,0 +1,143 @@ +--- +id: Tree-shaking +title: Tree-shaking +section: extensions +subsection: ChatBot +sortValue: 80 +source: TreeShaking +--- + +**Note:** The PatternFly ChatBot extension lives in its own package [`@patternfly/chatbot`](https://www.npmjs.com/package/@patternfly/chatbot). + +When you add ChatBot to your application, you want the bundler to include only the components you actually use — not the entire library or every PatternFly icon. ChatBot is designed to support tree-shaking when imported correctly. + +--- + +## Recommended import pattern + +Import each component from its dynamic entry point: + +```tsx +import ChatbotToggle from '@patternfly/chatbot/dist/dynamic/ChatbotToggle'; +import ChatbotHeader from '@patternfly/chatbot/dist/dynamic/ChatbotHeader'; +``` + +Named imports from the root barrel also tree-shake with modern bundlers: + +```tsx +import { ChatbotToggle } from '@patternfly/chatbot'; +``` + +Sub-components can be imported from the same entry point: + +```tsx +import ChatbotHeader, { + ChatbotHeaderMenu, + ChatbotHeaderMain, +} from '@patternfly/chatbot/dist/dynamic/ChatbotHeader'; +``` + +Per-component `dist/dynamic` imports are preferred for faster builds and for components excluded from the root barrel (`CodeModal`, `PreviewAttachment`, `AttachmentEdit`). + +## What to avoid + +Do **not** use wildcard imports from the package root: + +```tsx +// Avoid — may pull in the entire library +import * as Chatbot from '@patternfly/chatbot'; +``` + +## Icon imports + +Which PatternFly icons end up in your bundle depends on **which ChatBot components you import**, not on whether ChatBot source code or your app uses barrel or deep icon paths. Importing `ChatbotToggle` via `dist/dynamic` includes only the icons that component uses — currently four icons in the tree-shaking demo. + +## CSS import + +ChatBot styles are side-effectful and must be imported explicitly: + +```tsx +import '@patternfly/chatbot/dist/css/main.css'; +``` + +Place this import after your PatternFly CSS imports so ChatBot overrides apply correctly. + +## Monaco editor (`CodeModal`, attachment preview and edit) + +`CodeModal` (used by `PreviewAttachment` and `AttachmentEdit`) lazy-loads Monaco. Web workers must be configured before the modal opens. Import the package worker helper once at application startup: + +```tsx +import '@patternfly/chatbot/monaco-environment'; +import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment'; +``` + +`CodeModal`, `PreviewAttachment`, and `AttachmentEdit` are excluded from the root barrel so Monaco stays out of root-barrel bundles. Import them from dynamic entry points: + +```tsx +import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment'; +import AttachmentEdit from '@patternfly/chatbot/dist/dynamic/AttachmentEdit'; +``` + +`monaco-editor` and `@monaco-editor/react` are peer dependencies when you use these components. + +## Markdown rendering (`Message`, `MarkdownContent`) + +`MarkdownContent` lazy-loads its markdown parser so lightweight imports avoid pulling in `react-markdown`, syntax highlighting, and related dependencies until they are needed. In the tree-shaking demo, that async chunk is roughly 400 KB. + +`MessageBox` automatically preloads the markdown renderer and coordinates rendering so existing messages do not each flash an individual loading state — message chrome (avatars, timestamps, and so on) appears immediately, and markdown content fills in once the chunk is ready. + +For chatbots that display messages on first render, you can call `preloadMarkdownRenderer()` earlier in your application — such as in your app's entry point or route loader — so the chunk is already loaded by the time the chatbot mounts: + +```tsx +// App.tsx or route loader — call once at startup +import { preloadMarkdownRenderer } from '@patternfly/chatbot/dist/dynamic/MarkdownContent'; + +preloadMarkdownRenderer(); +``` + +## Migration: root barrel changes + +The following modules are **not** re-exported from the root barrel (`@patternfly/chatbot`). They were removed so Monaco and internal utilities stay out of default bundles. Update existing root imports to subpath entry points: + +| Module | Before (no longer works) | After | +|--------|--------------------------|-------| +| `CodeModal` | `import { CodeModal } from '@patternfly/chatbot'` | `import CodeModal from '@patternfly/chatbot/dist/dynamic/CodeModal'` | +| `PreviewAttachment` | `import { PreviewAttachment } from '@patternfly/chatbot'` | `import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment'` | +| `AttachmentEdit` | `import { AttachmentEdit } from '@patternfly/chatbot'` | `import AttachmentEdit from '@patternfly/chatbot/dist/dynamic/AttachmentEdit'` | +| `tracking` | `import { getTrackingProviders } from '@patternfly/chatbot'` | `import { getTrackingProviders } from '@patternfly/chatbot/dist/dynamic/tracking'` | + +All other components remain available from the root barrel and continue to tree-shake when your bundler respects the package `sideEffects` field. + +When using `CodeModal`, `PreviewAttachment`, or `AttachmentEdit`, also import the Monaco worker helper once at application startup: + +```tsx +import '@patternfly/chatbot/monaco-environment'; +``` + +## Verify tree-shaking in your project + +The repository includes a tree-shaking demo at `packages/tree-shaking-demo/` that builds four scenarios and compares bundle size, icon count, and component count: + +```bash +npm run build -w @patternfly/chatbot +npm run analyze:tree-shaking +``` + +Open the generated `dist//stats.html` files for interactive bundle visualizations. + +Example results from the demo (Vite 6): + +| Scenario | JS size | Icons | ChatBot components | +|----------|---------|-------|--------------------| +| `ChatbotToggle` via `dist/dynamic` | ~184 KB | 4 | 1 | +| `ChatbotToggle` via root barrel | ~184 KB | 4 | 1 | +| Multi-component UI (7 imports) | ~895 KB | 49 | 17 | + +## How ChatBot supports tree-shaking + +- **ESM output** with a `module` field pointing to `dist/esm/` +- **`sideEffects`** in `package.json` so bundlers can drop unused re-exports from the root barrel while preserving CSS and the documentation-site style entry (`patternfly-docs/**`) +- **Per-component dynamic entry points** at `dist/dynamic//` +- **Unbundled compilation** — icons and dependencies remain as external imports for your bundler to resolve +- **`exports`** field maps public subpaths for bundler-friendly resolution +- **Explicit CSS imports** (see above) diff --git a/packages/module/patternfly-docs/monaco-environment.js b/packages/module/patternfly-docs/monaco-environment.js new file mode 100644 index 000000000..7adfd1db6 --- /dev/null +++ b/packages/module/patternfly-docs/monaco-environment.js @@ -0,0 +1,45 @@ +/* global globalThis */ +// Docs-site worker setup for rspack/webpack. Paths target hoisted monaco-editor in the +// workspace root (../../../node_modules/...). npm consumers should import +// @patternfly/chatbot/monaco-environment instead (../../monaco-editor/... layout). +// Each branch must use inline new Worker(new URL(...)) so rspack emits worker chunks. +const workerOptions = { type: 'module' }; + +if (typeof globalThis !== 'undefined' && !globalThis.MonacoEnvironment?.getWorker) { + globalThis.MonacoEnvironment = { + getWorker(_workerId, label) { + switch (label) { + case 'json': + return new Worker( + new URL('../../../node_modules/monaco-editor/esm/vs/language/json/json.worker.js', import.meta.url), + workerOptions + ); + case 'css': + case 'scss': + case 'less': + return new Worker( + new URL('../../../node_modules/monaco-editor/esm/vs/language/css/css.worker.js', import.meta.url), + workerOptions + ); + case 'html': + case 'handlebars': + case 'razor': + return new Worker( + new URL('../../../node_modules/monaco-editor/esm/vs/language/html/html.worker.js', import.meta.url), + workerOptions + ); + case 'typescript': + case 'javascript': + return new Worker( + new URL('../../../node_modules/monaco-editor/esm/vs/language/typescript/ts.worker.js', import.meta.url), + workerOptions + ); + default: + return new Worker( + new URL('../../../node_modules/monaco-editor/esm/vs/editor/editor.worker.js', import.meta.url), + workerOptions + ); + } + } + }; +} diff --git a/packages/module/patternfly-docs/patternfly-docs.css.js b/packages/module/patternfly-docs/patternfly-docs.css.js index c104c2235..2e05d9070 100644 --- a/packages/module/patternfly-docs/patternfly-docs.css.js +++ b/packages/module/patternfly-docs/patternfly-docs.css.js @@ -1,4 +1,10 @@ // Patternfly +// Monaco workers for CodeModal attachment examples — load before any editor opens. +// The docs framework aliases this file as the global client entry (client-styles), so +// side-effect imports belong here even though the filename suggests CSS only. +// Uses patternfly-docs/monaco-environment.js (monorepo node_modules paths), not the package export. +// This file must stay side-effectful — see package.json "sideEffects" ("patternfly-docs/**"). +import './monaco-environment.js'; import '@patternfly/patternfly/patternfly.css'; // Patternfly utilities import '@patternfly/patternfly/patternfly-addons.css'; diff --git a/packages/module/src/CodeModal/CodeModal.tsx b/packages/module/src/CodeModal/CodeModal.tsx index 59788042c..42c88c161 100644 --- a/packages/module/src/CodeModal/CodeModal.tsx +++ b/packages/module/src/CodeModal/CodeModal.tsx @@ -27,6 +27,12 @@ import ChatbotModal from '../ChatbotModal/ChatbotModal'; let monacoInstance: typeof import('monaco-editor') | null = null; const loadMonaco = async () => { if (!monacoInstance) { + if (!globalThis.MonacoEnvironment?.getWorker && !globalThis.MonacoEnvironment?.getWorkerUrl) { + // eslint-disable-next-line no-console + console.error( + 'Monaco web workers are not configured. Import @patternfly/chatbot/monaco-environment before using CodeModal.' + ); + } const [monaco, { loader }] = await Promise.all([import('monaco-editor'), import('@monaco-editor/react')]); monacoInstance = monaco; loader.config({ monaco }); diff --git a/packages/module/src/DeepThinking/DeepThinking.test.tsx b/packages/module/src/DeepThinking/DeepThinking.test.tsx index 4f0a2731b..8af62acdf 100644 --- a/packages/module/src/DeepThinking/DeepThinking.test.tsx +++ b/packages/module/src/DeepThinking/DeepThinking.test.tsx @@ -2,6 +2,7 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import '@testing-library/jest-dom'; import DeepThinking from './DeepThinking'; +import { expectBoldMarkdownText } from '../test-utils/markdownTestUtils'; describe('DeepThinking', () => { const defaultProps = { @@ -120,11 +121,10 @@ describe('DeepThinking', () => { expect(screen.getByText('Thinking content')).not.toBeVisible(); }); - it('should render toggleContent as markdown when isToggleContentMarkdown is true', () => { + it('should render toggleContent as markdown when isToggleContentMarkdown is true', async () => { const toggleContent = '**Bold thinking**'; - const { container } = render(); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold thinking')).toBeTruthy(); + render(); + await expectBoldMarkdownText('Bold thinking'); }); it('should not render toggleContent as markdown when isToggleContentMarkdown is false', () => { @@ -134,11 +134,10 @@ describe('DeepThinking', () => { expect(screen.getByText('**Bold thinking**')).toBeTruthy(); }); - it('should render subheading as markdown when isSubheadingMarkdown is true', () => { + it('should render subheading as markdown when isSubheadingMarkdown is true', async () => { const subheading = '**Bold subheading**'; - const { container } = render(); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold subheading')).toBeTruthy(); + render(); + await expectBoldMarkdownText('Bold subheading'); }); it('should not render subheading as markdown when isSubheadingMarkdown is false', () => { @@ -147,11 +146,10 @@ describe('DeepThinking', () => { expect(screen.getByText('**Bold subheading**')).toBeTruthy(); }); - it('should render body as markdown when isBodyMarkdown is true', () => { + it('should render body as markdown when isBodyMarkdown is true', async () => { const body = '**Bold body**'; - const { container } = render(); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold body')).toBeTruthy(); + render(); + await expectBoldMarkdownText('Bold body'); }); it('should not render body as markdown when isBodyMarkdown is false', () => { diff --git a/packages/module/src/MarkdownContent/MarkdownContent.test.tsx b/packages/module/src/MarkdownContent/MarkdownContent.test.tsx index c05292347..29cfbd942 100644 --- a/packages/module/src/MarkdownContent/MarkdownContent.test.tsx +++ b/packages/module/src/MarkdownContent/MarkdownContent.test.tsx @@ -1,7 +1,12 @@ import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom'; -import MarkdownContent from './MarkdownContent'; +import MarkdownContent, { + MarkdownRendererReadyContext, + preloadMarkdownRenderer, + whenMarkdownRendererReady +} from './MarkdownContent'; import rehypeExternalLinks from '../__mocks__/rehype-external-links'; +import { expectBoldMarkdownText, warmupMarkdownRenderer } from '../test-utils/markdownTestUtils'; const BOLD_TEXT = '**Bold text**'; const ITALIC_TEXT = '*Italic text*'; @@ -33,14 +38,17 @@ const BLOCKQUOTE = '> This is a blockquote'; const IMAGE = '![Alt text](https://example.com/image.png)'; describe('MarkdownContent', () => { + beforeAll(async () => { + await warmupMarkdownRenderer(); + }); + beforeEach(() => { jest.clearAllMocks(); }); - it('should render bold text correctly', () => { - const { container } = render(); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold text')).toBeTruthy(); + it('should render bold text correctly', async () => { + render(); + await expectBoldMarkdownText('Bold text'); }); it('should render italic text correctly', () => { @@ -205,3 +213,42 @@ const x = 5; expect(screen.getByRole('link', { name: /Link/i })).toBeTruthy(); }); }); + +describe('preloadMarkdownRenderer', () => { + it('starts loading the markdown renderer', async () => { + preloadMarkdownRenderer(); + const module = await whenMarkdownRendererReady(); + expect(module.default).toBeDefined(); + }); +}); + +describe('whenMarkdownRendererReady', () => { + it('should resolve to the MarkdownRenderer module', async () => { + const module = await whenMarkdownRendererReady(); + expect(module.default).toBeDefined(); + }); +}); + +describe('MarkdownContent with MarkdownRendererReadyContext', () => { + it('renders nothing while markdown is not ready inside MessageBox', () => { + const { container } = render( + + + + ); + + expect(container).toBeEmptyDOMElement(); + }); +}); + +describe('MarkdownContent lazy loading', () => { + it('renders nothing while markdown renderer is not ready', () => { + const { container } = render( + + + + ); + + expect(container).toBeEmptyDOMElement(); + }); +}); diff --git a/packages/module/src/MarkdownContent/MarkdownContent.tsx b/packages/module/src/MarkdownContent/MarkdownContent.tsx index ff937b708..cb7755866 100644 --- a/packages/module/src/MarkdownContent/MarkdownContent.tsx +++ b/packages/module/src/MarkdownContent/MarkdownContent.tsx @@ -1,34 +1,76 @@ // ============================================================================ // Markdown Content - Shared component for rendering markdown // ============================================================================ -import { type FunctionComponent, ReactNode } from 'react'; -import Markdown, { Options } from 'react-markdown'; -import remarkGfm from 'remark-gfm'; +import { + createContext, + useContext, + useSyncExternalStore, + type ComponentType, + type FunctionComponent, + type ReactNode +} from 'react'; +import type { Options } from 'react-markdown'; import { ContentVariants } from '@patternfly/react-core'; -import CodeBlockMessage, { CodeBlockMessageProps } from '../Message/CodeBlockMessage/CodeBlockMessage'; +import type { CodeBlockMessageProps } from '../Message/CodeBlockMessage/CodeBlockMessage'; +import type { TableProps } from '@patternfly/react-table'; +import type { PluggableList } from 'unified'; +import type { ButtonProps } from '@patternfly/react-core'; import TextMessage from '../Message/TextMessage/TextMessage'; -import ListItemMessage from '../Message/ListMessage/ListItemMessage'; -import UnorderedListMessage from '../Message/ListMessage/UnorderedListMessage'; -import OrderedListMessage from '../Message/ListMessage/OrderedListMessage'; -import TableMessage from '../Message/TableMessage/TableMessage'; -import TrMessage from '../Message/TableMessage/TrMessage'; -import TdMessage from '../Message/TableMessage/TdMessage'; -import TbodyMessage from '../Message/TableMessage/TbodyMessage'; -import TheadMessage from '../Message/TableMessage/TheadMessage'; -import ThMessage from '../Message/TableMessage/ThMessage'; -import { TableProps } from '@patternfly/react-table'; -import ImageMessage from '../Message/ImageMessage/ImageMessage'; -import rehypeUnwrapImages from 'rehype-unwrap-images'; -import rehypeExternalLinks from 'rehype-external-links'; -import rehypeSanitize from 'rehype-sanitize'; -import rehypeHighlight from 'rehype-highlight'; -import 'highlight.js/styles/vs2015.css'; -import { PluggableList } from 'unified'; -import LinkMessage from '../Message/LinkMessage/LinkMessage'; -import { rehypeMoveImagesOutOfParagraphs } from '../Message/Plugins/rehypeMoveImagesOutOfParagraphs'; -import SuperscriptMessage from '../Message/SuperscriptMessage/SuperscriptMessage'; -import { ButtonProps } from '@patternfly/react-core'; -import { css } from '@patternfly/react-styles'; + +type MarkdownRendererModule = typeof import('./MarkdownRenderer'); + +let markdownRendererPromise: Promise | null = null; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +let ResolvedMarkdownRenderer: ComponentType | null = null; +const markdownRendererListeners = new Set<() => void>(); + +const importMarkdownRenderer = () => { + if (!markdownRendererPromise) { + markdownRendererPromise = import('./MarkdownRenderer').then((module) => { + ResolvedMarkdownRenderer = module.default; + markdownRendererListeners.forEach((listener) => listener()); + return module; + }); + } + + return markdownRendererPromise; +}; + +const subscribeToMarkdownRendererReady = (listener: () => void) => { + markdownRendererListeners.add(listener); + void importMarkdownRenderer(); + return () => markdownRendererListeners.delete(listener); +}; + +/** + * Whether the lazy-loaded markdown renderer chunk has finished loading. + */ +export const useIsMarkdownRendererReady = (): boolean => + useSyncExternalStore( + subscribeToMarkdownRendererReady, + () => ResolvedMarkdownRenderer !== null, + () => true + ); + +/** + * When provided by `MessageBox`, defers markdown rendering until the shared chunk is ready + * so existing messages don't each flash an individual loading state. + */ +export const MarkdownRendererReadyContext = createContext(null); + +/** + * Eagerly fetches the markdown renderer chunk so the first rendered message + * doesn't flash a loading state while the chunk downloads. Safe to call repeatedly + * (the dynamic import is cached). + */ +export const preloadMarkdownRenderer = (): void => { + void importMarkdownRenderer(); +}; + +/** + * Resolves when the markdown renderer chunk has loaded. + */ +export const whenMarkdownRendererReady = (): Promise => importMarkdownRenderer(); /** * MarkdownContent renders content either as plain text or with content with markdown support. @@ -69,31 +111,13 @@ export interface MarkdownContentProps { export const MarkdownContent: FunctionComponent = ({ content, isMarkdownDisabled, - codeBlockProps, - tableProps, - openLinkInNewTab = true, - additionalRehypePlugins = [], - additionalRemarkPlugins = [], - linkProps, - reactMarkdownProps, - remarkGfmProps, - hasNoImages = false, isPrimary, textComponent, - shouldRetainStyles + ...markdownProps }: MarkdownContentProps) => { - let rehypePlugins: PluggableList = [rehypeUnwrapImages, rehypeMoveImagesOutOfParagraphs, rehypeHighlight]; - if (openLinkInNewTab) { - rehypePlugins = rehypePlugins.concat([[rehypeExternalLinks, { target: '_blank' }, rehypeSanitize]]); - } - if (additionalRehypePlugins) { - rehypePlugins.push(...additionalRehypePlugins); - } - - const disallowedElements = hasNoImages ? ['img'] : []; - if (reactMarkdownProps && reactMarkdownProps.disallowedElements) { - disallowedElements.push(...reactMarkdownProps.disallowedElements); - } + const contextReady = useContext(MarkdownRendererReadyContext); + const storeReady = useIsMarkdownRendererReady(); + const isMarkdownRendererReady = contextReady ?? storeReady; if (isMarkdownDisabled) { if (textComponent) { @@ -106,178 +130,11 @@ export const MarkdownContent: FunctionComponent = ({ ); } - return ( - { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ( -
- ); - }, - p: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ( - - ); - }, - code: ({ children, ...props }) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...codeProps } = props; - return ( - - {children} - - ); - }, - h1: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - h2: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - h3: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - h4: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - h5: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - h6: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - blockquote: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ( - - ); - }, - ul: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - ol: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - li: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - // table requires node attribute for calculating headers for mobile breakpoint - table: (props) => ( - - ), - tbody: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - thead: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - tr: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - td: (props) => { - // Conflicts with Td type - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, width, ...rest } = props; - return ; - }, - th: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - img: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - }, - a: (props) => { - // node is just the details of the document structure - not needed - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ( - // some a types conflict with ButtonProps, but it's ok because we are using an a tag - // there are too many to handle manually - - {props.children} - - ); - }, - // used for footnotes - sup: (props) => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { node, ...rest } = props; - return ; - } - }} - remarkPlugins={[[remarkGfm, { ...remarkGfmProps }], ...additionalRemarkPlugins]} - rehypePlugins={rehypePlugins} - {...reactMarkdownProps} - remarkRehypeOptions={{ - // removes sr-only class from footnote labels applied by default - footnoteLabelProperties: { className: [''] }, - // omit default ↩ text; backref icon is rendered in LinkMessage - footnoteBackContent: (_referenceIndex, rereferenceIndex) => { - if (rereferenceIndex > 1) { - return [ - { - type: 'element', - tagName: 'sup', - properties: {}, - children: [{ type: 'text', value: String(rereferenceIndex) }] - } - ]; - } - return []; - }, - ...reactMarkdownProps?.remarkRehypeOptions - }} - disallowedElements={disallowedElements} - > - {content} - - ); + if (!isMarkdownRendererReady || !ResolvedMarkdownRenderer) { + return null; + } + + return ; }; export default MarkdownContent; diff --git a/packages/module/src/MarkdownContent/MarkdownRenderer.tsx b/packages/module/src/MarkdownContent/MarkdownRenderer.tsx new file mode 100644 index 000000000..0290b6b6d --- /dev/null +++ b/packages/module/src/MarkdownContent/MarkdownRenderer.tsx @@ -0,0 +1,235 @@ +// ============================================================================ +// Markdown Renderer - Heavy markdown pipeline (dynamically imported) +// ============================================================================ +import { type FunctionComponent } from 'react'; +import Markdown from 'react-markdown'; +import remarkGfm from 'remark-gfm'; +import { ContentVariants } from '@patternfly/react-core'; +import CodeBlockMessage from '../Message/CodeBlockMessage/CodeBlockMessage'; +import TextMessage from '../Message/TextMessage/TextMessage'; +import ListItemMessage from '../Message/ListMessage/ListItemMessage'; +import UnorderedListMessage from '../Message/ListMessage/UnorderedListMessage'; +import OrderedListMessage from '../Message/ListMessage/OrderedListMessage'; +import TableMessage from '../Message/TableMessage/TableMessage'; +import TrMessage from '../Message/TableMessage/TrMessage'; +import TdMessage from '../Message/TableMessage/TdMessage'; +import TbodyMessage from '../Message/TableMessage/TbodyMessage'; +import TheadMessage from '../Message/TableMessage/TheadMessage'; +import ThMessage from '../Message/TableMessage/ThMessage'; +import ImageMessage from '../Message/ImageMessage/ImageMessage'; +import rehypeUnwrapImages from 'rehype-unwrap-images'; +import rehypeExternalLinks from 'rehype-external-links'; +import rehypeSanitize from 'rehype-sanitize'; +import rehypeHighlight from 'rehype-highlight'; +import 'highlight.js/styles/vs2015.css'; +import type { PluggableList } from 'unified'; +import LinkMessage from '../Message/LinkMessage/LinkMessage'; +import { rehypeMoveImagesOutOfParagraphs } from '../Message/Plugins/rehypeMoveImagesOutOfParagraphs'; +import SuperscriptMessage from '../Message/SuperscriptMessage/SuperscriptMessage'; +import { css } from '@patternfly/react-styles'; +import type { MarkdownContentProps } from './MarkdownContent'; + +export type MarkdownRendererProps = Omit; + +const MarkdownRenderer: FunctionComponent = ({ + content, + codeBlockProps, + tableProps, + openLinkInNewTab = true, + additionalRehypePlugins = [], + additionalRemarkPlugins = [], + linkProps, + reactMarkdownProps, + remarkGfmProps, + hasNoImages = false, + isPrimary, + shouldRetainStyles +}) => { + let rehypePlugins: PluggableList = [rehypeUnwrapImages, rehypeMoveImagesOutOfParagraphs, rehypeHighlight]; + if (openLinkInNewTab) { + rehypePlugins = rehypePlugins.concat([[rehypeExternalLinks, { target: '_blank' }, rehypeSanitize]]); + } + if (additionalRehypePlugins) { + rehypePlugins.push(...additionalRehypePlugins); + } + + const disallowedElements = hasNoImages ? ['img'] : []; + if (reactMarkdownProps && reactMarkdownProps.disallowedElements) { + disallowedElements.push(...reactMarkdownProps.disallowedElements); + } + + return ( + { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ( +
+ ); + }, + p: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ( + + ); + }, + code: ({ children, ...props }) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...codeProps } = props; + return ( + + {children} + + ); + }, + h1: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + h2: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + h3: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + h4: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + h5: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + h6: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + blockquote: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ( + + ); + }, + ul: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + ol: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + li: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + // table requires node attribute for calculating headers for mobile breakpoint + table: (props) => ( + + ), + tbody: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + thead: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + tr: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + td: (props) => { + // Conflicts with Td type + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, width, ...rest } = props; + return ; + }, + th: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + img: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + }, + a: (props) => { + // node is just the details of the document structure - not needed + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ( + // some a types conflict with ButtonProps, but it's ok because we are using an a tag + // there are too many to handle manually + + {props.children} + + ); + }, + // used for footnotes + sup: (props) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { node, ...rest } = props; + return ; + } + }} + remarkPlugins={[[remarkGfm, { ...remarkGfmProps }], ...additionalRemarkPlugins]} + rehypePlugins={rehypePlugins} + {...reactMarkdownProps} + remarkRehypeOptions={{ + // removes sr-only class from footnote labels applied by default + footnoteLabelProperties: { className: [''] }, + // omit default ↩ text; backref icon is rendered in LinkMessage + footnoteBackContent: (_referenceIndex, rereferenceIndex) => { + if (rereferenceIndex > 1) { + return [ + { + type: 'element', + tagName: 'sup', + properties: {}, + children: [{ type: 'text', value: String(rereferenceIndex) }] + } + ]; + } + return []; + }, + ...reactMarkdownProps?.remarkRehypeOptions + }} + disallowedElements={disallowedElements} + > + {content} + + ); +}; + +export default MarkdownRenderer; diff --git a/packages/module/src/Message/Message.test.tsx b/packages/module/src/Message/Message.test.tsx index 5609e1fec..c2f97d687 100644 --- a/packages/module/src/Message/Message.test.tsx +++ b/packages/module/src/Message/Message.test.tsx @@ -8,6 +8,7 @@ import { monitorSampleAppQuickStartWithImage } from './QuickStarts/monitor-sampl import rehypeExternalLinks from '../__mocks__/rehype-external-links'; import { AlertActionLink, Button, CodeBlockAction } from '@patternfly/react-core'; import { DeepThinkingProps } from '../DeepThinking'; +import { warmupMarkdownRenderer } from '../test-utils/markdownTestUtils'; // Mock the icon components jest.mock('@patternfly/react-icons', () => ({ @@ -222,6 +223,10 @@ const checkListItemsRendered = () => { }; describe('Message', () => { + beforeAll(async () => { + await warmupMarkdownRenderer(); + }); + beforeEach(() => { jest.clearAllMocks(); }); diff --git a/packages/module/src/Message/Message.tsx b/packages/module/src/Message/Message.tsx index 3bd3fc920..355f661f7 100644 --- a/packages/module/src/Message/Message.tsx +++ b/packages/module/src/Message/Message.tsx @@ -3,7 +3,7 @@ // ============================================================================ import { forwardRef, ReactNode, useEffect, useState } from 'react'; import type { FunctionComponent, HTMLProps, MouseEvent as ReactMouseEvent, Ref } from 'react'; -import { Options } from 'react-markdown'; +import type { Options } from 'react-markdown'; import { AlertProps, Avatar, @@ -25,10 +25,8 @@ import { QuickStart, QuickstartAction } from './QuickStarts/types'; import QuickResponse from './QuickResponse/QuickResponse'; import UserFeedback, { UserFeedbackProps } from './UserFeedback/UserFeedback'; import UserFeedbackComplete, { UserFeedbackCompleteProps } from './UserFeedback/UserFeedbackComplete'; -import { TableProps } from '@patternfly/react-table'; -// see the full list of styles here: https://highlightjs.org/examples -import 'highlight.js/styles/vs2015.css'; -import { PluggableList } from 'unified'; +import type { TableProps } from '@patternfly/react-table'; +import type { PluggableList } from 'unified'; import ErrorMessage from './ErrorMessage/ErrorMessage'; import MessageInput from './MessageInput'; import ToolResponse, { ToolResponseProps } from '../ToolResponse'; diff --git a/packages/module/src/MessageBox/MessageBox.tsx b/packages/module/src/MessageBox/MessageBox.tsx index 675f87a65..2902be51a 100644 --- a/packages/module/src/MessageBox/MessageBox.tsx +++ b/packages/module/src/MessageBox/MessageBox.tsx @@ -18,9 +18,17 @@ import { WheelEventHandler } from 'react'; import JumpButton from './JumpButton'; +import { + MarkdownRendererReadyContext, + preloadMarkdownRenderer, + useIsMarkdownRendererReady +} from '../MarkdownContent/MarkdownContent'; import { ButtonProps, getResizeObserver, TooltipProps } from '@patternfly/react-core'; import { css } from '@patternfly/react-styles'; +// Start fetching the markdown chunk as soon as MessageBox enters the bundle. +preloadMarkdownRenderer(); + export interface MessageBoxProps extends HTMLProps { /** Content that can be announced, such as a new message, for screen readers */ announcement?: string; @@ -123,6 +131,8 @@ export const MessageBox = forwardRef( }: MessageBoxProps, ref: ForwardedRef ) => { + const isMarkdownReady = useIsMarkdownRendererReady(); + const [atTop, setAtTop] = useState(true); const [atBottom, setAtBottom] = useState(false); const [isOverflowing, setIsOverflowing] = useState(false); @@ -447,7 +457,9 @@ export const MessageBox = forwardRef( {...props} {...(enableSmartScroll ? { ...smartScrollHandlers } : {})} > - {children} + + {children} +
{announcement}
diff --git a/packages/module/src/ResponseActions/ResponseActions.test.tsx b/packages/module/src/ResponseActions/ResponseActions.test.tsx index fc698fbfc..517db22bf 100644 --- a/packages/module/src/ResponseActions/ResponseActions.test.tsx +++ b/packages/module/src/ResponseActions/ResponseActions.test.tsx @@ -3,7 +3,6 @@ import '@testing-library/jest-dom'; import ResponseActions, { ActionProps } from './ResponseActions'; import userEvent from '@testing-library/user-event'; import { RhUiExportIcon, RhMicronsInformationFillIcon, RhUiRedoIcon } from '@patternfly/react-icons'; -import Message from '../Message'; // Mock the icon components jest.mock('@patternfly/react-icons', () => ({ @@ -116,18 +115,16 @@ describe('ResponseActions', () => { }); }); it('should handle click outside of group of buttons correctly', async () => { - // using message just so we have something outside the group that's rendered render( - +
+ +
Outside
+
); const goodBtn = screen.getByRole('button', { name: 'Good response' }); const badBtn = screen.getByRole('button', { name: 'Bad response' }); @@ -145,9 +142,8 @@ describe('ResponseActions', () => { 'pf-chatbot__button--response-action-clicked' ); expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked'); - await userEvent.click( - screen.getByText("I updated your account with those settings. You're ready to set up your first dashboard!") - ); + + await userEvent.click(screen.getByTestId('outside')); expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked'); expect(badBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked'); }); @@ -343,27 +339,28 @@ describe('ResponseActions', () => { // we are testing for the reverse case already above it('should not deselect when clicking outside when persistActionSelection is true', async () => { + const user = userEvent.setup(); + render( - +
+ +
Outside
+
); const goodBtn = screen.getByRole('button', { name: 'Good response' }); - await userEvent.click(goodBtn); + await user.click(goodBtn); expect(screen.getByRole('button', { name: 'Good response recorded' })).toHaveClass( 'pf-chatbot__button--response-action-clicked' ); - await userEvent.click(screen.getByText('Test content')); + await user.click(screen.getByTestId('outside')); expect(screen.getByRole('button', { name: 'Good response recorded' })).toHaveClass( 'pf-chatbot__button--response-action-clicked' @@ -371,15 +368,13 @@ describe('ResponseActions', () => { }); it('should switch selection to another button when persistActionSelection is true', async () => { + const user = userEvent.setup(); + render( - @@ -387,38 +382,37 @@ describe('ResponseActions', () => { const goodBtn = screen.getByRole('button', { name: 'Good response' }); const badBtn = screen.getByRole('button', { name: 'Bad response' }); - await userEvent.click(goodBtn); + await user.click(goodBtn); expect(goodBtn).toHaveClass('pf-chatbot__button--response-action-clicked'); - await userEvent.click(badBtn); + await user.click(badBtn); expect(badBtn).toHaveClass('pf-chatbot__button--response-action-clicked'); expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked'); }); it('should toggle off when clicking the same button when persistActionSelection is true', async () => { + const user = userEvent.setup(); + render( - ); const goodBtn = screen.getByRole('button', { name: 'Good response' }); - await userEvent.click(goodBtn); + await user.click(goodBtn); expect(goodBtn).toHaveClass('pf-chatbot__button--response-action-clicked'); - await userEvent.click(goodBtn); + await user.click(goodBtn); expect(goodBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked'); }); it('should work with custom actions when persistActionSelection is true', async () => { + const user = userEvent.setup(); const actions = { positive: { 'data-testid': 'positive', onClick: jest.fn() }, negative: { 'data-testid': 'negative', onClick: jest.fn() }, @@ -433,10 +427,10 @@ describe('ResponseActions', () => { render(); const customBtn = screen.getByTestId('custom'); - await userEvent.click(customBtn); + await user.click(customBtn); expect(customBtn).toHaveClass('pf-chatbot__button--response-action-clicked'); - await userEvent.click(customBtn); + await user.click(customBtn); expect(customBtn).not.toHaveClass('pf-chatbot__button--response-action-clicked'); }); diff --git a/packages/module/src/ToolCall/ToolCall.test.tsx b/packages/module/src/ToolCall/ToolCall.test.tsx index fa418d78f..525aa2f08 100644 --- a/packages/module/src/ToolCall/ToolCall.test.tsx +++ b/packages/module/src/ToolCall/ToolCall.test.tsx @@ -2,6 +2,7 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import '@testing-library/jest-dom'; import ToolCall from './ToolCall'; +import { expectBoldMarkdownText } from '../test-utils/markdownTestUtils'; describe('ToolCall', () => { const defaultProps = { @@ -233,11 +234,10 @@ describe('ToolCall', () => { expect(screen.queryByText('Expandable Content')).not.toBeVisible(); }); - it('should render titleText as markdown when isTitleMarkdown is true', () => { + it('should render titleText as markdown when isTitleMarkdown is true', async () => { const titleText = '**Bold title**'; - const { container } = render(); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold title')).toBeTruthy(); + render(); + await expectBoldMarkdownText('Bold title'); }); it('should not render titleText as markdown when isTitleMarkdown is false', () => { @@ -249,12 +249,9 @@ describe('ToolCall', () => { it('should render expandableContent as markdown when isExpandableContentMarkdown is true', async () => { const user = userEvent.setup(); const expandableContent = '**Bold expandable content**'; - const { container } = render( - - ); + render(); await user.click(screen.getByRole('button', { name: defaultProps.titleText })); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold expandable content')).toBeTruthy(); + await expectBoldMarkdownText('Bold expandable content'); }); it('should not render expandableContent as markdown when isExpandableContentMarkdown is false', async () => { diff --git a/packages/module/src/ToolResponse/ToolResponse.test.tsx b/packages/module/src/ToolResponse/ToolResponse.test.tsx index 6737363a3..345c8cdd4 100644 --- a/packages/module/src/ToolResponse/ToolResponse.test.tsx +++ b/packages/module/src/ToolResponse/ToolResponse.test.tsx @@ -2,6 +2,7 @@ import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import '@testing-library/jest-dom'; import ToolResponse from './ToolResponse'; +import { expectBoldMarkdownText } from '../test-utils/markdownTestUtils'; describe('ToolResponse', () => { const defaultProps = { @@ -150,13 +151,10 @@ describe('ToolResponse', () => { expect(screen.getByText(defaultProps.cardBody)).not.toBeVisible(); }); - it('should render toggleContent as markdown when isToggleContentMarkdown is true', () => { + it('should render toggleContent as markdown when isToggleContentMarkdown is true', async () => { const toggleContent = '**Bold toggle**'; - const { container } = render( - - ); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold toggle')).toBeTruthy(); + render(); + await expectBoldMarkdownText('Bold toggle'); }); it('should not render toggleContent as markdown when isToggleContentMarkdown is false', () => { @@ -165,11 +163,10 @@ describe('ToolResponse', () => { expect(screen.getByText('**Bold toggle**')).toBeTruthy(); }); - it('should render subheading as markdown when isSubheadingMarkdown is true', () => { + it('should render subheading as markdown when isSubheadingMarkdown is true', async () => { const subheading = '**Bold subheading**'; - const { container } = render(); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold subheading')).toBeTruthy(); + render(); + await expectBoldMarkdownText('Bold subheading'); }); it('should not render subheading as markdown when isSubheadingMarkdown is false', () => { @@ -178,11 +175,10 @@ describe('ToolResponse', () => { expect(screen.getByText('**Bold subheading**')).toBeTruthy(); }); - it('should render body as markdown when isBodyMarkdown is true', () => { + it('should render body as markdown when isBodyMarkdown is true', async () => { const body = '**Bold body**'; - const { container } = render(); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold body')).toBeTruthy(); + render(); + await expectBoldMarkdownText('Bold body'); }); it('should not render body as markdown when isBodyMarkdown is false', () => { @@ -191,11 +187,10 @@ describe('ToolResponse', () => { expect(screen.getByText('**Bold body**')).toBeTruthy(); }); - it('should render cardTitle as markdown when isCardTitleMarkdown is true', () => { + it('should render cardTitle as markdown when isCardTitleMarkdown is true', async () => { const cardTitle = '**Bold card title**'; - const { container } = render(); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold card title')).toBeTruthy(); + render(); + await expectBoldMarkdownText('Bold card title'); }); it('should not render cardTitle as markdown when isCardTitleMarkdown is false', () => { @@ -204,11 +199,10 @@ describe('ToolResponse', () => { expect(screen.getByText('**Bold card title**')).toBeTruthy(); }); - it('should render cardBody as markdown when isCardBodyMarkdown is true', () => { + it('should render cardBody as markdown when isCardBodyMarkdown is true', async () => { const cardBody = '**Bold card body**'; - const { container } = render(); - expect(container.querySelector('strong')).toBeTruthy(); - expect(screen.getByText('Bold card body')).toBeTruthy(); + render(); + await expectBoldMarkdownText('Bold card body'); }); it('should not render cardBody as markdown when isCardBodyMarkdown is false', () => { diff --git a/packages/module/src/index.ts b/packages/module/src/index.ts index e8340c8b5..211200066 100644 --- a/packages/module/src/index.ts +++ b/packages/module/src/index.ts @@ -1,8 +1,5 @@ // this file is autogenerated by generate-index.js, modifying it manually will have no effect -export { default as AttachmentEdit } from './AttachmentEdit'; -export * from './AttachmentEdit'; - export { default as AttachMenu } from './AttachMenu'; export * from './AttachMenu'; @@ -36,9 +33,6 @@ export * from './ChatbotToggle'; export { default as ChatbotWelcomePrompt } from './ChatbotWelcomePrompt'; export * from './ChatbotWelcomePrompt'; -export { default as CodeModal } from './CodeModal'; -export * from './CodeModal'; - export { default as Compare } from './Compare'; export * from './Compare'; @@ -78,9 +72,6 @@ export * from './MessageDivider'; export { default as Onboarding } from './Onboarding'; export * from './Onboarding'; -export { default as PreviewAttachment } from './PreviewAttachment'; -export * from './PreviewAttachment'; - export { default as ResponseActions } from './ResponseActions'; export * from './ResponseActions'; @@ -104,6 +95,3 @@ export * from './ToolCall'; export { default as ToolResponse } from './ToolResponse'; export * from './ToolResponse'; - -export { default as tracking } from './tracking'; -export * from './tracking'; diff --git a/packages/module/src/test-utils/markdownTestUtils.ts b/packages/module/src/test-utils/markdownTestUtils.ts new file mode 100644 index 000000000..9ed3d8502 --- /dev/null +++ b/packages/module/src/test-utils/markdownTestUtils.ts @@ -0,0 +1,21 @@ +import { createElement } from 'react'; +import { render, screen } from '@testing-library/react'; +import MarkdownContent, { + preloadMarkdownRenderer, + whenMarkdownRendererReady +} from '../MarkdownContent/MarkdownContent'; + +/** Preloads and warms the lazy MarkdownRenderer so synchronous getByText assertions work. */ +export async function warmupMarkdownRenderer() { + preloadMarkdownRenderer(); + await whenMarkdownRendererReady(); + const { unmount } = render(createElement(MarkdownContent, { content: '.' })); + await screen.findByText('.', {}, { timeout: 10000 }); + unmount(); +} + +/** Waits for lazy-loaded markdown to render and asserts bold text. */ +export async function expectBoldMarkdownText(text: string) { + const element = await screen.findByText(text, {}, { timeout: 10000 }); + expect(element.closest('strong')).not.toBeNull(); +} diff --git a/packages/module/tsconfig.json b/packages/module/tsconfig.json index 9c6eb57dd..78443b958 100644 --- a/packages/module/tsconfig.json +++ b/packages/module/tsconfig.json @@ -69,5 +69,10 @@ "skipLibCheck": true /* Skip type checking of declaration files. */, "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ }, - "include": ["./src/*", "./src/**/*", "./cypress/**/*"] + "include": ["./src/*", "./src/**/*", "./cypress/**/*"], + "exclude": [ + "**/*.test.tsx", + "**/__mocks__/**", + "**/test-utils/**" + ] } diff --git a/packages/tree-shaking-demo/README.md b/packages/tree-shaking-demo/README.md new file mode 100644 index 000000000..7b2372a22 --- /dev/null +++ b/packages/tree-shaking-demo/README.md @@ -0,0 +1,73 @@ +# ChatBot Tree-Shaking Demo + +This package verifies that `@patternfly/chatbot` tree-shakes correctly and demonstrates the recommended import patterns for production applications. + +## Quick start + +From the repository root: + +```bash +# Build the ChatBot library first +npm run build -w @patternfly/chatbot + +# Run the analysis (builds scenarios and prints a report) +npm run analyze:tree-shaking +``` + +## Verification results + +Running the analysis against Vite 6 confirms tree-shaking is working: + +| Scenario | JS size | Icons | ChatBot components | +|----------|---------|-------|--------------------| +| ChatbotToggle only (root barrel) | ~184 KB | 4 | 1 | +| ChatbotToggle only (`dist/dynamic`) | ~184 KB | 4 | 1 | +| Multi-component UI (7 imports) | ~895 KB | 49 | 17 | + +**Key takeaway:** Root barrel and `dist/dynamic` imports tree-shake to the same size. `dist/dynamic` imports are preferred for faster builds and for components excluded from the root barrel (`CodeModal`, `PreviewAttachment`, `AttachmentEdit`). + +## Scenarios + +### 1. Dynamic per-component import (recommended) + +```tsx +import ChatbotToggle from '@patternfly/chatbot/dist/dynamic/ChatbotToggle'; +import '@patternfly/react-core/dist/styles/base.css'; +import '@patternfly/chatbot/dist/css/main.css'; +``` + +### 2. Root barrel import + +```tsx +import { ChatbotToggle } from '@patternfly/chatbot'; +``` + +Named imports from the root barrel tree-shake correctly when your bundler respects the package `sideEffects` field. + +## Correct setup checklist + +1. Import components from `dist/dynamic/` or the root barrel +2. Import CSS once from: `@patternfly/chatbot/dist/css/main.css` and `@patternfly/react-core/dist/styles/base.css` +3. Import Monaco-related components from `dist/dynamic/` only + +## Migration: root barrel changes + +`CodeModal`, `PreviewAttachment`, `AttachmentEdit`, and `tracking` are no longer exported from the root barrel. Update imports as follows: + +| Module | Before | After | +|--------|--------|-------| +| `CodeModal` | `import { CodeModal } from '@patternfly/chatbot'` | `import CodeModal from '@patternfly/chatbot/dist/dynamic/CodeModal'` | +| `PreviewAttachment` | `import { PreviewAttachment } from '@patternfly/chatbot'` | `import PreviewAttachment from '@patternfly/chatbot/dist/dynamic/PreviewAttachment'` | +| `AttachmentEdit` | `import { AttachmentEdit } from '@patternfly/chatbot'` | `import AttachmentEdit from '@patternfly/chatbot/dist/dynamic/AttachmentEdit'` | +| `tracking` | `import { getTrackingProviders } from '@patternfly/chatbot'` | `import { getTrackingProviders } from '@patternfly/chatbot/dist/dynamic/tracking'` | + + +## Files + +``` +src/barrel/ ChatbotToggle via root barrel +src/dynamic/ ChatbotToggle via dist/dynamic import +src/full/ Multi-component ChatBot UI +scripts/ Build and analysis tooling +dist/ Output bundles + stats.html treemaps +``` diff --git a/packages/tree-shaking-demo/index.html b/packages/tree-shaking-demo/index.html new file mode 100644 index 000000000..9909f6160 --- /dev/null +++ b/packages/tree-shaking-demo/index.html @@ -0,0 +1,12 @@ + + + + + + ChatBot Tree-Shaking Demo + + +
+ + + diff --git a/packages/tree-shaking-demo/package.json b/packages/tree-shaking-demo/package.json new file mode 100644 index 000000000..6b4dcd2ef --- /dev/null +++ b/packages/tree-shaking-demo/package.json @@ -0,0 +1,30 @@ +{ + "name": "@patternfly/chatbot-tree-shaking-demo", + "private": true, + "version": "0.0.0", + "description": "Demonstrates tree-shaking with @patternfly/chatbot and PatternFly dependencies", + "type": "module", + "scripts": { + "dev": "vite --mode full", + "dev:minimal": "vite --mode minimal", + "dev:barrel": "vite --mode barrel", + "build": "node scripts/build-and-analyze.mjs", + "build:minimal": "vite build --mode minimal", + "build:barrel": "vite build --mode barrel", + "analyze": "node scripts/build-and-analyze.mjs" + }, + "dependencies": { + "@patternfly/chatbot": "*", + "@patternfly/react-core": "^6.6.0", + "@patternfly/react-icons": "^6.6.0", + "react": "^18", + "react-dom": "^18" + }, + "devDependencies": { + "@types/react": "^18.2.61", + "@types/react-dom": "^18.2.19", + "rollup-plugin-visualizer": "^5.14.0", + "typescript": "^5.3.3", + "vite": "^6.2.0" + } +} diff --git a/packages/tree-shaking-demo/scripts/build-and-analyze.mjs b/packages/tree-shaking-demo/scripts/build-and-analyze.mjs new file mode 100644 index 000000000..0d75f5648 --- /dev/null +++ b/packages/tree-shaking-demo/scripts/build-and-analyze.mjs @@ -0,0 +1,239 @@ +#!/usr/bin/env node +/* eslint-disable no-console */ +/** + * Builds tree-shaking scenarios and reports bundle metrics from source maps. + */ +import { execSync } from 'node:child_process'; +import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs'; +import { join, resolve, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const demoRoot = resolve(__dirname, '..'); + +const scenarios = [ + { id: 'barrel', label: 'ChatbotToggle (root barrel import, source alias)' }, + { id: 'dynamic', label: 'ChatbotToggle (dist/dynamic import, source alias)' }, + { id: 'full', label: 'Multi-component ChatBot UI (dist/dynamic import, source alias)' } +]; + +function ensureChatbotBuilt() { + const distIndex = resolve(demoRoot, '../module/dist/esm/index.js'); + if (!existsSync(distIndex)) { + console.error( + '\n@patternfly/chatbot dist/ is missing. Build the library before running analysis:\n\n npm run build -w @patternfly/chatbot\n' + ); + process.exit(1); + } +} + +function formatBytes(bytes) { + if (bytes < 1024) { + return `${bytes} B`; + } + if (bytes < 1024 * 1024) { + return `${(bytes / 1024).toFixed(1)} KB`; + } + return `${(bytes / (1024 * 1024)).toFixed(2)} MB`; +} + +function collectJsFiles(dir) { + const files = []; + if (!existsSync(dir)) { + return files; + } + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const fullPath = join(dir, entry.name); + if (entry.isDirectory()) { + files.push(...collectJsFiles(fullPath)); + } else if (entry.name.endsWith('.js') && !entry.name.endsWith('.map')) { + files.push(fullPath); + } + } + return files; +} + +function collectSourceMapFiles(dir) { + const files = []; + if (!existsSync(dir)) { + return files; + } + for (const entry of readdirSync(dir, { withFileTypes: true })) { + const fullPath = join(dir, entry.name); + if (entry.isDirectory()) { + files.push(...collectSourceMapFiles(fullPath)); + } else if (entry.name.endsWith('.js.map')) { + files.push(fullPath); + } + } + return files; +} + +function analyzeFromSources(sources) { + const uniqueSources = [...new Set(sources)]; + + const iconSources = uniqueSources.filter((s) => s.includes('react-icons') && s.includes('/icons/')); + const uniqueIcons = [...new Set(iconSources.map((s) => s.split('/icons/').pop()))]; + + const chatbotSources = uniqueSources.filter( + (s) => (s.includes('/chatbot/') || s.includes('/module/')) && (s.includes('/dist/esm/') || s.includes('/src/')) + ); + const uniqueComponents = [ + ...new Set( + chatbotSources + .map((s) => { + const match = s.match(/\/(?:dist\/esm|src)\/([A-Z][a-zA-Z]+)\//); + return match ? match[1] : null; + }) + .filter(Boolean) + ) + ]; + + const monacoSources = uniqueSources.filter((s) => s.includes('monaco')); + const reactCoreSources = uniqueSources.filter((s) => s.includes('react-core') && s.includes('/components/')); + const reactCoreComponents = [ + ...new Set( + reactCoreSources + .map((s) => { + const match = s.match(/\/components\/([^/]+)/); + return match ? match[1] : null; + }) + .filter(Boolean) + ) + ].sort(); + + return { + totalSources: uniqueSources.length, + iconCount: uniqueIcons.length, + icons: uniqueIcons.sort(), + chatbotComponentCount: uniqueComponents.length, + chatbotComponents: uniqueComponents.sort(), + monacoRefs: monacoSources.length, + reactCoreComponentCount: reactCoreComponents.length, + reactCoreComponents + }; +} + +function analyzeBundle(scenario) { + const distDir = join(demoRoot, 'dist', scenario.id); + const jsFiles = collectJsFiles(distDir); + const initialFiles = jsFiles.filter((file) => file.includes('/assets/main-')); + const asyncFiles = jsFiles.filter((file) => !file.includes('/assets/main-')); + let totalSize = 0; + let initialSize = 0; + let asyncSize = 0; + for (const file of jsFiles) { + const size = statSync(file).size; + totalSize += size; + if (initialFiles.includes(file)) { + initialSize += size; + } else { + asyncSize += size; + } + } + + const mapFiles = collectSourceMapFiles(distDir); + const allSources = []; + const initialSources = []; + const asyncSources = []; + for (const mapFile of mapFiles) { + const map = JSON.parse(readFileSync(mapFile, 'utf8')); + const sources = map.sources ?? []; + allSources.push(...sources); + if (mapFile.includes('/assets/main-')) { + initialSources.push(...sources); + } else { + asyncSources.push(...sources); + } + } + const mapAnalysis = mapFiles.length ? analyzeFromSources(allSources) : null; + const initialAnalysis = mapFiles.length ? analyzeFromSources(initialSources) : null; + const asyncAnalysis = mapFiles.length ? analyzeFromSources(asyncSources) : null; + + return { + id: scenario.id, + label: scenario.label, + jsFileCount: jsFiles.length, + initialFileCount: initialFiles.length, + asyncFileCount: asyncFiles.length, + totalSize, + initialSize, + asyncSize, + ...mapAnalysis, + initial: initialAnalysis, + async: asyncAnalysis + }; +} + +function printReport(results) { + console.log('\n╔══════════════════════════════════════════════════════════════╗'); + console.log('║ ChatBot Tree-Shaking Verification Report ║'); + console.log('╚══════════════════════════════════════════════════════════════╝\n'); + + for (const result of results) { + console.log(`── ${result.label} ──`); + console.log(` Bundle size (JS): ${formatBytes(result.totalSize)}`); + console.log( + ` Initial JS: ${formatBytes(result.initialSize)} (${result.initialFileCount} chunk${result.initialFileCount === 1 ? '' : 's'})` + ); + console.log( + ` Async JS: ${formatBytes(result.asyncSize)} (${result.asyncFileCount} chunk${result.asyncFileCount === 1 ? '' : 's'})` + ); + console.log(` Source modules: ${result.totalSources ?? 'n/a'}`); + console.log(` PatternFly icons: ${result.iconCount ?? 'n/a'}`); + console.log(` ChatBot components: ${result.chatbotComponentCount ?? 'n/a'}`); + console.log(` React-Core groups: ${result.reactCoreComponentCount ?? 'n/a'}`); + if (result.initial) { + console.log( + ` Initial payload only: ${result.initial.chatbotComponentCount} ChatBot comps, ${result.initial.iconCount} icons, ${result.initial.reactCoreComponentCount} react-core groups` + ); + if (result.initial.reactCoreComponentCount > 0 && result.initial.reactCoreComponentCount <= 50) { + console.log(` Initial react-core: ${result.initial.reactCoreComponents.join(', ')}`); + } + } + if (result.async && result.async.totalSources > 0) { + console.log( + ` Async chunks only: ${result.async.chatbotComponentCount} ChatBot comps, ${result.async.iconCount} icons, ${result.async.reactCoreComponentCount} react-core groups` + ); + if (result.async.reactCoreComponentCount > 0 && result.async.reactCoreComponentCount <= 50) { + console.log(` Async react-core: ${result.async.reactCoreComponents.join(', ')}`); + } + } + if (result.reactCoreComponentCount > 0 && result.reactCoreComponentCount <= 50) { + console.log(` All react-core: ${result.reactCoreComponents.join(', ')}`); + } + if (result.monacoRefs > 0) { + console.log(` Monaco editor refs: ${result.monacoRefs} ⚠`); + } + if (result.iconCount > 0 && result.iconCount <= 30) { + console.log(` Icons: ${result.icons.join(', ')}`); + } + if (result.chatbotComponentCount > 0 && result.chatbotComponentCount <= 20) { + console.log(` Components: ${result.chatbotComponents.join(', ')}`); + } + console.log(''); + } + + console.log('Interactive treemap reports:'); + for (const { id } of scenarios) { + console.log(` dist/${id}/stats.html`); + } + console.log(''); +} + +console.log('Building tree-shaking demo scenarios...\n'); + +ensureChatbotBuilt(); + +for (const scenario of scenarios) { + process.stdout.write(` Building "${scenario.id}"...`); + execSync(`vite build --mode ${scenario.id}`, { + cwd: demoRoot, + // Do not pipe stdout — vite can emit enough build output to fill the pipe buffer and deadlock. + stdio: ['inherit', 'ignore', 'inherit'] + }); + console.log(' done'); +} + +const results = scenarios.map(analyzeBundle); +printReport(results); diff --git a/packages/tree-shaking-demo/src/barrel/App.tsx b/packages/tree-shaking-demo/src/barrel/App.tsx new file mode 100644 index 000000000..f142e8962 --- /dev/null +++ b/packages/tree-shaking-demo/src/barrel/App.tsx @@ -0,0 +1,10 @@ +/** + * Root barrel import pattern. + */ +import { ChatbotToggle } from '@patternfly/chatbot'; +import '@patternfly/react-core/dist/styles/base.css'; +import '@patternfly/chatbot/dist/css/main.css'; + +export default function App() { + return undefined} />; +} diff --git a/packages/tree-shaking-demo/src/barrel/main.tsx b/packages/tree-shaking-demo/src/barrel/main.tsx new file mode 100644 index 000000000..e0138a10c --- /dev/null +++ b/packages/tree-shaking-demo/src/barrel/main.tsx @@ -0,0 +1,4 @@ +import { createRoot } from 'react-dom/client'; +import App from './App'; + +createRoot(document.getElementById('root')!).render(); diff --git a/packages/tree-shaking-demo/src/dynamic/App.tsx b/packages/tree-shaking-demo/src/dynamic/App.tsx new file mode 100644 index 000000000..17113e3b0 --- /dev/null +++ b/packages/tree-shaking-demo/src/dynamic/App.tsx @@ -0,0 +1,14 @@ +/** + * Dynamic per-component import via dist/dynamic. + */ +import ChatbotToggle from '@patternfly/chatbot/dist/dynamic/ChatbotToggle'; +import '@patternfly/react-core/dist/styles/base.css'; +import '@patternfly/chatbot/dist/css/main.css'; + +export default function App() { + return ( + <> + undefined} /> + + ); +} diff --git a/packages/tree-shaking-demo/src/dynamic/main.tsx b/packages/tree-shaking-demo/src/dynamic/main.tsx new file mode 100644 index 000000000..e0138a10c --- /dev/null +++ b/packages/tree-shaking-demo/src/dynamic/main.tsx @@ -0,0 +1,4 @@ +import { createRoot } from 'react-dom/client'; +import App from './App'; + +createRoot(document.getElementById('root')!).render(); diff --git a/packages/tree-shaking-demo/src/full/App.tsx b/packages/tree-shaking-demo/src/full/App.tsx new file mode 100644 index 000000000..ee679e649 --- /dev/null +++ b/packages/tree-shaking-demo/src/full/App.tsx @@ -0,0 +1,42 @@ +/** + * This is a minimal implementation of a ChatBot that goes beyond the minimal toggle examples + */ +import { useState } from 'react'; +import Chatbot from '@patternfly/chatbot/dist/dynamic/Chatbot'; +import ChatbotContent from '@patternfly/chatbot/dist/dynamic/ChatbotContent'; +import ChatbotFooter from '@patternfly/chatbot/dist/dynamic/ChatbotFooter'; +import ChatbotToggle from '@patternfly/chatbot/dist/dynamic/ChatbotToggle'; +import Message from '@patternfly/chatbot/dist/dynamic/Message'; +import MessageBox from '@patternfly/chatbot/dist/dynamic/MessageBox'; +import MessageBar from '@patternfly/chatbot/dist/dynamic/MessageBar'; +import '@patternfly/react-core/dist/styles/base.css'; +import '@patternfly/chatbot/dist/css/main.css'; + +export default function App() { + const [isVisible, setIsVisible] = useState(true); + + const handleSend = (message: string | number) => { + // eslint-disable-next-line no-console + console.log(message); + }; + + return ( + <> + + + + + + + + + + + setIsVisible(!isVisible)} + /> + + ); +} diff --git a/packages/tree-shaking-demo/src/full/main.tsx b/packages/tree-shaking-demo/src/full/main.tsx new file mode 100644 index 000000000..e0138a10c --- /dev/null +++ b/packages/tree-shaking-demo/src/full/main.tsx @@ -0,0 +1,4 @@ +import { createRoot } from 'react-dom/client'; +import App from './App'; + +createRoot(document.getElementById('root')!).render(); diff --git a/packages/tree-shaking-demo/src/vite-env.d.ts b/packages/tree-shaking-demo/src/vite-env.d.ts new file mode 100644 index 000000000..0229e234b --- /dev/null +++ b/packages/tree-shaking-demo/src/vite-env.d.ts @@ -0,0 +1,6 @@ +// + +declare module '*.css' { + const content: string; + export default content; +} diff --git a/packages/tree-shaking-demo/tsconfig.json b/packages/tree-shaking-demo/tsconfig.json new file mode 100644 index 000000000..42e052169 --- /dev/null +++ b/packages/tree-shaking-demo/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "strict": true + }, + "include": ["src"] +} diff --git a/packages/tree-shaking-demo/vite.config.ts b/packages/tree-shaking-demo/vite.config.ts new file mode 100644 index 000000000..65e7a2fde --- /dev/null +++ b/packages/tree-shaking-demo/vite.config.ts @@ -0,0 +1,35 @@ +import { defineConfig } from 'vite'; +import { resolve } from 'path'; +import { visualizer } from 'rollup-plugin-visualizer'; + +// All scenarios alias to monorepo source for fast iteration. +const SOURCE_ALIAS_MODES = new Set(['barrel', 'dynamic', 'full']); +const CHATBOT_SOURCE_ALIAS = { + '@patternfly/chatbot': resolve(__dirname, '../module') +}; + +export default defineConfig(({ mode }) => ({ + plugins: [ + visualizer({ + filename: resolve(__dirname, `dist/${mode}/stats.html`), + gzipSize: true, + brotliSize: true, + open: false + }) + ], + resolve: { + alias: SOURCE_ALIAS_MODES.has(mode) ? CHATBOT_SOURCE_ALIAS : {} + }, + build: { + outDir: `dist/${mode}`, + emptyOutDir: true, + sourcemap: true, + rollupOptions: { + input: resolve(__dirname, `src/${mode}/main.tsx`), + output: { + entryFileNames: 'assets/[name]-[hash].js', + chunkFileNames: 'assets/[name]-[hash].js' + } + } + } +}));