diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index ca58d3e7c..a5d9e77d1 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -330,7 +330,9 @@ jobs:
run: playwright install chromium
- name: Run solara server (pyinstaller)
- run: pyinstaller/minimal/dist/solara/solara --port 18765 &
+ # serve the app bundle that this run built and linked (or copied) above, not the published one
+ # from the CDN, which lacks the chunk files of a new frontend until its npm release
+ run: SOLARA_ASSETS_PROXY_CACHE_DIR="$(python -c 'import sys; sys.stdout.write(sys.prefix)')/share/solara/cdn" pyinstaller/minimal/dist/solara/solara --port 18765 &
- name: Wait for Solara server to get online
run: |
@@ -615,6 +617,70 @@ jobs:
path: ./**/${{ env.LOCK_FILE_LOCATION }}
include-hidden-files: true
+ # Page load benchmark: prints the numbers in the job summary and uploads the JSON.
+ # Timings never fail this job (no thresholds yet), keep it out of the required checks,
+ # and out of update-ci-package-locks/release: it only reads the integration test locks.
+ benchmark:
+ needs: [build]
+ timeout-minutes: 20
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ vue: ["2", "3"]
+ include:
+ - vue: "2"
+ lock: .ci-package-locks/integration/osubuntu-python3.10-ipywidgets8.txt
+ - vue: "3"
+ lock: .ci-package-locks/integration-vue3/osubuntu-ipywidgets8.txt
+
+ steps:
+ - uses: actions/checkout@v6
+
+ - name: Set up Python 3.10
+ uses: actions/setup-python@v6
+ with:
+ python-version: "3.10"
+
+ - uses: actions/download-artifact@v6
+ with:
+ name: solara-builds
+
+ - name: Link solara app packages
+ run: |
+ (cd packages/solara-vuetify-app; npm run devlink)
+ (cd packages/solara-vuetify3-app; npm run devlink)
+
+ - name: Install
+ run: |
+ command -v uv >/dev/null || pip install uv
+ uv pip install --system -r ${{ matrix.lock }} \
+ `echo dist/*.whl`[all] \
+ `echo packages/solara-server/dist/*.whl`[all] \
+ `echo packages/pytest-ipywidgets/dist/*.whl`[all,ipywidgets8]
+
+ - name: Install and verify ipyvuetify 3
+ if: matrix.vue == '3'
+ run: |
+ pip install --pre "ipyvue>=3.0.0a1" "ipyvuetify>=3.0.0a1"
+ python -c "import ipyvuetify, solara.util; print('ipyvuetify', ipyvuetify.__version__); assert solara.util.IPYVUETIFY_V3"
+
+ - name: Install playwright
+ run: playwright install chromium
+
+ - name: Test the benchmark script
+ run: pytest tests/benchmark -v --timeout=120
+
+ - name: Benchmark
+ run: python -m tests.benchmark.bench --configs all --out bench-results/vue${{ matrix.vue }}.json
+
+ - name: Upload benchmark results
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: benchmark-vue${{ matrix.vue }}
+ path: bench-results
+
unit-test:
needs: [build]
runs-on: ${{ matrix.os }}-latest
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 84cbaec29..5aafcc2a9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -21,6 +21,8 @@ repos:
hooks:
- id: codespell
files: ^.*\.(py|md|yaml|js|ts|ipynb)$
+ # vendored minified file
+ exclude: ^solara/server/static/require\.min\.js$
args: ["--skip=**/solara_portal/**"]
additional_dependencies:
- tomli
diff --git a/packages/solara-vuetify-app/.bumpversion.cfg b/packages/solara-vuetify-app/.bumpversion.cfg
index a55cc1e75..ea197b9f5 100644
--- a/packages/solara-vuetify-app/.bumpversion.cfg
+++ b/packages/solara-vuetify-app/.bumpversion.cfg
@@ -8,8 +8,12 @@ message = Bump version solara-vuetify-app: {current_version} → {new_version}
[bumpversion:file:package.json]
-[bumpversion:file:../../solara/server/templates/solara.html.j2]
+[bumpversion:file:../../solara/server/frontend_assets.py]
+search = SOLARA_VUETIFY_APP_VERSION = "{current_version}"
+replace = SOLARA_VUETIFY_APP_VERSION = "{new_version}"
[bumpversion:file:../../release.sh]
[bumpversion:file:../solara-assets/hatch_build.py]
+search = ["@widgetti/solara-vuetify-app", "{current_version}"]
+replace = ["@widgetti/solara-vuetify-app", "{new_version}"]
diff --git a/packages/solara-vuetify-app/package-lock.json b/packages/solara-vuetify-app/package-lock.json
index e6c81bc44..ba3339aa0 100644
--- a/packages/solara-vuetify-app/package-lock.json
+++ b/packages/solara-vuetify-app/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@widgetti/solara-vuetify-app",
- "version": "10.0.3",
+ "version": "10.1.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@widgetti/solara-vuetify-app",
- "version": "10.0.3",
+ "version": "10.1.1",
"license": "MIT",
"dependencies": {
"@mariobuikhuizen/vue-compiler-addon": "^2.6.10-alpha.2",
@@ -20,9 +20,11 @@
},
"devDependencies": {
"css-loader": "^6.9.1",
+ "css-minimizer-webpack-plugin": "^7.0.4",
"file-loader": "^6.2.0",
"mini-css-extract-plugin": "^2.7.7",
"style-loader": "^3.3.4",
+ "terser-webpack-plugin": "^5.6.1",
"webpack": "^5.90.0",
"webpack-bundle-analyzer": "^4.10.1",
"webpack-cli": "^5.1.4"
@@ -39,6 +41,7 @@
"@jupyter-widgets/controls8": "npm:@jupyter-widgets/controls@^5.0.1",
"@jupyter-widgets/jupyterlab-manager": "^3.1.7",
"@jupyter-widgets/jupyterlab-manager8": "npm:@jupyter-widgets/jupyterlab-manager@^5.0.3",
+ "@jupyter-widgets/output": "^4.1.5",
"@jupyterlab/application": "^3.6.7",
"@jupyterlab/apputils": "^3.6.7",
"@jupyterlab/coreutils": "^5.6.7",
@@ -55,7 +58,8 @@
"@lumino/signaling": "^1.11.1",
"@lumino/virtualdom": "^1.14.3",
"@lumino/widgets": "^1.37.2",
- "katex": "^0.16.9"
+ "katex": "^0.16.9",
+ "sanitize-html": "^2.11.0"
},
"devDependencies": {
"npm-run-all": "^4.1.5",
@@ -71,6 +75,7 @@
"@jupyter-widgets/base": "npm:@jupyter-widgets/base@^6.0.6",
"@jupyter-widgets/controls": "npm:@jupyter-widgets/controls@^5.0.1",
"@jupyter-widgets/jupyterlab-manager": "npm:@jupyter-widgets/jupyterlab-manager@^5.0.3",
+ "@jupyter-widgets/output": "^6.0.6",
"@jupyterlab/application": "^3.6.7",
"@jupyterlab/apputils": "^3.6.7",
"@jupyterlab/coreutils": "^5.6.7",
@@ -88,13 +93,21 @@
"@lumino/virtualdom": "^1.14.3",
"@lumino/widgets": "^1.37.2",
"katex": "^0.16.9",
- "patch-package": "^8.0.0"
+ "patch-package": "^8.0.0",
+ "sanitize-html": "^2.11.0"
},
"devDependencies": {
"npm-run-all": "^4.1.5",
"typescript": "~5.3.3"
}
},
+ "node_modules/@colordx/core": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@colordx/core/-/core-5.8.0.tgz",
+ "integrity": "sha512-cG0QJAO6VkaRUlIb0zOzX9gfJgs1pjoOL9gZ/PK1kfvBs0GCkADu5oQh6gPxXgQnZ3gV575h+lQRC0NlMDTclA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@discoveryjs/json-ext": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -104,59 +117,97 @@
"node": ">=10.0.0"
}
},
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "node_modules/@jest/pattern": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.5.0.tgz",
+ "integrity": "sha512-HdNQYSdRTEBNrginaqzQtTjG0HRMfrra/z6Ok7uL3S87vSlarIVohEsJsSj5edu3MiHoHjAkvPROz5ZjoKai+w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@types/node": "*",
+ "jest-regex-util": "30.5.0"
},
"engines": {
- "node": ">=6.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
- "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "node_modules/@jest/schemas": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz",
+ "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.34.0"
+ },
"engines": {
- "node": ">=6.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "node_modules/@jest/types": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz",
+ "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/pattern": "30.5.0",
+ "@jest/schemas": "30.5.0",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "@types/istanbul-reports": "^3.0.4",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.33",
+ "chalk": "^4.1.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
- "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
- "dev": true
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
+ "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.22",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
- "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@@ -181,6 +232,13 @@
"integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==",
"dev": true
},
+ "node_modules/@sinclair/typebox": {
+ "version": "0.34.52",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz",
+ "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/eslint": {
"version": "8.56.2",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz",
@@ -207,6 +265,33 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -222,6 +307,30 @@
"undici-types": "~5.26.4"
}
},
+ "node_modules/@types/yargs": {
+ "version": "17.0.35",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
+ "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz",
+ "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/@webassemblyjs/ast": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
@@ -433,10 +542,11 @@
"dev": true
},
"node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz",
+ "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==",
"dev": true,
+ "license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -526,6 +636,35 @@
"ajv": "^6.9.1"
}
},
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.11.27",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.27.tgz",
+ "integrity": "sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -535,10 +674,17 @@
"node": "*"
}
},
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/browserslist": {
- "version": "4.22.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
- "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+ "version": "4.29.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz",
+ "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==",
"dev": true,
"funding": [
{
@@ -554,11 +700,13 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001565",
- "electron-to-chromium": "^1.4.601",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.13"
+ "baseline-browser-mapping": "^2.11.26",
+ "caniuse-lite": "^1.0.30001813",
+ "electron-to-chromium": "^1.5.439",
+ "node-releases": "^2.0.57",
+ "update-browserslist-db": "^1.3.3"
},
"bin": {
"browserslist": "cli.js"
@@ -571,12 +719,26 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/caniuse-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "caniuse-lite": "^1.0.0",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001580",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001580.tgz",
- "integrity": "sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA==",
+ "version": "1.0.30001814",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001814.tgz",
+ "integrity": "sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==",
"dev": true,
"funding": [
{
@@ -591,7 +753,38 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "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/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
},
"node_modules/chrome-trace-event": {
"version": "1.0.3",
@@ -602,6 +795,22 @@
"node": ">=6.0"
}
},
+ "node_modules/ci-info": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz",
+ "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -628,6 +837,26 @@
"node": ">=0.10.0"
}
},
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/colorette": {
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
@@ -635,10 +864,14 @@
"dev": true
},
"node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
+ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
},
"node_modules/cross-spawn": {
"version": "7.0.3",
@@ -654,6 +887,19 @@
"node": ">= 8"
}
},
+ "node_modules/css-declaration-sorter": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.4.0.tgz",
+ "integrity": "sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14 || ^16 || >=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.9"
+ }
+ },
"node_modules/css-loader": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.9.1.tgz",
@@ -680,86 +926,456 @@
"webpack": "^5.0.0"
}
},
- "node_modules/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "node_modules/css-minimizer-webpack-plugin": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-7.0.4.tgz",
+ "integrity": "sha512-2iACis+P8qdLj1tHcShtztkGhCNIRUajJj7iX0IM9a5FA0wXGwjV8Nf6+HsBjBfb4LO8TTAVoetBbM54V6f3+Q==",
"dev": true,
- "bin": {
- "cssesc": "bin/cssesc"
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "cssnano": "^7.0.4",
+ "jest-worker": "^30.0.5",
+ "postcss": "^8.4.40",
+ "schema-utils": "^4.2.0",
+ "serialize-javascript": "^6.0.2"
},
"engines": {
- "node": ">=4"
+ "node": ">= 18.12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@parcel/css": {
+ "optional": true
+ },
+ "@swc/css": {
+ "optional": true
+ },
+ "clean-css": {
+ "optional": true
+ },
+ "csso": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ }
}
},
- "node_modules/de-indent": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
- "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg=="
- },
- "node_modules/debounce": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
- "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
- "dev": true
- },
- "node_modules/duplexer": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
- "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
- "dev": true
- },
- "node_modules/electron-to-chromium": {
- "version": "1.4.645",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.645.tgz",
- "integrity": "sha512-EeS1oQDCmnYsRDRy2zTeC336a/4LZ6WKqvSaM1jLocEk5ZuyszkQtCpsqvuvaIXGOUjwtvF6LTcS8WueibXvSw==",
- "dev": true
- },
- "node_modules/emojis-list": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
- "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
"dev": true,
- "engines": {
- "node": ">= 4"
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/enhanced-resolve": {
- "version": "5.15.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
- "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+ "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
+ "ajv": "^8.0.0"
},
- "engines": {
- "node": ">=10.13.0"
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
}
},
- "node_modules/envinfo": {
- "version": "7.11.0",
- "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz",
- "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==",
+ "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"dev": true,
- "bin": {
- "envinfo": "dist/cli.js"
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
},
- "engines": {
- "node": ">=4"
+ "peerDependencies": {
+ "ajv": "^8.8.2"
}
},
- "node_modules/es-module-lexer": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
- "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
- "dev": true
- },
- "node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "node_modules/css-minimizer-webpack-plugin/node_modules/jest-worker": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.5.1.tgz",
+ "integrity": "sha512-Cbxh5v7AoLuFRmFJSM4/aHdQ68rjXvUWr716EE0Dh3I7T+T/3FgFKhOERGXHcU2Meftq9+9zxPM3TSNyI9D+HA==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@ungap/structured-clone": "^1.3.0",
+ "jest-util": "30.5.1",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.1.1"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.5.0.tgz",
+ "integrity": "sha512-zJlMCZ0cAR5p/Y4oVpRoqioDMJcGxaXRrQ/4rP4WyR84vc5z/DolXdbvXeDpTwbtocDFr2rhPqHPErDCUtz2kA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^8.20.0",
+ "ajv-formats": "^3.0.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-6.0.0.tgz",
+ "integrity": "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^7.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "nth-check": "^2.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.27.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-7.0.0.tgz",
+ "integrity": "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cssnano": {
+ "version": "7.1.9",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.1.9.tgz",
+ "integrity": "sha512-uPR75+5Dk/WJ/YSPR1/YDHdwMM9c5FsaARljfKWgeCKLKOtJ0we21xy/RcCjn53fZnD/f6yYEIZ8pu18+GnbNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-preset-default": "^7.0.17",
+ "lilconfig": "^3.1.3"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/cssnano"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/cssnano-preset-default": {
+ "version": "7.0.17",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.17.tgz",
+ "integrity": "sha512-11qO63A+czwguQFJCaTdICvbaxn0pJzz/XghLlv+OT7WyToDxAMR0Xb3/26/l0y0hQJywwNbj/SLSQlGBHE1OA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "css-declaration-sorter": "^7.2.0",
+ "cssnano-utils": "^5.0.3",
+ "postcss-calc": "^10.1.1",
+ "postcss-colormin": "^7.0.10",
+ "postcss-convert-values": "^7.0.12",
+ "postcss-discard-comments": "^7.0.8",
+ "postcss-discard-duplicates": "^7.0.4",
+ "postcss-discard-empty": "^7.0.3",
+ "postcss-discard-overridden": "^7.0.3",
+ "postcss-merge-longhand": "^7.0.7",
+ "postcss-merge-rules": "^7.0.11",
+ "postcss-minify-font-values": "^7.0.3",
+ "postcss-minify-gradients": "^7.0.5",
+ "postcss-minify-params": "^7.0.9",
+ "postcss-minify-selectors": "^7.1.2",
+ "postcss-normalize-charset": "^7.0.3",
+ "postcss-normalize-display-values": "^7.0.3",
+ "postcss-normalize-positions": "^7.0.4",
+ "postcss-normalize-repeat-style": "^7.0.4",
+ "postcss-normalize-string": "^7.0.3",
+ "postcss-normalize-timing-functions": "^7.0.3",
+ "postcss-normalize-unicode": "^7.0.9",
+ "postcss-normalize-url": "^7.0.3",
+ "postcss-normalize-whitespace": "^7.0.3",
+ "postcss-ordered-values": "^7.0.4",
+ "postcss-reduce-initial": "^7.0.9",
+ "postcss-reduce-transforms": "^7.0.3",
+ "postcss-svgo": "^7.1.3",
+ "postcss-unique-selectors": "^7.0.7"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/cssnano-utils": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.3.tgz",
+ "integrity": "sha512-ynIREMICLxkxm7e9bCR9sh75s4Q5drICi0ua1yxo5jH2XPBqSKkl4dOh4EbFqtUmnTMhRffHgYL0EKKkMjtJTg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/csso": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
+ "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "css-tree": "~2.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/css-tree": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
+ "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.0.28",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/mdn-data": {
+ "version": "2.0.28",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
+ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/de-indent": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+ "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg=="
+ },
+ "node_modules/debounce": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
+ "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
+ "dev": true
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "dev": true
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.444",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.444.tgz",
+ "integrity": "sha512-5ss/uJfoDYDHT0lfJzT6FbcskIzROIOPf0BbbFkGcvDzoJU7i//9GDrwwIHQVmIsrAGiF3ihpADBRIsrEFt1rQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.15.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+ "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/envinfo": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz",
+ "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==",
+ "dev": true,
+ "bin": {
+ "envinfo": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
+ "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
+ "dev": true
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -840,6 +1456,23 @@
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
+ "node_modules/fast-uri": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
+ "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
@@ -1030,6 +1663,34 @@
"node": ">=0.10.0"
}
},
+ "node_modules/jest-regex-util": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz",
+ "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz",
+ "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "graceful-fs": "^4.2.11",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
"node_modules/jest-worker": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
@@ -1077,6 +1738,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
"node_modules/loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
@@ -1112,6 +1786,20 @@
"node": ">=8"
}
},
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -1129,6 +1817,13 @@
"resolved": "https://registry.npmjs.org/material-design-icons-iconfont/-/material-design-icons-iconfont-5.0.1.tgz",
"integrity": "sha512-Xg6rIdGrfySTqiTZ6d+nQbcFepS6R4uKbJP0oAqyeZXJY/bX6mZDnOmmUJusqLXfhIwirs0c++a6JpqVa8RFvA=="
},
+ "node_modules/mdn-data": {
+ "version": "2.27.1",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -1238,9 +1933,9 @@
}
},
"node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "version": "3.3.19",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz",
+ "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==",
"dev": true,
"funding": [
{
@@ -1248,6 +1943,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -1262,10 +1958,27 @@
"dev": true
},
"node_modules/node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
- "dev": true
+ "version": "2.0.57",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz",
+ "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
},
"node_modules/opener": {
"version": "1.5.2",
@@ -1337,27 +2050,41 @@
"dev": true
},
"node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "dev": true
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
},
- "node_modules/pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "node_modules/picomatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
"dev": true,
- "dependencies": {
- "find-up": "^4.0.0"
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/postcss": {
- "version": "8.4.33",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
- "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
+ "version": "8.5.28",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
+ "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==",
"dev": true,
"funding": [
{
@@ -1373,15 +2100,287 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
+ "nanoid": "^3.3.18",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/postcss-calc": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.1.1.tgz",
+ "integrity": "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^7.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12 || ^20.9 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.38"
+ }
+ },
+ "node_modules/postcss-calc/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-colormin": {
+ "version": "7.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.10.tgz",
+ "integrity": "sha512-yFr6JezOolHLta/buLE71VKPh2mXursp4saVe98/ol8ZnEWhL+racShqPKlvd/DKWLre/39B6HhcMXf7RZ3hxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@colordx/core": "^5.4.3",
+ "browserslist": "^4.28.2",
+ "caniuse-api": "^3.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-convert-values": {
+ "version": "7.0.12",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.12.tgz",
+ "integrity": "sha512-xurKu5qqk4viR3Cp3p4xBR4KfnZm4w4ys6+UBwBmeuBSNkH7+DtLnYOYnOffgtE4yx8sH9S1VZ6RAAvROXzP2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-discard-comments": {
+ "version": "7.0.8",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.8.tgz",
+ "integrity": "sha512-CvvS5S9WrXblFXCEJ9nVo+4z+eA7zSC7Z88V1HEJuwlQhlFnYTIjg1xJY+BCUiG2bvICap2tXii4mP22BD108Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-discard-comments/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-discard-duplicates": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.4.tgz",
+ "integrity": "sha512-VBNn1+EuMZkeGVVtz0gRfbNGtx9IFgAsAV+E2pHtXPrp4qfGBkhTIiAuE/wrb+Y6Pakg9NewAlfTpYIFAWODtw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-discard-empty": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.3.tgz",
+ "integrity": "sha512-M2pyjQCU+/7cMHVtL6bKTHjv0lZnPLMpicgr67Dlth7AbuV9gjVTtUqaRwn6Pp6BwSDspUzhz8SaUrRykJU5Dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-discard-overridden": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.3.tgz",
+ "integrity": "sha512-aNovXo9UsZuRNLzHJtp13lHIvinDPfiXBPePpXkSjCbgp++iU2FqE+YxvjIsg6EdyPZsASFbfu+JcBFVsErXIQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-merge-longhand": {
+ "version": "7.0.7",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.7.tgz",
+ "integrity": "sha512-b3mfYUxR388u5Pt0HPcVIUtUDn/k15UfTY9M+ORW+meCR6JLNxoZffiYvXyOYQoRYQNZyX/UFkMCM/mNHxe1qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "stylehacks": "^7.0.11"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-merge-rules": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.11.tgz",
+ "integrity": "sha512-SJUPM18g2BmPhf8BVlbwqWz4aK3pLu6u6xjfwEzra7xL6IBR10sUaiB++EzqcVfadPHrKBSMlNdP+XieykhI+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "caniuse-api": "^3.0.0",
+ "cssnano-utils": "^5.0.3",
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-minify-font-values": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.3.tgz",
+ "integrity": "sha512-yilG/VOaNI74IylQvAQQxm3/wZVBkXyYUqNUAdxqwtbWUXPsbK1q8Ms0mL83v+f8YicgcyfYCRZtWACUdYajpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-minify-gradients": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.5.tgz",
+ "integrity": "sha512-YraROyQRg3BI1+Hg8E05B/JPdnTm8EDSVu4P2BxdM+CRiOyfmou809+chGIqo6fQqwjPGQ947nbGncSjmTU1WQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@colordx/core": "^5.4.3",
+ "cssnano-utils": "^5.0.3",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-minify-params": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.9.tgz",
+ "integrity": "sha512-R8itbB8BhlpoYyBm1ou0dD+vJnQ3F6adQipR4UnkCHUwlo+S9WXJaDRg1RHjC8YVAtIdrQzSWvJl40HnGDTKjA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "cssnano-utils": "^5.0.3",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-minify-selectors": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.1.2.tgz",
+ "integrity": "sha512-aQtrEWKwqafNlExcKHQvPGsXR2+vlUqqJtf5XsCQcgsSb5PL4wlujWBYDJuWsP4UnQX1YHDHU8qRlD+1PzTQ+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.1",
+ "caniuse-api": "^3.0.0",
+ "cssesc": "^3.0.0",
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-modules-extract-imports": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
@@ -1441,6 +2440,198 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/postcss-normalize-charset": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.3.tgz",
+ "integrity": "sha512-NoBfZu8PR4c2NlmjvrqQTzCzLY79hwcSRgNQ3ZiNK0ABzf9kYKloE/jNj+/8GQY1wsm8pRRgANk6ydLH8cwo0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-display-values": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.3.tgz",
+ "integrity": "sha512-ldsCX0QIt05pKIOobZtVQ48wXJecr+czw4+e1/YjVhLMqslShgpVxgPtI2CefURR8oyVoYaU/l829MMwExDMLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-positions": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.4.tgz",
+ "integrity": "sha512-VEvlpeGd3Ju1Hqa/oN4jaP3+ms4laYwkEL9N9u+B6k54PZjXbW1n6wI+aVprf1BQXlCYpS5+1pl/7/vHiKgARg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-repeat-style": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.4.tgz",
+ "integrity": "sha512-6mPKlY/8cSaDHxX502wERADarJsccwlky6yIrOapHH2ZgfoKAV94SbiTKfKEs4EEpdazuc3J72WsqeYk7hp9+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-string": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.3.tgz",
+ "integrity": "sha512-HnEQPUchi1eznmDKEYrKUTqrprEq97SrpUYClgUkv7V2zRODD9DFoUsYU+m9ZOetmD5ku7fEMZB/lwy8IT6xVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-timing-functions": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.3.tgz",
+ "integrity": "sha512-zmEzHdvpZBZu0OKlbJSfgASQvaayyAoVuWtvyr34IJ/LyS+DaOKvvR3EvFJ9RWWtNIx+CMvO125OVophaxNYew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-unicode": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.9.tgz",
+ "integrity": "sha512-DRAdWfeh/TjmhLJsw91vdiWCnUod9iwvM7xyS02/nF/sLsCR3A8l3pztrSUrWG8DSBqfX7yEk9FM0USaVJ2mSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-url": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.3.tgz",
+ "integrity": "sha512-CL93wmloq5qsffmFv+bw24MIRbmhHrp53qoh1LDAb/5TtjWEXI/np4xcP/Gw9oWCb2XyWnqHYLDUwiKRoJBA1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-whitespace": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.3.tgz",
+ "integrity": "sha512-FdHjjn+Ht5Z2ZRjNOmeCbNq6lq09sUYKpmlF/Aq0XjVNSLTL6fmHlA/3swN2wP2caY9GV/tjSDcIIyS7aN7W0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-ordered-values": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.4.tgz",
+ "integrity": "sha512-nubSi49hDHQk4E8KIj+IbLY8Bg+8OcSUEhgyolgM+atnOvXjV7EjaR6bac4YGZoFyPa9mWoAF3EaYbWdFkKqVg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-utils": "^5.0.3",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-reduce-initial": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.9.tgz",
+ "integrity": "sha512-ztTNPdIxXTxtBcG03E9u8v44M4ElXbMIRT7pf2onlquGula0Y83nKKxqM22FA/hMgkfCjN7ohevkVlaNwI8iOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "caniuse-api": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-reduce-transforms": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.3.tgz",
+ "integrity": "sha512-FXsnN9ZwcZTT8Yf8cAHA8qIGUXcX6WfLd9JoYhrdDfmvsVhhfqkkv7m4AC3rwFOfz+GzkUa87OCKF9dUcicd+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
"node_modules/postcss-selector-parser": {
"version": "6.0.15",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
@@ -1454,6 +2645,53 @@
"node": ">=4"
}
},
+ "node_modules/postcss-svgo": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.1.3.tgz",
+ "integrity": "sha512-2QfoFOYMcj8lwcVEf9WeTlkVIAm7u2QvOEhMzkQU3KUhhGX/l8hVV9EtjMv4iq3E9iI3OeeMN0YoMLbGusuigw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "svgo": "^4.0.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >= 18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-unique-selectors": {
+ "version": "7.0.7",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.7.tgz",
+ "integrity": "sha512-d+sCkaRnSefghOUdH8CMJZV9yUQhj2ojpe8Nw/lA+LV1UOfeleGkLTl6XdCFFSai9UJ+DJPb69FFuqthXYsY8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-unique-selectors/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
@@ -1557,6 +2795,16 @@
}
]
},
+ "node_modules/sax": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz",
+ "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=11.0.0"
+ }
+ },
"node_modules/schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
@@ -1651,15 +2899,17 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz",
+ "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
@@ -1669,6 +2919,7 @@
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -1690,6 +2941,37 @@
"webpack": "^5.0.0"
}
},
+ "node_modules/stylehacks": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.11.tgz",
+ "integrity": "sha512-iODNfhXVLqc5LADs+Y6Oh5wJuK5ZcHbVng8aiK3y9pjMQdc5hLrBW0eFU6FtnpNrE6PoEg/MmFTU4waotj5WNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/stylehacks/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@@ -1717,6 +2999,32 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/svgo": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.1.0.tgz",
+ "integrity": "sha512-bkxnTg1kSU0guhIBmibA6UUhrQmPVA1XsQLN+ylCd+UWzbnLkySOcXpyk1mrl05f+pcaCx2eHb+sp6BgMZWX+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^11.1.0",
+ "css-select": "^6.0.0",
+ "css-tree": "^3.0.1",
+ "css-what": "^7.0.0",
+ "csso": "^5.0.5",
+ "picocolors": "^1.1.1",
+ "sax": "1.6.1"
+ },
+ "bin": {
+ "svgo": "bin/svgo.js"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/svgo"
+ }
+ },
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@@ -1727,13 +3035,14 @@
}
},
"node_modules/terser": {
- "version": "5.27.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz",
- "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==",
+ "version": "5.51.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.51.2.tgz",
+ "integrity": "sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
- "acorn": "^8.8.2",
+ "acorn": "^8.15.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
@@ -1745,16 +3054,16 @@
}
},
"node_modules/terser-webpack-plugin": {
- "version": "5.3.10",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
- "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
+ "version": "5.6.1",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz",
+ "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.20",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
- "schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.1",
- "terser": "^5.26.0"
+ "schema-utils": "^4.3.0",
+ "terser": "^5.31.1"
},
"engines": {
"node": ">= 10.13.0"
@@ -1767,17 +3076,126 @@
"webpack": "^5.1.0"
},
"peerDependenciesMeta": {
+ "@minify-html/node": {
+ "optional": true
+ },
"@swc/core": {
"optional": true
},
+ "@swc/css": {
+ "optional": true
+ },
+ "@swc/html": {
+ "optional": true
+ },
+ "clean-css": {
+ "optional": true
+ },
+ "cssnano": {
+ "optional": true
+ },
+ "csso": {
+ "optional": true
+ },
"esbuild": {
"optional": true
},
+ "html-minifier-terser": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
"uglify-js": {
"optional": true
}
}
},
+ "node_modules/terser-webpack-plugin/node_modules/ajv": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.5.0.tgz",
+ "integrity": "sha512-zJlMCZ0cAR5p/Y4oVpRoqioDMJcGxaXRrQ/4rP4WyR84vc5z/DolXdbvXeDpTwbtocDFr2rhPqHPErDCUtz2kA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^8.20.0",
+ "ajv-formats": "^3.0.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/totalist": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
@@ -1799,9 +3217,9 @@
"dev": true
},
"node_modules/update-browserslist-db": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
- "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz",
+ "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==",
"dev": true,
"funding": [
{
@@ -1817,9 +3235,10 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
diff --git a/packages/solara-vuetify-app/package.json b/packages/solara-vuetify-app/package.json
index 8680b513e..22de9bebf 100644
--- a/packages/solara-vuetify-app/package.json
+++ b/packages/solara-vuetify-app/package.json
@@ -29,9 +29,11 @@
},
"devDependencies": {
"css-loader": "^6.9.1",
+ "css-minimizer-webpack-plugin": "^7.0.4",
"file-loader": "^6.2.0",
"mini-css-extract-plugin": "^2.7.7",
"style-loader": "^3.3.4",
+ "terser-webpack-plugin": "^5.6.1",
"webpack": "^5.90.0",
"webpack-bundle-analyzer": "^4.10.1",
"webpack-cli": "^5.1.4"
diff --git a/packages/solara-vuetify-app/src/fonts.js b/packages/solara-vuetify-app/src/fonts.js
deleted file mode 100644
index baea67787..000000000
--- a/packages/solara-vuetify-app/src/fonts.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import 'typeface-roboto';
-import 'material-design-icons-iconfont/dist/material-design-icons.css';
-import '@mdi/font/css/materialdesignicons.css';
diff --git a/packages/solara-vuetify-app/src/solara-vuetify-app.js b/packages/solara-vuetify-app/src/solara-vuetify-app.js
index 7606ed88f..f47cd6866 100644
--- a/packages/solara-vuetify-app/src/solara-vuetify-app.js
+++ b/packages/solara-vuetify-app/src/solara-vuetify-app.js
@@ -1,7 +1,6 @@
import Vue from 'vue';
import Vuetify from 'vuetify';
-import 'vuetify/dist/vuetify.min.css';
import { addCompiler } from '@mariobuikhuizen/vue-compiler-addon';
addCompiler(Vue);
@@ -9,6 +8,19 @@ addCompiler(Vue);
Vue.use(Vuetify);
import * as solara from './solara';
+
+// The frontend features of this bundle, next to the ones of the widget manager.
+// Vuetify is in the core bundle on Vue 2: jupyter-vuetify's nodeps.js reads the app's vuetify.
+solara.provideFeature('vuetify', { Vuetify });
+// Vuetify's CSS is a CSS-only feature (main{M}.vuetify.css), so an app can ship its own: the page always preloads it
+// on Vue 2, before the core CSS (its place when it was part of main{M}.css), unless its --frontend says -vuetify-css
+solara.registerFeature('vuetify-css', () => import(/* webpackChunkName: "vuetify-css" */ 'vuetify/dist/vuetify.min.css'), [], true);
+// CSS only (fonts and icons); Vuetify needs mdi, so the page always preloads it on Vue 2, and roboto unless the
+// page's --frontend says -roboto
+solara.registerFeature('mdi', () => import(/* webpackChunkName: "mdi" */ '@mdi/font/css/materialdesignicons.css'), [], true);
+solara.registerFeature('material-icons', () => import(/* webpackChunkName: "material-icons" */ 'material-design-icons-iconfont/dist/material-design-icons.css'), [], true);
+solara.registerFeature('roboto', () => import(/* webpackChunkName: "roboto" */ 'typeface-roboto'), [], true);
+
export { solara };
export { Vue };
diff --git a/packages/solara-vuetify-app/src/solara.js b/packages/solara-vuetify-app/src/solara.js
index bd38c21e0..6c29eaf12 100644
--- a/packages/solara-vuetify-app/src/solara.js
+++ b/packages/solara-vuetify-app/src/solara.js
@@ -1 +1,5 @@
-export { RenderMimeRegistry, WidgetManager, connectKernel, extendedRendererFactories, KatexTypesetter, renderKatex, shutdownKernel } from '@widgetti/solara-widget-manager';
+export {
+ RenderMimeRegistry, WidgetManager, connectKernel, extendedRendererFactories, KatexTypesetter, renderKatex, shutdownKernel,
+ registerFeature, provideFeature, setEnabledFeatures, isEnabled, hasFeature, loadFeature, loadPreloadedFeaturesSync,
+ getLoadedFeature, onLazyLoad, defineAmdModules, loadKatex,
+} from '@widgetti/solara-widget-manager';
diff --git a/packages/solara-vuetify-app/webpack.config.js b/packages/solara-vuetify-app/webpack.config.js
index 2118c7b0f..bead87348 100755
--- a/packages/solara-vuetify-app/webpack.config.js
+++ b/packages/solara-vuetify-app/webpack.config.js
@@ -1,125 +1,104 @@
-var path = require('path');
+const path = require('path');
+const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
+const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
+const TerserPlugin = require("terser-webpack-plugin");
+const { slotInsert, cssChunkFilename, DropCssPlugin, WrapUmdFactoryPlugin, ChunkGuardPlugin, DedupePackagesPlugin } = require("../solara-widget-manager/webpack-plugins");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
-const analyzerPlugins = process.env.ANALYZE === "true" ? [
- new BundleAnalyzerPlugin({analyzerPort: 9999})] : [];
+const analyze = process.env.ANALYZE === "true";
-var rules = [
+// Each frontend feature (katex, jupyter-controls, ...) is a named async chunk:
+// solara-vuetify-app{M}.{feature}{.min}.js and main{M}.{feature}.css.
+// The server preloads the chunks of the enabled features, see solara/server/frontend_assets.py.
+// On Vue 2, Vuetify stays in the core bundle (jupyter-vuetify's nodeps.js reads the app's vuetify).
+
+const rules = [
{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] },
- // required to load font-awesome
- {
- test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
- },
- {
- test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
- },
- {
- test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
- },
+ // fonts are files, not data URIs: the browser fetches only the fonts a page uses
+ // (KaTeX's CSS was 77 KB gzip with its fonts inlined, 4 KB without)
{
- test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
+ test: /\.(woff2?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
+ type: 'asset/resource',
},
- {
- test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
- }
];
-module.exports = [
- {
- plugins: [new MiniCssExtractPlugin({filename: 'fonts.css'})],
- entry: './src/fonts.js',
- output: {
- filename: 'fonts.js',
- path: path.resolve(__dirname, 'dist'),
- libraryTarget: 'umd',
- publicPath: 'auto',
- },
- module: {
- rules: rules
- },
- mode: 'production',
- },
- {
- plugins: [new MiniCssExtractPlugin({filename: 'main7.css'})],
- entry: './src/solara-vuetify-app.js',
- output: {
- filename: 'solara-vuetify-app7.min.js',
- path: path.resolve(__dirname, 'dist'),
- libraryTarget: 'umd',
- publicPath: 'auto',
- },
- module: {
- rules: rules
- },
- mode: 'production',
- },
- {
- plugins: [new MiniCssExtractPlugin({filename: 'main7.css'})],
- entry: './src/solara-vuetify-app.js',
- output: {
- filename: 'solara-vuetify-app7.js',
- path: path.resolve(__dirname, 'dist'),
- libraryTarget: 'umd',
- publicPath: 'auto',
- devtoolModuleFilenameTemplate: `webpack://@widgetti/solara-vuetify-app`
- },
- module: {
- rules: rules
- },
- mode: 'development',
- },
- {
- plugins: [new MiniCssExtractPlugin({filename: 'main8.css'}), ...analyzerPlugins],
+const empty = path.resolve(__dirname, "src", "empty.js");
+
+// one config per (ipywidgets major version, production|development)
+function config(major, production) {
+ const min = production ? '.min' : '';
+ const widgetManager = major === 8 ? '@widgetti/solara-widget-manager8' : '@widgetti/solara-widget-manager';
+ return {
+ name: `solara-vuetify-app${major}${min}`,
entry: './src/solara-vuetify-app.js',
+ mode: production ? 'production' : 'development',
+ // as before: no source map for prod 7, eval for dev 7
+ devtool: major === 8 ? 'source-map' : (production ? false : 'eval'),
output: {
- filename: 'solara-vuetify-app8.min.js',
+ filename: `solara-vuetify-app${major}${min}.js`,
+ chunkFilename: `solara-vuetify-app${major}.[name]${min}.js`,
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'umd',
+ // chunks load from where the core script came from (CDN, /_solara/cdn, solara-assets)
publicPath: 'auto',
+ // own JSONP global per build, so two builds can never share chunks
+ uniqueName: `solara_vuetify_app${major}${production ? '' : '_dev'}`,
+ ...(production ? {} : { devtoolModuleFilenameTemplate: `webpack://@widgetti/solara-vuetify-app` }),
},
- devtool: 'source-map',
+ plugins: [
+ new MiniCssExtractPlugin({
+ filename: `main${major}.css`,
+ // main{M}.{chunk name}.css, but Vuetify's CSS (chunk vuetify-css) is main{M}.vuetify.css
+ chunkFilename: cssChunkFilename(major),
+ insert: slotInsert,
+ }),
+ new ChunkGuardPlugin(),
+ new DedupePackagesPlugin(),
+ // only the parts of the @jupyterlab/services index that we use (see solara-widget-manager/src/services.ts)
+ new webpack.NormalModuleReplacementPlugin(
+ /@jupyterlab[\\/]services[\\/]lib[\\/]index\.js$/,
+ path.resolve(__dirname, 'node_modules', widgetManager, 'lib', 'services.js'),
+ ),
+ ...(production ? [] : [new DropCssPlugin(), new WrapUmdFactoryPlugin()]),
+ ...(analyze && major === 8 && production ? [new BundleAnalyzerPlugin({ analyzerPort: 9999 })] : []),
+ ],
module: {
rules: rules
},
optimization: {
- concatenateModules: false,
+ // no shared chunks with generated names: every async chunk is one feature
+ splitChunks: false,
+ // the bundle analyzer shows more detail without module concatenation
+ concatenateModules: analyze ? false : undefined,
+ minimizer: [
+ // without ascii_only, the chunks need on the page.
+ // wrap_func_args (the default before terser 5.43) keeps a function passed as an argument in
+ // parentheses, as in the published bundles: V8 then compiles the UMD factory, "(self,(()=>...))",
+ // eagerly and off the main thread, instead of lazily on the main thread (see WrapUmdFactoryPlugin)
+ new TerserPlugin({ terserOptions: { format: { ascii_only: true, wrap_func_args: true } } }),
+ // also removes the duplicate Vuetify rules (dist + lib CSS), keeping the last copy.
+ // mergeLonghand off: merging var() longhands into a shorthand changes the cascade, e.g.
+ // Vuetify's .v-main padding-top/left longhands became one padding shorthand, and one invalid
+ // var (--v-layout-left: NaN with a width="min-content" drawer) then voided padding-top as well
+ new CssMinimizerPlugin({ minimizerOptions: { preset: ['default', { mergeLonghand: false }] } }),
+ ],
},
resolve: {
alias: {
- "@widgetti/solara-widget-manager": "@widgetti/solara-widget-manager8",
- // why would we need codemirror?
- '@jupyterlab/codemirror': path.resolve(__dirname, "src", "empty.js"),
- // do not think we use these
- 'postcss': path.resolve(__dirname, "src", "empty.js"),
- 'moment': path.resolve(__dirname, "src", "empty.js"),
+ ...(major === 8 ? { "@widgetti/solara-widget-manager": widgetManager } : {}),
+ // CodeMirror (markdown code highlighting) is a lazy chunk (see solara-widget-manager/src/codemirror.ts)
+ '@jupyterlab/codemirror$': path.resolve(__dirname, 'node_modules', widgetManager, 'lib', 'codemirror.js'),
+ // do not think we use this
+ 'moment': empty,
+ // as before: the ipywidgets 8 production build has no postcss, so sanitize-html drops the
+ // style attributes of HTML descriptions (the development build keeps them)
+ ...(major === 8 && production ? { 'postcss': empty } : {}),
+ // one sanitize-html copy, in the "sanitizer" chunk (see solara-widget-manager/src/sanitize.ts)
+ 'sanitize-html$': path.resolve(__dirname, 'node_modules', widgetManager, 'lib', 'sanitize.js'),
}
},
- mode: 'production',
- }, {
- plugins: [new MiniCssExtractPlugin({filename: 'main8.css'})],
- entry: './src/solara-vuetify-app.js',
- output: {
- filename: 'solara-vuetify-app8.js',
- path: path.resolve(__dirname, 'dist'),
- libraryTarget: 'umd',
- publicPath: 'auto',
- devtoolModuleFilenameTemplate: `webpack://@widgetti/solara-vuetify-app`
- },
- devtool: 'source-map',
- module: {
- rules: rules
- },
- resolve: {
- alias: {
- "@widgetti/solara-widget-manager": "@widgetti/solara-widget-manager8",
- }
- },
- mode: 'development',
- },
-];
+ };
+}
+
+module.exports = [config(7, true), config(7, false), config(8, true), config(8, false)];
diff --git a/packages/solara-vuetify3-app/.bumpversion.cfg b/packages/solara-vuetify3-app/.bumpversion.cfg
index 013671cf1..8fb6a520e 100644
--- a/packages/solara-vuetify3-app/.bumpversion.cfg
+++ b/packages/solara-vuetify3-app/.bumpversion.cfg
@@ -8,8 +8,12 @@ message = Bump version solara-vuetify3-app: {current_version} → {new_version}
[bumpversion:file:package.json]
-[bumpversion:file:../../solara/server/templates/solara.html.j2]
+[bumpversion:file:../../solara/server/frontend_assets.py]
+search = SOLARA_VUETIFY3_APP_VERSION = "{current_version}"
+replace = SOLARA_VUETIFY3_APP_VERSION = "{new_version}"
[bumpversion:file:../../release.sh]
[bumpversion:file:../solara-assets/hatch_build.py]
+search = ["@widgetti/solara-vuetify3-app", "{current_version}"]
+replace = ["@widgetti/solara-vuetify3-app", "{new_version}"]
diff --git a/packages/solara-vuetify3-app/package-lock.json b/packages/solara-vuetify3-app/package-lock.json
index 21a2fc71a..431d604b0 100644
--- a/packages/solara-vuetify3-app/package-lock.json
+++ b/packages/solara-vuetify3-app/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@widgetti/solara-vuetify3-app",
- "version": "5.1.1",
+ "version": "5.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@widgetti/solara-vuetify3-app",
- "version": "5.1.1",
+ "version": "5.2.0",
"license": "MIT",
"dependencies": {
"@mdi/font": "^4.9.95",
@@ -19,9 +19,11 @@
},
"devDependencies": {
"css-loader": "^6.9.1",
+ "css-minimizer-webpack-plugin": "^7.0.4",
"file-loader": "^6.2.0",
"mini-css-extract-plugin": "^2.7.7",
"style-loader": "^3.3.4",
+ "terser-webpack-plugin": "^5.6.1",
"webpack": "^5.90.0",
"webpack-cli": "^5.1.4"
}
@@ -37,6 +39,7 @@
"@jupyter-widgets/controls8": "npm:@jupyter-widgets/controls@^5.0.1",
"@jupyter-widgets/jupyterlab-manager": "^3.1.7",
"@jupyter-widgets/jupyterlab-manager8": "npm:@jupyter-widgets/jupyterlab-manager@^5.0.3",
+ "@jupyter-widgets/output": "^4.1.5",
"@jupyterlab/application": "^3.6.7",
"@jupyterlab/apputils": "^3.6.7",
"@jupyterlab/coreutils": "^5.6.7",
@@ -53,7 +56,8 @@
"@lumino/signaling": "^1.11.1",
"@lumino/virtualdom": "^1.14.3",
"@lumino/widgets": "^1.37.2",
- "katex": "^0.16.9"
+ "katex": "^0.16.9",
+ "sanitize-html": "^2.11.0"
},
"devDependencies": {
"npm-run-all": "^4.1.5",
@@ -69,6 +73,7 @@
"@jupyter-widgets/base": "npm:@jupyter-widgets/base@^6.0.6",
"@jupyter-widgets/controls": "npm:@jupyter-widgets/controls@^5.0.1",
"@jupyter-widgets/jupyterlab-manager": "npm:@jupyter-widgets/jupyterlab-manager@^5.0.3",
+ "@jupyter-widgets/output": "^6.0.6",
"@jupyterlab/application": "^3.6.7",
"@jupyterlab/apputils": "^3.6.7",
"@jupyterlab/coreutils": "^5.6.7",
@@ -86,7 +91,8 @@
"@lumino/virtualdom": "^1.14.3",
"@lumino/widgets": "^1.37.2",
"katex": "^0.16.9",
- "patch-package": "^8.0.0"
+ "patch-package": "^8.0.0",
+ "sanitize-html": "^2.11.0"
},
"devDependencies": {
"npm-run-all": "^4.1.5",
@@ -139,6 +145,13 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@colordx/core": {
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@colordx/core/-/core-5.8.0.tgz",
+ "integrity": "sha512-cG0QJAO6VkaRUlIb0zOzX9gfJgs1pjoOL9gZ/PK1kfvBs0GCkADu5oQh6gPxXgQnZ3gV575h+lQRC0NlMDTclA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@discoveryjs/json-ext": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -148,46 +161,82 @@
"node": ">=10.0.0"
}
},
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
- "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "node_modules/@jest/pattern": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.5.0.tgz",
+ "integrity": "sha512-HdNQYSdRTEBNrginaqzQtTjG0HRMfrra/z6Ok7uL3S87vSlarIVohEsJsSj5edu3MiHoHjAkvPROz5ZjoKai+w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/set-array": "^1.0.1",
- "@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@types/node": "*",
+ "jest-regex-util": "30.5.0"
},
"engines": {
- "node": ">=6.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
- "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "node_modules/@jest/schemas": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.5.0.tgz",
+ "integrity": "sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.34.0"
+ },
"engines": {
- "node": ">=6.0.0"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/@jridgewell/set-array": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
- "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "node_modules/@jest/types": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.5.1.tgz",
+ "integrity": "sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==",
"dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/pattern": "30.5.0",
+ "@jest/schemas": "30.5.0",
+ "@types/istanbul-lib-coverage": "^2.0.6",
+ "@types/istanbul-reports": "^3.0.4",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.33",
+ "chalk": "^4.1.2"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
- "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
+ "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.0",
- "@jridgewell/trace-mapping": "^0.3.9"
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
@@ -197,10 +246,11 @@
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.22",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
- "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@@ -211,6 +261,13 @@
"resolved": "https://registry.npmjs.org/@mdi/font/-/font-4.9.95.tgz",
"integrity": "sha512-m2sbAs+SMwRnWpkMriBxEulwuhmqRyh6X+hdOZlqSxYZUM2C2TaDnQ4gcilzdoAgru2XYnWViZ/xPuSDGgRXVw=="
},
+ "node_modules/@sinclair/typebox": {
+ "version": "0.34.52",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz",
+ "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/eslint": {
"version": "8.56.2",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz",
@@ -237,6 +294,33 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -252,6 +336,30 @@
"undici-types": "~5.26.4"
}
},
+ "node_modules/@types/yargs": {
+ "version": "17.0.35",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
+ "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz",
+ "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/@vue/compiler-core": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.39.tgz",
@@ -563,10 +671,11 @@
"dev": true
},
"node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz",
+ "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==",
"dev": true,
+ "license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@@ -647,6 +756,35 @@
"ajv": "^6.9.1"
}
},
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.11.27",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.27.tgz",
+ "integrity": "sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.cjs"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -656,10 +794,17 @@
"node": "*"
}
},
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/browserslist": {
- "version": "4.22.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz",
- "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+ "version": "4.29.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz",
+ "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==",
"dev": true,
"funding": [
{
@@ -675,11 +820,13 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001565",
- "electron-to-chromium": "^1.4.601",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.13"
+ "baseline-browser-mapping": "^2.11.26",
+ "caniuse-lite": "^1.0.30001813",
+ "electron-to-chromium": "^1.5.439",
+ "node-releases": "^2.0.57",
+ "update-browserslist-db": "^1.3.3"
},
"bin": {
"browserslist": "cli.js"
@@ -692,12 +839,26 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "dev": true
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/caniuse-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.0.0",
+ "caniuse-lite": "^1.0.0",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001580",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001580.tgz",
- "integrity": "sha512-mtj5ur2FFPZcCEpXFy8ADXbDACuNFXg6mxVDqp7tqooX6l3zwm+d8EPoeOSIFRDvHs8qu7/SLFOGniULkcH2iA==",
+ "version": "1.0.30001814",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001814.tgz",
+ "integrity": "sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==",
"dev": true,
"funding": [
{
@@ -712,7 +873,38 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
- ]
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "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/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
},
"node_modules/chrome-trace-event": {
"version": "1.0.3",
@@ -723,6 +915,22 @@
"node": ">=6.0"
}
},
+ "node_modules/ci-info": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz",
+ "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/clone-deep": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
@@ -737,6 +945,26 @@
"node": ">=6"
}
},
+ "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/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/colorette": {
"version": "2.0.20",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
@@ -744,10 +972,14 @@
"dev": true
},
"node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
+ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
},
"node_modules/cross-spawn": {
"version": "7.0.3",
@@ -763,6 +995,19 @@
"node": ">= 8"
}
},
+ "node_modules/css-declaration-sorter": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.4.0.tgz",
+ "integrity": "sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14 || ^16 || >=18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.0.9"
+ }
+ },
"node_modules/css-loader": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.9.1.tgz",
@@ -789,87 +1034,457 @@
"webpack": "^5.0.0"
}
},
- "node_modules/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "node_modules/css-minimizer-webpack-plugin": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-7.0.4.tgz",
+ "integrity": "sha512-2iACis+P8qdLj1tHcShtztkGhCNIRUajJj7iX0IM9a5FA0wXGwjV8Nf6+HsBjBfb4LO8TTAVoetBbM54V6f3+Q==",
"dev": true,
- "bin": {
- "cssesc": "bin/cssesc"
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "cssnano": "^7.0.4",
+ "jest-worker": "^30.0.5",
+ "postcss": "^8.4.40",
+ "schema-utils": "^4.2.0",
+ "serialize-javascript": "^6.0.2"
},
"engines": {
- "node": ">=4"
+ "node": ">= 18.12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ },
+ "peerDependencies": {
+ "webpack": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@parcel/css": {
+ "optional": true
+ },
+ "@swc/css": {
+ "optional": true
+ },
+ "clean-css": {
+ "optional": true
+ },
+ "csso": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ }
}
},
- "node_modules/csstype": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "license": "MIT"
- },
- "node_modules/electron-to-chromium": {
- "version": "1.4.645",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.645.tgz",
- "integrity": "sha512-EeS1oQDCmnYsRDRy2zTeC336a/4LZ6WKqvSaM1jLocEk5ZuyszkQtCpsqvuvaIXGOUjwtvF6LTcS8WueibXvSw==",
- "dev": true
- },
- "node_modules/emojis-list": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
- "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
"dev": true,
- "engines": {
- "node": ">= 4"
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
}
},
- "node_modules/enhanced-resolve": {
- "version": "5.15.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
- "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+ "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.2.0"
+ "ajv": "^8.0.0"
},
- "engines": {
- "node": ">=10.13.0"
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
}
},
- "node_modules/entities": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
- "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
+ "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
},
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
+ "peerDependencies": {
+ "ajv": "^8.8.2"
}
},
- "node_modules/envinfo": {
- "version": "7.11.0",
- "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz",
- "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==",
+ "node_modules/css-minimizer-webpack-plugin/node_modules/jest-worker": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.5.1.tgz",
+ "integrity": "sha512-Cbxh5v7AoLuFRmFJSM4/aHdQ68rjXvUWr716EE0Dh3I7T+T/3FgFKhOERGXHcU2Meftq9+9zxPM3TSNyI9D+HA==",
"dev": true,
- "bin": {
- "envinfo": "dist/cli.js"
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@ungap/structured-clone": "^1.3.0",
+ "jest-util": "30.5.1",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.1.1"
},
"engines": {
- "node": ">=4"
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
},
- "node_modules/es-module-lexer": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
- "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
- "dev": true
+ "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.5.0.tgz",
+ "integrity": "sha512-zJlMCZ0cAR5p/Y4oVpRoqioDMJcGxaXRrQ/4rP4WyR84vc5z/DolXdbvXeDpTwbtocDFr2rhPqHPErDCUtz2kA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^8.20.0",
+ "ajv-formats": "^3.0.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-6.0.0.tgz",
+ "integrity": "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^7.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "nth-check": "^2.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-tree": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+ "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.27.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-7.0.0.tgz",
+ "integrity": "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/cssnano": {
+ "version": "7.1.9",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.1.9.tgz",
+ "integrity": "sha512-uPR75+5Dk/WJ/YSPR1/YDHdwMM9c5FsaARljfKWgeCKLKOtJ0we21xy/RcCjn53fZnD/f6yYEIZ8pu18+GnbNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-preset-default": "^7.0.17",
+ "lilconfig": "^3.1.3"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/cssnano"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/cssnano-preset-default": {
+ "version": "7.0.17",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.17.tgz",
+ "integrity": "sha512-11qO63A+czwguQFJCaTdICvbaxn0pJzz/XghLlv+OT7WyToDxAMR0Xb3/26/l0y0hQJywwNbj/SLSQlGBHE1OA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "css-declaration-sorter": "^7.2.0",
+ "cssnano-utils": "^5.0.3",
+ "postcss-calc": "^10.1.1",
+ "postcss-colormin": "^7.0.10",
+ "postcss-convert-values": "^7.0.12",
+ "postcss-discard-comments": "^7.0.8",
+ "postcss-discard-duplicates": "^7.0.4",
+ "postcss-discard-empty": "^7.0.3",
+ "postcss-discard-overridden": "^7.0.3",
+ "postcss-merge-longhand": "^7.0.7",
+ "postcss-merge-rules": "^7.0.11",
+ "postcss-minify-font-values": "^7.0.3",
+ "postcss-minify-gradients": "^7.0.5",
+ "postcss-minify-params": "^7.0.9",
+ "postcss-minify-selectors": "^7.1.2",
+ "postcss-normalize-charset": "^7.0.3",
+ "postcss-normalize-display-values": "^7.0.3",
+ "postcss-normalize-positions": "^7.0.4",
+ "postcss-normalize-repeat-style": "^7.0.4",
+ "postcss-normalize-string": "^7.0.3",
+ "postcss-normalize-timing-functions": "^7.0.3",
+ "postcss-normalize-unicode": "^7.0.9",
+ "postcss-normalize-url": "^7.0.3",
+ "postcss-normalize-whitespace": "^7.0.3",
+ "postcss-ordered-values": "^7.0.4",
+ "postcss-reduce-initial": "^7.0.9",
+ "postcss-reduce-transforms": "^7.0.3",
+ "postcss-svgo": "^7.1.3",
+ "postcss-unique-selectors": "^7.0.7"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/cssnano-utils": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.3.tgz",
+ "integrity": "sha512-ynIREMICLxkxm7e9bCR9sh75s4Q5drICi0ua1yxo5jH2XPBqSKkl4dOh4EbFqtUmnTMhRffHgYL0EKKkMjtJTg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/csso": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
+ "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "css-tree": "~2.2.0"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/css-tree": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
+ "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.0.28",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/csso/node_modules/mdn-data": {
+ "version": "2.0.28",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
+ "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/csstype": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
+ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
+ "license": "MIT"
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/dom-serializer/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.444",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.444.tgz",
+ "integrity": "sha512-5ss/uJfoDYDHT0lfJzT6FbcskIzROIOPf0BbbFkGcvDzoJU7i//9GDrwwIHQVmIsrAGiF3ihpADBRIsrEFt1rQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.15.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+ "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/envinfo": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.0.tgz",
+ "integrity": "sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==",
+ "dev": true,
+ "bin": {
+ "envinfo": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
+ "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
+ "dev": true
},
"node_modules/escalade": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -944,6 +1559,23 @@
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
+ "node_modules/fast-uri": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
+ "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
@@ -1116,6 +1748,34 @@
"node": ">=0.10.0"
}
},
+ "node_modules/jest-regex-util": {
+ "version": "30.5.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.5.0.tgz",
+ "integrity": "sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "30.5.1",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.5.1.tgz",
+ "integrity": "sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "30.5.1",
+ "@types/node": "*",
+ "chalk": "^4.1.2",
+ "ci-info": "^4.2.0",
+ "graceful-fs": "^4.2.11",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
+ }
+ },
"node_modules/jest-worker": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
@@ -1163,6 +1823,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
"node_modules/loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
@@ -1198,6 +1871,20 @@
"node": ">=8"
}
},
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -1224,6 +1911,13 @@
"resolved": "https://registry.npmjs.org/material-design-icons-iconfont/-/material-design-icons-iconfont-5.0.1.tgz",
"integrity": "sha512-Xg6rIdGrfySTqiTZ6d+nQbcFepS6R4uKbJP0oAqyeZXJY/bX6mZDnOmmUJusqLXfhIwirs0c++a6JpqVa8RFvA=="
},
+ "node_modules/mdn-data": {
+ "version": "2.27.1",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -1348,10 +2042,27 @@
"dev": true
},
"node_modules/node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
- "dev": true
+ "version": "2.0.57",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz",
+ "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
},
"node_modules/p-limit": {
"version": "2.3.0",
@@ -1419,7 +2130,20 @@
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"license": "ISC"
},
- "node_modules/pkg-dir": {
+ "node_modules/picomatch": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
+ "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
@@ -1459,6 +2183,277 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/postcss-calc": {
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.1.1.tgz",
+ "integrity": "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^7.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12 || ^20.9 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.38"
+ }
+ },
+ "node_modules/postcss-calc/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-colormin": {
+ "version": "7.0.10",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.10.tgz",
+ "integrity": "sha512-yFr6JezOolHLta/buLE71VKPh2mXursp4saVe98/ol8ZnEWhL+racShqPKlvd/DKWLre/39B6HhcMXf7RZ3hxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@colordx/core": "^5.4.3",
+ "browserslist": "^4.28.2",
+ "caniuse-api": "^3.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-convert-values": {
+ "version": "7.0.12",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.12.tgz",
+ "integrity": "sha512-xurKu5qqk4viR3Cp3p4xBR4KfnZm4w4ys6+UBwBmeuBSNkH7+DtLnYOYnOffgtE4yx8sH9S1VZ6RAAvROXzP2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-discard-comments": {
+ "version": "7.0.8",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.8.tgz",
+ "integrity": "sha512-CvvS5S9WrXblFXCEJ9nVo+4z+eA7zSC7Z88V1HEJuwlQhlFnYTIjg1xJY+BCUiG2bvICap2tXii4mP22BD108Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-discard-comments/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-discard-duplicates": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.4.tgz",
+ "integrity": "sha512-VBNn1+EuMZkeGVVtz0gRfbNGtx9IFgAsAV+E2pHtXPrp4qfGBkhTIiAuE/wrb+Y6Pakg9NewAlfTpYIFAWODtw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-discard-empty": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.3.tgz",
+ "integrity": "sha512-M2pyjQCU+/7cMHVtL6bKTHjv0lZnPLMpicgr67Dlth7AbuV9gjVTtUqaRwn6Pp6BwSDspUzhz8SaUrRykJU5Dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-discard-overridden": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.3.tgz",
+ "integrity": "sha512-aNovXo9UsZuRNLzHJtp13lHIvinDPfiXBPePpXkSjCbgp++iU2FqE+YxvjIsg6EdyPZsASFbfu+JcBFVsErXIQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-merge-longhand": {
+ "version": "7.0.7",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.7.tgz",
+ "integrity": "sha512-b3mfYUxR388u5Pt0HPcVIUtUDn/k15UfTY9M+ORW+meCR6JLNxoZffiYvXyOYQoRYQNZyX/UFkMCM/mNHxe1qA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "stylehacks": "^7.0.11"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-merge-rules": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.11.tgz",
+ "integrity": "sha512-SJUPM18g2BmPhf8BVlbwqWz4aK3pLu6u6xjfwEzra7xL6IBR10sUaiB++EzqcVfadPHrKBSMlNdP+XieykhI+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "caniuse-api": "^3.0.0",
+ "cssnano-utils": "^5.0.3",
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/postcss-minify-font-values": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.3.tgz",
+ "integrity": "sha512-yilG/VOaNI74IylQvAQQxm3/wZVBkXyYUqNUAdxqwtbWUXPsbK1q8Ms0mL83v+f8YicgcyfYCRZtWACUdYajpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-minify-gradients": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.5.tgz",
+ "integrity": "sha512-YraROyQRg3BI1+Hg8E05B/JPdnTm8EDSVu4P2BxdM+CRiOyfmou809+chGIqo6fQqwjPGQ947nbGncSjmTU1WQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@colordx/core": "^5.4.3",
+ "cssnano-utils": "^5.0.3",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-minify-params": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.9.tgz",
+ "integrity": "sha512-R8itbB8BhlpoYyBm1ou0dD+vJnQ3F6adQipR4UnkCHUwlo+S9WXJaDRg1RHjC8YVAtIdrQzSWvJl40HnGDTKjA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "cssnano-utils": "^5.0.3",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-minify-selectors": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.1.2.tgz",
+ "integrity": "sha512-aQtrEWKwqafNlExcKHQvPGsXR2+vlUqqJtf5XsCQcgsSb5PL4wlujWBYDJuWsP4UnQX1YHDHU8qRlD+1PzTQ+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.1",
+ "caniuse-api": "^3.0.0",
+ "cssesc": "^3.0.0",
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-modules-extract-imports": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
@@ -1518,6 +2513,198 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/postcss-normalize-charset": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.3.tgz",
+ "integrity": "sha512-NoBfZu8PR4c2NlmjvrqQTzCzLY79hwcSRgNQ3ZiNK0ABzf9kYKloE/jNj+/8GQY1wsm8pRRgANk6ydLH8cwo0Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-display-values": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.3.tgz",
+ "integrity": "sha512-ldsCX0QIt05pKIOobZtVQ48wXJecr+czw4+e1/YjVhLMqslShgpVxgPtI2CefURR8oyVoYaU/l829MMwExDMLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-positions": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.4.tgz",
+ "integrity": "sha512-VEvlpeGd3Ju1Hqa/oN4jaP3+ms4laYwkEL9N9u+B6k54PZjXbW1n6wI+aVprf1BQXlCYpS5+1pl/7/vHiKgARg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-repeat-style": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.4.tgz",
+ "integrity": "sha512-6mPKlY/8cSaDHxX502wERADarJsccwlky6yIrOapHH2ZgfoKAV94SbiTKfKEs4EEpdazuc3J72WsqeYk7hp9+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-string": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.3.tgz",
+ "integrity": "sha512-HnEQPUchi1eznmDKEYrKUTqrprEq97SrpUYClgUkv7V2zRODD9DFoUsYU+m9ZOetmD5ku7fEMZB/lwy8IT6xVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-timing-functions": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.3.tgz",
+ "integrity": "sha512-zmEzHdvpZBZu0OKlbJSfgASQvaayyAoVuWtvyr34IJ/LyS+DaOKvvR3EvFJ9RWWtNIx+CMvO125OVophaxNYew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-unicode": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.9.tgz",
+ "integrity": "sha512-DRAdWfeh/TjmhLJsw91vdiWCnUod9iwvM7xyS02/nF/sLsCR3A8l3pztrSUrWG8DSBqfX7yEk9FM0USaVJ2mSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-url": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.3.tgz",
+ "integrity": "sha512-CL93wmloq5qsffmFv+bw24MIRbmhHrp53qoh1LDAb/5TtjWEXI/np4xcP/Gw9oWCb2XyWnqHYLDUwiKRoJBA1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-normalize-whitespace": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.3.tgz",
+ "integrity": "sha512-FdHjjn+Ht5Z2ZRjNOmeCbNq6lq09sUYKpmlF/Aq0XjVNSLTL6fmHlA/3swN2wP2caY9GV/tjSDcIIyS7aN7W0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-ordered-values": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.4.tgz",
+ "integrity": "sha512-nubSi49hDHQk4E8KIj+IbLY8Bg+8OcSUEhgyolgM+atnOvXjV7EjaR6bac4YGZoFyPa9mWoAF3EaYbWdFkKqVg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssnano-utils": "^5.0.3",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-reduce-initial": {
+ "version": "7.0.9",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.9.tgz",
+ "integrity": "sha512-ztTNPdIxXTxtBcG03E9u8v44M4ElXbMIRT7pf2onlquGula0Y83nKKxqM22FA/hMgkfCjN7ohevkVlaNwI8iOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "caniuse-api": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-reduce-transforms": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.3.tgz",
+ "integrity": "sha512-FXsnN9ZwcZTT8Yf8cAHA8qIGUXcX6WfLd9JoYhrdDfmvsVhhfqkkv7m4AC3rwFOfz+GzkUa87OCKF9dUcicd+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
"node_modules/postcss-selector-parser": {
"version": "6.0.15",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz",
@@ -1531,6 +2718,53 @@
"node": ">=4"
}
},
+ "node_modules/postcss-svgo": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.1.3.tgz",
+ "integrity": "sha512-2QfoFOYMcj8lwcVEf9WeTlkVIAm7u2QvOEhMzkQU3KUhhGX/l8hVV9EtjMv4iq3E9iI3OeeMN0YoMLbGusuigw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-value-parser": "^4.2.0",
+ "svgo": "^4.0.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >= 18"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-unique-selectors": {
+ "version": "7.0.7",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.7.tgz",
+ "integrity": "sha512-d+sCkaRnSefghOUdH8CMJZV9yUQhj2ojpe8Nw/lA+LV1UOfeleGkLTl6XdCFFSai9UJ+DJPb69FFuqthXYsY8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/postcss-unique-selectors/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
@@ -1634,6 +2868,16 @@
}
]
},
+ "node_modules/sax": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz",
+ "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=11.0.0"
+ }
+ },
"node_modules/schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
@@ -1714,6 +2958,7 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
@@ -1732,6 +2977,7 @@
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
@@ -1753,6 +2999,37 @@
"webpack": "^5.0.0"
}
},
+ "node_modules/stylehacks": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.11.tgz",
+ "integrity": "sha512-iODNfhXVLqc5LADs+Y6Oh5wJuK5ZcHbVng8aiK3y9pjMQdc5hLrBW0eFU6FtnpNrE6PoEg/MmFTU4waotj5WNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.28.2",
+ "postcss-selector-parser": "^7.1.1"
+ },
+ "engines": {
+ "node": "^18.12.0 || ^20.9.0 || >=22.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.5.13"
+ }
+ },
+ "node_modules/stylehacks/node_modules/postcss-selector-parser": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
+ "integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@@ -1780,6 +3057,32 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/svgo": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.1.0.tgz",
+ "integrity": "sha512-bkxnTg1kSU0guhIBmibA6UUhrQmPVA1XsQLN+ylCd+UWzbnLkySOcXpyk1mrl05f+pcaCx2eHb+sp6BgMZWX+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^11.1.0",
+ "css-select": "^6.0.0",
+ "css-tree": "^3.0.1",
+ "css-what": "^7.0.0",
+ "csso": "^5.0.5",
+ "picocolors": "^1.1.1",
+ "sax": "1.6.1"
+ },
+ "bin": {
+ "svgo": "bin/svgo.js"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/svgo"
+ }
+ },
"node_modules/tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@@ -1790,13 +3093,14 @@
}
},
"node_modules/terser": {
- "version": "5.27.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.0.tgz",
- "integrity": "sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==",
+ "version": "5.51.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.51.2.tgz",
+ "integrity": "sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==",
"dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
- "acorn": "^8.8.2",
+ "acorn": "^8.15.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
@@ -1808,16 +3112,16 @@
}
},
"node_modules/terser-webpack-plugin": {
- "version": "5.3.10",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
- "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
+ "version": "5.6.1",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz",
+ "integrity": "sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.20",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
- "schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.1",
- "terser": "^5.26.0"
+ "schema-utils": "^4.3.0",
+ "terser": "^5.31.1"
},
"engines": {
"node": ">= 10.13.0"
@@ -1830,17 +3134,126 @@
"webpack": "^5.1.0"
},
"peerDependenciesMeta": {
+ "@minify-html/node": {
+ "optional": true
+ },
"@swc/core": {
"optional": true
},
+ "@swc/css": {
+ "optional": true
+ },
+ "@swc/html": {
+ "optional": true
+ },
+ "clean-css": {
+ "optional": true
+ },
+ "cssnano": {
+ "optional": true
+ },
+ "csso": {
+ "optional": true
+ },
"esbuild": {
"optional": true
},
+ "html-minifier-terser": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
"uglify-js": {
"optional": true
}
}
},
+ "node_modules/terser-webpack-plugin/node_modules/ajv": {
+ "version": "8.20.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
+ "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv-formats": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
+ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependencies": {
+ "ajv": "^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "ajv": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+ "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "ajv": "^8.8.2"
+ }
+ },
+ "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.5.0.tgz",
+ "integrity": "sha512-zJlMCZ0cAR5p/Y4oVpRoqioDMJcGxaXRrQ/4rP4WyR84vc5z/DolXdbvXeDpTwbtocDFr2rhPqHPErDCUtz2kA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^8.20.0",
+ "ajv-formats": "^3.0.1",
+ "ajv-keywords": "^5.1.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/webpack"
+ }
+ },
+ "node_modules/terser/node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/typeface-roboto": {
"version": "0.0.54",
"resolved": "https://registry.npmjs.org/typeface-roboto/-/typeface-roboto-0.0.54.tgz",
@@ -1853,9 +3266,9 @@
"dev": true
},
"node_modules/update-browserslist-db": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
- "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz",
+ "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==",
"dev": true,
"funding": [
{
@@ -1871,9 +3284,10 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
diff --git a/packages/solara-vuetify3-app/package.json b/packages/solara-vuetify3-app/package.json
index d67216aed..c974fce75 100644
--- a/packages/solara-vuetify3-app/package.json
+++ b/packages/solara-vuetify3-app/package.json
@@ -27,9 +27,11 @@
},
"devDependencies": {
"css-loader": "^6.9.1",
+ "css-minimizer-webpack-plugin": "^7.0.4",
"file-loader": "^6.2.0",
"mini-css-extract-plugin": "^2.7.7",
"style-loader": "^3.3.4",
+ "terser-webpack-plugin": "^5.6.1",
"webpack": "^5.90.0",
"webpack-cli": "^5.1.4"
}
diff --git a/packages/solara-vuetify3-app/src/empty.js b/packages/solara-vuetify3-app/src/empty.js
new file mode 100644
index 000000000..78d0d90bc
--- /dev/null
+++ b/packages/solara-vuetify3-app/src/empty.js
@@ -0,0 +1 @@
+// used as alias to avoid bundling unused code
diff --git a/packages/solara-vuetify3-app/src/fonts.js b/packages/solara-vuetify3-app/src/fonts.js
deleted file mode 100644
index ab1415acb..000000000
--- a/packages/solara-vuetify3-app/src/fonts.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import '@mdi/font/css/materialdesignicons.css';
-import 'material-design-icons-iconfont/dist/material-design-icons.css';
-import 'typeface-roboto';
diff --git a/packages/solara-vuetify3-app/src/solara-vuetify-app.js b/packages/solara-vuetify3-app/src/solara-vuetify-app.js
index 07074faf2..f8373bc16 100644
--- a/packages/solara-vuetify3-app/src/solara-vuetify-app.js
+++ b/packages/solara-vuetify3-app/src/solara-vuetify-app.js
@@ -1,32 +1,24 @@
import * as Vue from 'vue';
-import * as Vuetify from 'vuetify';
-import 'vuetify/dist/vuetify.min.css';
-import * as components from 'vuetify/components';
-import * as labComponents from 'vuetify/labs/components';
-import * as directives from 'vuetify/directives';
+import * as solara from './solara';
-const rawThemes = typeof window !== 'undefined' ? window.vuetifyThemes || {} : {};
-const themes = Object.fromEntries(
- Object.entries(rawThemes).map(([name, theme]) => [
- name,
- theme.colors ? theme : { dark: name === 'dark', colors: theme },
- ]),
+// The frontend features of this bundle, next to the ones of the widget manager.
+// Vuetify (JS) is a chunk that the page always preloads (the page shell is made of Vuetify).
+// Its CSS is the feature vuetify-css.
+solara.registerFeature(
+ 'vuetify',
+ () => import(/* webpackChunkName: "vuetify" */ './vuetify'),
+ [],
+ false,
+ require.resolveWeak('./vuetify'),
);
+// CSS only: Vuetify's CSS (main{M}.vuetify.css; MoveCssPlugin in webpack.config.js moves the
+// CSS of the vuetify chunk into this chunk), fonts and icons
+solara.registerFeature('vuetify-css', () => import(/* webpackChunkName: "vuetify-css" */ './vuetify-css'), [], true);
+solara.registerFeature('mdi', () => import(/* webpackChunkName: "mdi" */ '@mdi/font/css/materialdesignicons.css'), [], true);
+solara.registerFeature('material-icons', () => import(/* webpackChunkName: "material-icons" */ 'material-design-icons-iconfont/dist/material-design-icons.css'), [], true);
+solara.registerFeature('roboto', () => import(/* webpackChunkName: "roboto" */ 'typeface-roboto'), [], true);
-const vuetifyPlugin = Vuetify.createVuetify({
- components: {
- ...components,
- ...labComponents,
- },
- directives,
- theme: {
- themes,
- },
-});
-
-
-import * as solara from './solara';
export { solara };
-export { Vue, Vuetify, vuetifyPlugin };
+export { Vue };
diff --git a/packages/solara-vuetify3-app/src/solara.js b/packages/solara-vuetify3-app/src/solara.js
index bd38c21e0..6c29eaf12 100644
--- a/packages/solara-vuetify3-app/src/solara.js
+++ b/packages/solara-vuetify3-app/src/solara.js
@@ -1 +1,5 @@
-export { RenderMimeRegistry, WidgetManager, connectKernel, extendedRendererFactories, KatexTypesetter, renderKatex, shutdownKernel } from '@widgetti/solara-widget-manager';
+export {
+ RenderMimeRegistry, WidgetManager, connectKernel, extendedRendererFactories, KatexTypesetter, renderKatex, shutdownKernel,
+ registerFeature, provideFeature, setEnabledFeatures, isEnabled, hasFeature, loadFeature, loadPreloadedFeaturesSync,
+ getLoadedFeature, onLazyLoad, defineAmdModules, loadKatex,
+} from '@widgetti/solara-widget-manager';
diff --git a/packages/solara-vuetify3-app/src/vuetify-css.js b/packages/solara-vuetify3-app/src/vuetify-css.js
new file mode 100644
index 000000000..1365e1107
--- /dev/null
+++ b/packages/solara-vuetify3-app/src/vuetify-css.js
@@ -0,0 +1,3 @@
+// feature "vuetify-css": Vuetify's CSS, main{M}.vuetify.css. This chunk has no code: MoveCssPlugin
+// (webpack.config.js) moves the CSS of the vuetify chunk into it, in the same order.
+export {};
diff --git a/packages/solara-vuetify3-app/src/vuetify.js b/packages/solara-vuetify3-app/src/vuetify.js
new file mode 100644
index 000000000..f72137eaf
--- /dev/null
+++ b/packages/solara-vuetify3-app/src/vuetify.js
@@ -0,0 +1,35 @@
+// feature "vuetify": the Vuetify JS. Its CSS (this CSS import, and the CSS that Vuetify's components
+// import) is the feature "vuetify-css": MoveCssPlugin (webpack.config.js) moves it to that chunk.
+import * as Vuetify from 'vuetify';
+import 'vuetify/dist/vuetify.min.css';
+
+import * as components from 'vuetify/components';
+import * as labComponents from 'vuetify/labs/components';
+import * as directives from 'vuetify/directives';
+
+const rawThemes = typeof window !== 'undefined' ? window.vuetifyThemes || {} : {};
+const themes = Object.fromEntries(
+ Object.entries(rawThemes).map(([name, theme]) => [
+ name,
+ theme.colors ? theme : { dark: name === 'dark', colors: theme },
+ ]),
+);
+
+const vuetifyPlugin = Vuetify.createVuetify({
+ components: {
+ ...components,
+ ...labComponents,
+ },
+ directives,
+ theme: {
+ themes,
+ },
+});
+
+// the page and jupyter-vuetify's nodeps.js use these globals (they were exports of the core bundle)
+if (typeof window !== 'undefined') {
+ window.Vuetify = Vuetify;
+ window.vuetifyPlugin = vuetifyPlugin;
+}
+
+export { Vuetify, vuetifyPlugin };
diff --git a/packages/solara-vuetify3-app/webpack.config.js b/packages/solara-vuetify3-app/webpack.config.js
index 9a99014c8..4354bdb37 100755
--- a/packages/solara-vuetify3-app/webpack.config.js
+++ b/packages/solara-vuetify3-app/webpack.config.js
@@ -1,125 +1,97 @@
-var path = require('path');
+const path = require('path');
+const webpack = require('webpack');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
+const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
+const TerserPlugin = require("terser-webpack-plugin");
+const { slotInsert, cssChunkFilename, MoveCssPlugin, DropCssPlugin, WrapUmdFactoryPlugin, ChunkGuardPlugin, DedupePackagesPlugin } = require("../solara-widget-manager/webpack-plugins");
-var rules = [
+// Each frontend feature (vuetify, katex, jupyter-controls, ...) is a named async chunk:
+// solara-vuetify-app{M}.{feature}{.min}.js and main{M}.{feature}.css.
+// The server preloads the chunks of the enabled features, see solara/server/frontend_assets.py.
+
+const rules = [
{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] },
- // required to load font-awesome
- {
- test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
- },
- {
- test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
- },
+ // fonts are files, not data URIs: the browser fetches only the fonts a page uses
+ // (KaTeX's CSS was 77 KB gzip with its fonts inlined, 4 KB without)
{
- test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
+ test: /\.(woff2?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
+ type: 'asset/resource',
},
- {
- test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
- },
- {
- test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
- type: 'asset',
- }
];
-module.exports = [
- {
- plugins: [new MiniCssExtractPlugin({filename: 'fonts.css'})],
- entry: './src/fonts.js',
- output: {
- filename: 'fonts.js',
- path: path.resolve(__dirname, 'dist'),
- libraryTarget: 'umd',
- publicPath: 'auto',
- },
- module: {
- rules: rules
- },
- mode: 'production',
- },
- {
- plugins: [new MiniCssExtractPlugin({filename: 'main7.css'})],
- entry: './src/solara-vuetify-app.js',
- output: {
- filename: 'solara-vuetify-app7.min.js',
- path: path.resolve(__dirname, 'dist'),
- libraryTarget: 'umd',
- publicPath: 'auto',
- },
- module: {
- rules: rules
- },
- resolve: {
- alias: {
- vue$: 'vue/dist/vue.esm-bundler.js',
- }
- },
- mode: 'production',
- },
- {
- plugins: [new MiniCssExtractPlugin({filename: 'main7.css'})],
- entry: './src/solara-vuetify-app.js',
- output: {
- filename: 'solara-vuetify-app7.js',
- path: path.resolve(__dirname, 'dist'),
- libraryTarget: 'umd',
- publicPath: 'auto',
- devtoolModuleFilenameTemplate: `webpack://@widgetti/solara-vuetify3-app`
- },
- module: {
- rules: rules
- },
- resolve: {
- alias: {
- vue$: 'vue/dist/vue.esm-bundler.js',
- }
- },
- mode: 'development',
- },
- {
- plugins: [new MiniCssExtractPlugin({filename: 'main8.css'})],
+const empty = path.resolve(__dirname, "src", "empty.js");
+
+// one config per (ipywidgets major version, production|development)
+function config(major, production) {
+ const min = production ? '.min' : '';
+ const widgetManager = major === 8 ? '@widgetti/solara-widget-manager8' : '@widgetti/solara-widget-manager';
+ return {
+ name: `solara-vuetify-app${major}${min}`,
entry: './src/solara-vuetify-app.js',
+ mode: production ? 'production' : 'development',
+ // as before: no source map for prod 7, eval for dev 7
+ devtool: major === 8 ? 'source-map' : (production ? false : 'eval'),
output: {
- filename: 'solara-vuetify-app8.min.js',
+ filename: `solara-vuetify-app${major}${min}.js`,
+ chunkFilename: `solara-vuetify-app${major}.[name]${min}.js`,
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'umd',
+ // chunks load from where the core script came from (CDN, /_solara/cdn, solara-assets)
publicPath: 'auto',
+ // own JSONP global per build, so two builds can never share chunks
+ uniqueName: `solara_vuetify3_app${major}${production ? '' : '_dev'}`,
+ ...(production ? {} : { devtoolModuleFilenameTemplate: `webpack://@widgetti/solara-vuetify3-app` }),
},
- devtool: 'source-map',
+ plugins: [
+ new MiniCssExtractPlugin({
+ filename: `main${major}.css`,
+ // main{M}.{chunk name}.css, but Vuetify's CSS (chunk vuetify-css) is main{M}.vuetify.css
+ chunkFilename: cssChunkFilename(major),
+ insert: slotInsert,
+ }),
+ // Vuetify's CSS (also the CSS its components import) loads with the vuetify-css feature, not with Vuetify
+ new MoveCssPlugin('vuetify', 'vuetify-css'),
+ new ChunkGuardPlugin(),
+ new DedupePackagesPlugin(),
+ // only the parts of the @jupyterlab/services index that we use (see solara-widget-manager/src/services.ts)
+ new webpack.NormalModuleReplacementPlugin(
+ /@jupyterlab[\\/]services[\\/]lib[\\/]index\.js$/,
+ path.resolve(__dirname, 'node_modules', widgetManager, 'lib', 'services.js'),
+ ),
+ ...(production ? [] : [new DropCssPlugin(), new WrapUmdFactoryPlugin()]),
+ ],
module: {
rules: rules
},
- resolve: {
- alias: {
- "@widgetti/solara-widget-manager": "@widgetti/solara-widget-manager8",
- vue$: 'vue/dist/vue.esm-bundler.js',
- }
- },
- mode: 'production',
- }, {
- plugins: [new MiniCssExtractPlugin({filename: 'main8.css'})],
- entry: './src/solara-vuetify-app.js',
- output: {
- filename: 'solara-vuetify-app8.js',
- path: path.resolve(__dirname, 'dist'),
- libraryTarget: 'umd',
- publicPath: 'auto',
- devtoolModuleFilenameTemplate: `webpack://@widgetti/solara-vuetify3-app`
- },
- devtool: 'source-map',
- module: {
- rules: rules
+ optimization: {
+ // no shared chunks with generated names: every async chunk is one feature
+ splitChunks: false,
+ minimizer: [
+ // without ascii_only, the chunks need on the page.
+ // wrap_func_args (the default before terser 5.43) keeps a function passed as an argument in
+ // parentheses, as in the published bundles: V8 then compiles the UMD factory, "(self,(()=>...))",
+ // eagerly and off the main thread, instead of lazily on the main thread (see WrapUmdFactoryPlugin)
+ new TerserPlugin({ terserOptions: { format: { ascii_only: true, wrap_func_args: true } } }),
+ // also removes the duplicate Vuetify rules (dist + lib CSS), keeping the last copy.
+ // mergeLonghand off: merging var() longhands into a shorthand changes the cascade, e.g.
+ // Vuetify's .v-main padding-top/left longhands became one padding shorthand, and one invalid
+ // var (--v-layout-left: NaN with a width="min-content" drawer) then voided padding-top as well
+ new CssMinimizerPlugin({ minimizerOptions: { preset: ['default', { mergeLonghand: false }] } }),
+ ],
},
resolve: {
alias: {
- "@widgetti/solara-widget-manager": "@widgetti/solara-widget-manager8",
+ ...(major === 8 ? { "@widgetti/solara-widget-manager": widgetManager } : {}),
vue$: 'vue/dist/vue.esm-bundler.js',
+ // CodeMirror (markdown code highlighting) is a lazy chunk (see solara-widget-manager/src/codemirror.ts)
+ '@jupyterlab/codemirror$': path.resolve(__dirname, 'node_modules', widgetManager, 'lib', 'codemirror.js'),
+ // do not think we use this
+ 'moment': empty,
+ // one sanitize-html copy, in the "sanitizer" chunk (see solara-widget-manager/src/sanitize.ts)
+ 'sanitize-html$': path.resolve(__dirname, 'node_modules', widgetManager, 'lib', 'sanitize.js'),
}
},
- mode: 'development',
- },
-];
+ };
+}
+
+module.exports = [config(7, true), config(7, false), config(8, true), config(8, false)];
diff --git a/packages/solara-widget-manager/package-lock.json b/packages/solara-widget-manager/package-lock.json
index 2459ce04e..420ebcc25 100644
--- a/packages/solara-widget-manager/package-lock.json
+++ b/packages/solara-widget-manager/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@widgetti/solara-widget-manager",
- "version": "0.4.0",
+ "version": "0.5.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@widgetti/solara-widget-manager",
- "version": "0.4.0",
+ "version": "0.5.0",
"license": "MIT",
"dependencies": {
"@jupyter-widgets/base": "^4.1.5",
@@ -15,6 +15,7 @@
"@jupyter-widgets/controls8": "npm:@jupyter-widgets/controls@^5.0.1",
"@jupyter-widgets/jupyterlab-manager": "^3.1.7",
"@jupyter-widgets/jupyterlab-manager8": "npm:@jupyter-widgets/jupyterlab-manager@^5.0.3",
+ "@jupyter-widgets/output": "^4.1.5",
"@jupyterlab/application": "^3.6.7",
"@jupyterlab/apputils": "^3.6.7",
"@jupyterlab/coreutils": "^5.6.7",
@@ -31,7 +32,8 @@
"@lumino/signaling": "^1.11.1",
"@lumino/virtualdom": "^1.14.3",
"@lumino/widgets": "^1.37.2",
- "katex": "^0.16.9"
+ "katex": "^0.16.9",
+ "sanitize-html": "^2.11.0"
},
"devDependencies": {
"npm-run-all": "^4.1.5",
@@ -469,6 +471,7 @@
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@jupyter-widgets/output/-/output-4.1.5.tgz",
"integrity": "sha512-HnH2SDk0TZgC7qioZo9ifm0QHjUpH844HcDwMPTelIuAI0Y7HA/PR+dlfSrvDyOXfO2U2oA00TvtaYnkhY1CTQ==",
+ "license": "BSD-3-Clause",
"dependencies": {
"@jupyter-widgets/base": "^4.1.5"
}
@@ -3662,6 +3665,7 @@
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.11.0.tgz",
"integrity": "sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==",
+ "license": "MIT",
"dependencies": {
"deepmerge": "^4.2.2",
"escape-string-regexp": "^4.0.0",
diff --git a/packages/solara-widget-manager/package.json b/packages/solara-widget-manager/package.json
index 97f37316e..d4534e137 100644
--- a/packages/solara-widget-manager/package.json
+++ b/packages/solara-widget-manager/package.json
@@ -12,6 +12,7 @@
"@jupyter-widgets/controls8": "npm:@jupyter-widgets/controls@^5.0.1",
"@jupyter-widgets/jupyterlab-manager": "^3.1.7",
"@jupyter-widgets/jupyterlab-manager8": "npm:@jupyter-widgets/jupyterlab-manager@^5.0.3",
+ "@jupyter-widgets/output": "^4.1.5",
"@jupyterlab/application": "^3.6.7",
"@jupyterlab/apputils": "^3.6.7",
"@jupyterlab/coreutils": "^5.6.7",
@@ -28,7 +29,8 @@
"@lumino/signaling": "^1.11.1",
"@lumino/virtualdom": "^1.14.3",
"@lumino/widgets": "^1.37.2",
- "katex": "^0.16.9"
+ "katex": "^0.16.9",
+ "sanitize-html": "^2.11.0"
},
"devDependencies": {
"npm-run-all": "^4.1.5",
diff --git a/packages/solara-widget-manager/src/amd.ts b/packages/solara-widget-manager/src/amd.ts
new file mode 100644
index 000000000..aa344d38c
--- /dev/null
+++ b/packages/solara-widget-manager/src/amd.ts
@@ -0,0 +1,53 @@
+// AMD (requirejs) modules for third-party widgets and nbextensions.
+import * as base from '@jupyter-widgets/base';
+import * as CoreUtils from '@jupyterlab/coreutils';
+
+import * as LuminoAlgorithm from '@lumino/algorithm';
+import * as LuminoCommands from '@lumino/commands';
+import * as LuminoDomutils from '@lumino/domutils';
+import * as LuminoSignaling from '@lumino/signaling';
+import * as LuminoVirtualdom from '@lumino/virtualdom';
+import * as LuminoWidget from '@lumino/widgets';
+
+import { loadFeature } from './features';
+
+let defined = false;
+
+/**
+ * Define the AMD modules. Call this after require.js is loaded.
+ * Feature modules (controls, output) are dormant named defines: their chunk
+ * loads only when a module requires them, through the 'solara-feature!' plugin.
+ */
+export function defineAmdModules(): void {
+ if (defined || typeof window === 'undefined' || typeof window.define === 'undefined') {
+ return;
+ }
+ defined = true;
+ const define = window.define;
+ // requirejs loader plugin: 'solara-feature!katex' resolves to the module of the feature chunk
+ define('solara-feature', [], () => ({
+ load: (name: string, _require: any, onload: any) => {
+ loadFeature(name).then(onload, onload.error);
+ },
+ }));
+ define('@jupyter-widgets/base', base);
+ define('@jupyter-widgets/controls', ['solara-feature!jupyter-controls'], (chunk: any) => chunk.controls);
+ define('@jupyter-widgets/output', ['solara-feature!output-widget'], (chunk: any) => chunk.output);
+ define('@jupyterlab/outputarea', ['solara-feature!output-widget'], (chunk: any) => chunk.OutputArea);
+
+ define('@jupyterlab/coreutils', CoreUtils);
+
+ define('@phosphor/widgets', LuminoWidget);
+ define('@phosphor/signaling', LuminoSignaling);
+ define('@phosphor/virtualdom', LuminoVirtualdom);
+ define('@phosphor/algorithm', LuminoAlgorithm);
+ define('@phosphor/commands', LuminoCommands);
+ define('@phosphor/domutils', LuminoDomutils);
+
+ define('@lumino/widgets', LuminoWidget);
+ define('@lumino/signaling', LuminoSignaling);
+ define('@lumino/virtualdom', LuminoVirtualdom);
+ define('@lumino/algorithm', LuminoAlgorithm);
+ define('@lumino/commands', LuminoCommands);
+ define('@lumino/domutils', LuminoDomutils);
+}
diff --git a/packages/solara-widget-manager/src/chunks/controls.ts b/packages/solara-widget-manager/src/chunks/controls.ts
new file mode 100644
index 000000000..47df83ec7
--- /dev/null
+++ b/packages/solara-widget-manager/src/chunks/controls.ts
@@ -0,0 +1,18 @@
+// feature "jupyter-controls": @jupyter-widgets/controls
+import * as controls from '@jupyter-widgets/controls';
+
+// Override DescriptionView with one that doesn't use MathJax, and instead just uses KatexTypesetter
+controls.DescriptionView.prototype.typeset = function (element: HTMLElement, text?: string): void {
+ this.displayed.then(() => {
+ const widget_manager: any = this.model.widget_manager;
+ const latexTypesetter = widget_manager._rendermime?.latexTypesetter;
+ if (latexTypesetter) {
+ if (text !== void 0) {
+ element.textContent = text;
+ }
+ latexTypesetter.typeset(element);
+ }
+ });
+};
+
+export { controls };
diff --git a/packages/solara-widget-manager/src/chunks/jupyter-css.ts b/packages/solara-widget-manager/src/chunks/jupyter-css.ts
new file mode 100644
index 000000000..4fba94cd4
--- /dev/null
+++ b/packages/solara-widget-manager/src/chunks/jupyter-css.ts
@@ -0,0 +1,2 @@
+// feature "jupyter-css": the CSS of the Jupyter widgets (.lm-Widget, --jp-widgets-* variables)
+import '@jupyter-widgets/controls/css/widgets-base.css';
diff --git a/packages/solara-widget-manager/src/chunks/katex.ts b/packages/solara-widget-manager/src/chunks/katex.ts
new file mode 100644
index 000000000..89b1c4cf8
--- /dev/null
+++ b/packages/solara-widget-manager/src/chunks/katex.ts
@@ -0,0 +1,6 @@
+// feature "katex": both imports resolve to the ESM build (katex.mjs), so there is one KaTeX copy
+import renderMathInElement from 'katex/contrib/auto-render';
+import katex from 'katex';
+import 'katex/dist/katex.min.css';
+
+export { katex, renderMathInElement };
diff --git a/packages/solara-widget-manager/src/chunks/output.ts b/packages/solara-widget-manager/src/chunks/output.ts
new file mode 100644
index 000000000..bf9152ba8
--- /dev/null
+++ b/packages/solara-widget-manager/src/chunks/output.ts
@@ -0,0 +1,5 @@
+// feature "output-widget": the Output widget and the Jupyter output area
+import * as output from '@jupyter-widgets/jupyterlab-manager/lib/output';
+import * as OutputArea from '@jupyterlab/outputarea';
+
+export { output, OutputArea };
diff --git a/packages/solara-widget-manager/src/chunks/sanitizer.ts b/packages/solara-widget-manager/src/chunks/sanitizer.ts
new file mode 100644
index 000000000..ab5c339e3
--- /dev/null
+++ b/packages/solara-widget-manager/src/chunks/sanitizer.ts
@@ -0,0 +1,8 @@
+// internal feature "sanitizer": the one sanitize-html copy, needed by jupyter-controls and output-widget.
+// The core bundle aliases 'sanitize-html' to ../sanitize (a stub), this deep import skips that alias.
+import sanitizeHtml from 'sanitize-html/index.js';
+import { setSanitizer } from '../sanitize';
+
+setSanitizer(sanitizeHtml);
+
+export { sanitizeHtml };
diff --git a/packages/solara-widget-manager/src/codemirror.ts b/packages/solara-widget-manager/src/codemirror.ts
new file mode 100644
index 000000000..dc7acf622
--- /dev/null
+++ b/packages/solara-widget-manager/src/codemirror.ts
@@ -0,0 +1,38 @@
+// Stub for @jupyterlab/codemirror. The app bundles alias the '@jupyterlab/codemirror' import of
+// @jupyterlab/rendermime (its markdown renderer) to this module, so CodeMirror is not in the core
+// bundle. The markdown renderer reads the theme name, and highlights code blocks with Mode.ensure
+// and Mode.run. CodeMirror loads (as the "codemirror" chunk) on the first code block with a language.
+type ModeNamespace = typeof import('@jupyterlab/codemirror/lib/mode').Mode;
+
+let realMode: ModeNamespace | undefined;
+let loading: Promise | undefined;
+
+function loadMode(): Promise {
+ if (!loading) {
+ loading = import(/* webpackChunkName: "codemirror" */ '@jupyterlab/codemirror/lib/mode').then(module => {
+ realMode = module.Mode;
+ return realMode;
+ });
+ // a failed load (e.g. network) may be retried by the next code block
+ loading.catch(() => (loading = undefined));
+ }
+ return loading;
+}
+
+// CodeMirrorEditor.defaultConfig.theme of @jupyterlab/codemirror 3.x
+export const CodeMirrorEditor = {
+ defaultConfig: { theme: 'jupyter' }
+};
+
+export const Mode = {
+ ensure(mode: any): Promise {
+ return loadMode().then(real => real.ensure(mode));
+ },
+ // only called after ensure resolved, so CodeMirror is loaded
+ run(code: string, mode: any, el: HTMLElement): void {
+ if (!realMode) {
+ throw new Error('CodeMirror is not loaded, call Mode.ensure first');
+ }
+ realMode.run(code, mode, el);
+ }
+};
diff --git a/packages/solara-widget-manager/src/features.ts b/packages/solara-widget-manager/src/features.ts
new file mode 100644
index 000000000..2262b50b2
--- /dev/null
+++ b/packages/solara-widget-manager/src/features.ts
@@ -0,0 +1,203 @@
+// Frontend features. Each feature is one named webpack chunk of the app bundle:
+// ..min.js and/or main..css.
+// The server adds a
+ {% endif -%}
{% block header %}
{{ pre_rendered_css | safe }}
- {% if vue3 == True %}
-
- {% else %}
-
+ {#- the CSS before the core CSS (Vuetify's CSS on Vue 2); the whitespace control keeps the page as before without it #}
+ {%- for css in frontend_assets.head_first_css %}
+ {% if css.url %}
+
{% endif %}
+
+ {%- endfor %}
+
+ {% for css in frontend_assets.head_css %}
+ {% if css.url %}
+
+ {% endif %}
+ {# a lazy loaded feature puts its CSS here, so the order is the same as when it is preloaded #}
+
+ {% endfor %}
{% if assets.fontawesome_enabled == True %}
@@ -245,21 +264,35 @@
{% block after_pre_rendered_html %}{% endblock %}
{{ resources.include_js("/static/assets/theme.js") }}
- {% if vue3 == True %}
-
- {% if production %}
-
- {% else %}
-
- {% endif %}
- {% else %}
-
- {% if production %}
-
- {% else %}
-
- {% endif %}
+ {% for css in frontend_assets.body_css %}
+ {% if css.url %}
+
{% endif %}
+
+ {% endfor %}
+
+
+ {# a failed chunk script must go: webpack reuses a script tag with the same src for a lazy load, and would wait for it #}
+ {% for url in frontend_assets.chunk_js %}
+
+ {% endfor %}
+
+ {% else %}
+ {{ resources.include_js("/static/require.min.js") }}
+ {% endif %}
{{ resources.include_js("/static/main-vuetify.js") }}
{{ resources.include_js("/static/ansi.js") }}
@@ -521,11 +558,22 @@
}
},
});
- requirejs([
+ // the AMD modules of the bundle (@jupyter-widgets/base, ...) and the app (vue, vuetify),
+ // before any nbextension can ask for them
+ if (typeof solara.defineAmdModules === "function") {
+ solara.defineAmdModules();
+ }
+ defineAppAmdModules();
+ // an nbextension configures requirejs in its extension.js (for instance a map to its own files), so
+ // the widget manager waits for this before it asks requirejs for the module of such a widget
+ solara.nbextensionsLoaded = new Promise((resolve) => requirejs([
{% for ext in resources.nbextensions if ext != 'jupyter-vuetify/extension' and ext != 'jupyter-vue/extension' -%}
"{{jupyter_root_path}}/nbextensions/{{ ext }}.js",
{% endfor %}
- ]);
+ ], () => resolve(), (error) => {
+ console.error(error);
+ resolve();
+ }));
(async function () {
await Promise.all([
solaraInit('solara-main')
diff --git a/solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md b/solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md
index 802a50499..2664c94d3 100644
--- a/solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md
+++ b/solara/website/pages/documentation/advanced/content/20-understanding/50-solara-server.md
@@ -101,6 +101,57 @@ By default, solara runs in development mode. This means, it will:
To disabled all of these option, pass the `--production` flag, or set the environment variable `SOLARA_MODE=production`.
+## Frontend features
+
+The page that the Solara server sends to the browser loads the frontend code in parts, called features.
+By default, the page preloads all features (the `full` preset), so every widget renders at once.
+If your app does not use some features, you can leave them out, and the page loads faster.
+
+Use the `--frontend` option, the `SOLARA_FRONTEND` environment variable, or `solara.server.settings.main.frontend`.
+The value is a preset, `full` or `minimal`, followed by `+feature` or `-feature`:
+
+```bash
+# everything, except the mermaid diagrams
+$ solara run sol.py --frontend=full,-mermaid
+# only Vue, Vuetify and the widget core, plus math rendering
+$ SOLARA_FRONTEND=minimal,+katex solara run sol.py
+```
+
+The features are:
+
+| Feature | What it gives |
+| - | - |
+| `vuetify` | Vuetify. Always on, and so is `mdi`, which it needs. Roboto and Vuetify's CSS come with `vuetify`; add `-roboto` to use your own font, and `-vuetify-css` to use your own Vuetify CSS. |
+| `vuetify-css` | Vuetify's stylesheet. Comes with `vuetify`; add `-vuetify-css` to use your own Vuetify CSS. |
+| `mdi` | The Material Design Icons font (`mdi-*` icons). |
+| `material-icons` | The Material Icons font. |
+| `roboto` | The Roboto font. Comes with `vuetify`; add `-roboto` to use your own font. |
+| `font-awesome` | The Font Awesome icons (replaces `SOLARA_ASSETS_FONTAWESOME_ENABLED`, which still works). |
+| `jupyter-controls` | The ipywidgets controls (`IntSlider`, `Button`, ...). Needs `jupyter-css`. |
+| `output-widget` | The ipywidgets `Output` widget. Needs `jupyter-css`. |
+| `jupyter-css` | The CSS of the ipywidgets controls. |
+| `katex` | Math rendering (KaTeX), for example in `solara.Markdown`. |
+| `mermaid` | Mermaid diagrams in `solara.Markdown`. The page never preloads it: when it is on, it loads when the first `solara.Markdown` mounts. |
+| `vue-sfc` | The full Vue single-file-component compiler of ipyvue, for templates with `"""
+
+
+def test_full_markdown_mathjax_first(page_session: playwright.sync_api.Page, solara_server, solara_app, extra_include_path, recorder, frontend_setting):
+ # as before the frontend features: with MathJax 2 on the page, Markdown typesets with MathJax, not with KaTeX
+ frontend_setting("full")
+
+ def add_fake_mathjax(route: playwright.sync_api.Route):
+ response = route.fetch()
+ html = response.text()
+ assert "" in html
+ route.fulfill(response=response, body=html.replace("", "" + FAKE_MATHJAX, 1))
+
+ def is_page(url: str) -> bool:
+ return url.rstrip("/") == solara_server.base_url.rstrip("/")
+
+ page_session.route(is_page, add_fake_mathjax)
+ try:
+ with extra_include_path(HERE), solara_app("frontend_chunks_test:MarkdownMath"):
+ page_session.goto(solara_server.base_url)
+ page_session.locator("text=math markdown").wait_for()
+ page_session.wait_for_function("window.solaraTestMathJaxTypeset.length > 0")
+ assert page_session.evaluate("window.solaraTestMathJaxTypeset[0]") == "Typeset"
+ assert page_session.locator(".solara-markdown .katex").count() == 0
+ assert page_session.locator("link[data-solara-katex-css-last]").count() == 0
+ finally:
+ page_session.unroute(is_page, add_fake_mathjax)
+ assert recorder.errors() == []
+
+
+# the default primary color of solara.lab.theme: ipyvuetify's light primary (3.x: #6200EE, 1.x: #1976D2)
+DEFAULT_PRIMARY = "rgb(98, 0, 238)" if vue3 else "rgb(25, 118, 210)"
+
+
+@pytest.mark.parametrize("preset", ["full", "minimal"])
+def test_vuetify_theme_colors(page_session: playwright.sync_api.Page, solara_server, solara_app, extra_include_path, recorder, frontend_setting, preset):
+ # Vuetify gets the theme of solara.lab.theme, and follows a change the app makes to it
+ frontend_setting(preset)
+ with extra_include_path(HERE):
+ with solara_app("frontend_chunks_test:DefaultButton"):
+ page_session.goto(solara_server.base_url)
+ playwright.sync_api.expect(page_session.locator(".default-button")).to_have_css("background-color", DEFAULT_PRIMARY)
+ with solara_app("frontend_chunks_test:ThemedButton"):
+ page_session.goto(solara_server.base_url)
+ playwright.sync_api.expect(page_session.locator(".themed-button")).to_have_css("background-color", "rgb(255, 0, 0)")
+ assert recorder.lazy_warnings() == []
+ assert recorder.errors() == []
+
+
+@pytest.mark.parametrize("preset", ["full", "minimal"])
+def test_vuetify_theme_after_soft_remount(
+ page_session: playwright.sync_api.Page, solara_server, solara_app, extra_include_path, frontend_setting, monkeypatch, preset
+):
+ # the fresh kernel of a soft-remount starts from the theme of the page, not from the color the old kernel set
+ frontend_setting(preset)
+ monkeypatch.setattr(solara.server.settings.state, "auto_remount", True)
+ monkeypatch.setattr(solara.server.settings.state, "test_eviction", True)
+ button = page_session.locator(".theme-button")
+ try:
+ with extra_include_path(HERE), solara_app("frontend_chunks_test:ThemeOnClick"):
+ page_session.goto(solara_server.base_url)
+ playwright.sync_api.expect(button).to_have_css("background-color", DEFAULT_PRIMARY)
+ button.click()
+ playwright.sync_api.expect(button).to_have_css("background-color", "rgb(255, 0, 0)")
+ assert page_session.evaluate("solara.debug.simulateFailover()") is not False
+ page_session.wait_for_function("() => solara.debug.remountCount === 1", timeout=30000)
+ playwright.sync_api.expect(button).to_have_css("background-color", DEFAULT_PRIMARY)
+ finally:
+ page_session.goto("about:blank")
+
+
+def test_minimal_single_dollar_no_katex(
+ page_session: playwright.sync_api.Page, solara_server, solara_app, extra_include_path, recorder, frontend_setting, caplog
+):
+ frontend_setting("minimal,+jupyter-controls")
+ with caplog.at_level(logging.WARNING, logger="solara.server.frontend"), extra_include_path(HERE), solara_app("frontend_chunks_test:SingleDollars"):
+ page_session.goto(solara_server.base_url)
+ page_session.locator("text=single dollar").wait_for()
+ page_session.locator(".widget-slider >> text=Price ($)").wait_for()
+ # give a (wrong) katex load the time to start
+ page_session.wait_for_timeout(500)
+ assert "katex" not in recorder.chunk_requests()
+ assert "katex" not in recorder.lazy_warnings()
+ assert not [message for message in _server_warnings(caplog) if "katex" in message]
+ assert recorder.errors() == []
+
+
+@pytest.mark.parametrize("preset", ["full", "minimal"])
+def test_markdown_entity_math(page_session: playwright.sync_api.Page, solara_server, solara_app, extra_include_path, recorder, frontend_setting, preset):
+ if not vue3 and preset == "minimal":
+ pytest.skip("Vue 2 cannot leave out Vuetify, so minimal is not minimal there")
+ frontend_setting(preset)
+ with extra_include_path(HERE), solara_app("frontend_chunks_test:EntityMath"):
+ page_session.goto(solara_server.base_url)
+ page_session.locator("text=entity dollars").wait_for()
+ # the first Markdown of the page renders math, as before the frontend features
+ page_session.locator(".katex").first.wait_for()
+ assert recorder.errors() == []
+
+
+@pytest.mark.parametrize("preset", ["full", "minimal", "full,-roboto", "minimal,-roboto"])
+def test_vuetify_has_roboto(page_session: playwright.sync_api.Page, solara_server, solara_app, extra_include_path, recorder, frontend_setting, preset):
+ # Vuetify's typography uses Roboto, so the page (Vuetify is always on) preloads the Roboto CSS.
+ # An app with its own font leaves it out with -roboto.
+ frontend_setting(preset)
+ own_font = preset.endswith("-roboto")
+ with extra_include_path(HERE), solara_app("frontend_chunks_test:VuetifyCaption"):
+ page_session.goto(solara_server.base_url)
+ page_session.locator(".font-weight-light >> text=vuetify caption text").wait_for()
+ roboto = page_session.evaluate(
+ """async () => {
+ const slot = document.querySelector('template[data-solara-css-slot="roboto"]');
+ const links = [...document.querySelectorAll('link[rel=stylesheet]')].filter(l => /main\\d\\.roboto\\.css/.test(l.href));
+ // the faces of the light caption text: none without the Roboto CSS
+ const faces = await document.fonts.load('300 12px Roboto');
+ return {count: links.length, atSlot: links.length == 1 && slot.previousElementSibling === links[0], faces: faces.length > 0};
+ }"""
+ )
+ assert roboto == ({"count": 0, "atSlot": False, "faces": False} if own_font else {"count": 1, "atSlot": True, "faces": True})
+ # a css-only feature that is preloaded needs no JS
+ assert recorder.chunk_requests().get("roboto") is None
+ assert recorder.lazy_warnings() == []
+ assert recorder.errors() == []
+
+
+@pytest.mark.parametrize("preset", ["full", "minimal", "full,-vuetify-css", "minimal,-vuetify-css"])
+def test_vuetify_css(page_session: playwright.sync_api.Page, solara_server, solara_app, extra_include_path, recorder, frontend_setting, preset):
+ # Vuetify's CSS comes with Vuetify (always on), preloaded. An app that ships its own Vuetify CSS leaves it out with
+ # -vuetify-css, and the page still renders without errors.
+ frontend_setting(preset)
+ own_css = preset.endswith("-vuetify-css")
+ with extra_include_path(HERE), solara_app("frontend_chunks_test:DefaultButton"):
+ page_session.goto(solara_server.base_url)
+ page_session.locator(".default-button >> text=default button").wait_for()
+ vuetify_css = page_session.evaluate(
+ """() => {
+ const slot = document.querySelector('template[data-solara-css-slot="vuetify"]');
+ const links = [...document.querySelectorAll('link[rel=stylesheet]')].filter(l => /main\\d\\.vuetify\\.css/.test(l.href));
+ // a rule of Vuetify's stylesheet in a stylesheet of the page (not in the theme stylesheet that Vuetify makes in
+ // JavaScript, nor in the
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/unit/shell_test.py b/tests/unit/shell_test.py
index bd4285006..f4c1c2319 100644
--- a/tests/unit/shell_test.py
+++ b/tests/unit/shell_test.py
@@ -23,3 +23,13 @@ def test_shell(no_kernel_context):
IPython.display.display("test1")
assert ws1.send.call_count == 1
assert ws2.send.call_count == 1
+
+ assert kernel1.shell is not None
+ magics_manager = kernel1.shell.magics_manager
+ assert magics_manager is not None
+ registry = magics_manager.registry
+ # IPython 9 loads magics lazily (registry is a _MagicsRegistry); older versions
+ # create ScriptMagics with the shell, so there is nothing to skip there.
+ if type(registry).__name__ == "_MagicsRegistry":
+ # a new session should not pay for ScriptMagics (see SolaraInteractiveShell.__init__)
+ assert "ScriptMagics" not in dict.keys(registry)
diff --git a/tests/unit/static_cache_headers_test.py b/tests/unit/static_cache_headers_test.py
index 847be29ab..956915243 100644
--- a/tests/unit/static_cache_headers_test.py
+++ b/tests/unit/static_cache_headers_test.py
@@ -15,7 +15,7 @@
import solara.server.starlette
from solara.server import server
from solara.server.app import AppScript
-from solara.server.starlette import StaticAssets, StaticFilesOptionalAuth, StaticNbFiles, StaticPublic, immutable_cache_control
+from solara.server.starlette import StaticAssets, StaticCdn, StaticFilesOptionalAuth, StaticNbFiles, StaticPublic, immutable_cache_control
CONTENT = b"console.log('hi')"
DIGEST = hashlib.md5(CONTENT).hexdigest()
@@ -208,3 +208,18 @@ def test_page_fetches_the_theme_css_from_immutable_urls(no_kernel_context, tmp_p
for url in urls.values():
assert "?v=" in url
assert cache_control(client, url) == IMMUTABLE
+
+
+@pytest.mark.parametrize(
+ "path, sep, expected",
+ [
+ ("@widgetti/solara-vuetify3-app@5.2.0/dist/main8.css", "/", True),
+ # Windows: StaticFiles.get_path returns an OS path
+ ("@widgetti\\solara-vuetify3-app@5.2.0\\dist\\main8.css", "\\", True),
+ ("requirejs@2.3.6\\require.js", "\\", True),
+ ("pkg@^1\\index.js", "\\", False),
+ ("pkg@1.2\\index.js", "\\", False),
+ ],
+)
+def test_cdn_proxy_exact_version_os_paths(path: str, sep: str, expected: bool):
+ assert StaticCdn._pins_exact_version(path, sep) is expected